Commit Graph
14 Commits
Author SHA1 Message Date
ca4ca65c5e feat(pe): inspect Authenticode certificate tables (#4830)
* feat(pe): inspect Authenticode certificate tables

Add inspect_pe_certificates for IMAGE_DIRECTORY_ENTRY_SECURITY
WIN_CERTIFICATE entries and structurally decoded PKCS#7 signer
and X.509 identity fields. The workflow reads a stable PE image
without executing it or verifying signatures, chains, timestamps,
or Authenticode digest coverage.

* fix(pe): bound and validate certificate DER decoding

- Cap decoded DER values with a shared node budget so sibling fan-out
  cannot exhaust memory before the PKCS#7 check
- Require SignedData version, encapContentInfo and a final signerInfos
  SET in RFC 5652 order, and a signature OCTET STRING in each SignerInfo
- Decode OBJECT IDENTIFIER arcs as unbounded base-128 values, including
  a multi-byte first combined arc
- Decode UniversalString names as UTF-32BE and reject invalid values
- Share PE header admission with the resource layout so a section table
  that does not fit SizeOfHeaders is rejected

* docs: list PE certificates in the translated READMEs

* fix(pe): cap OBJECT IDENTIFIER length and arc size

A crafted type-2 certificate with a 262,144-byte contentType OID stalled
decodeOid for about 20 seconds, because one arc kept growing a BigInt
before the signedData check ran. decodeOid now rejects an OID longer than
256 bytes and an arc longer than 32 bytes before decoding it. Certificate
OIDs, including 2.25 UUID arcs, fit under both caps.

* fix(pe): reject truncated certificate tables and PKCS#7

SignedData now requires one SignerInfo with a non-empty signature and a
complete issuerAndSerialNumber. Certificate names share a 64 KiB decoded-byte
budget and are copied once. A security directory that ends in a short
WIN_CERTIFICATE header fails instead of reporting a complete table. The
certificate CLI forwards the caller abort signal into cleanup.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* chore(ci): keep fork workflow files unchanged

The certificate restack follows current main. Workflow files stay at the
fork tip so this branch update does not rewrite .github/workflows.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(pe): charge serial and validity text to the decoded budget

Certificate and signer serial numbers and validity times now count against
the shared decoded-text budget before they are converted, so a crafted
certificate cannot push megabytes of text into the hashed evidence. The
budget error now names certificate text rather than only names.

Restore the CI workflow to match main: the CI_TIMING_TIER input, the
tier-named timing artifacts and their publication conditions, the Windows
typecheck, and the path and snapshot suites in the curated Windows lane.

* fix(pe): require certificate fields and preserve signer key ids

Reject X.509 records that omit subjectPublicKeyInfo or signatureValue,
return subjectKeyIdentifier bytes as bounded hex, and advertise an absolute
path in the PE certificate input schema.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(pe): reject extra PKCS#7 wrappers and invalid UTF-8 names

ContentInfo and its signedData wrapper no longer ignore trailing values, and
directory strings must round-trip as UTF-8 instead of becoming U+FFFD.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-22 17:20:07 +08:00
Kaoru0822andClaude Opus 5.5 933af60eba feat(native): inspect PE and ELF export tables without an engine (#6278)
* feat(native): read PE and ELF export tables

Add a host-independent export-table reader on the shared native
container layer. PE images report each used export-address-table slot
with its ordinal, one row per name, its address or forwarder text, and
the export directory identity; the PE image reader now exposes its data
directories. ELF images report defined default/protected global, weak
and unique .dynsym symbols with type, binding and .gnu.version_d
version (hidden versions kept distinct, unreadable version tables
"unknown"). Unreadable entries are counted in issues and make coverage
partial; an ELF without section headers is unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(native): inspect native export tables through CLI and MCP

Expose the reader as inspect_native_exports / inspect-native-exports:
one stable, digest-bound read of an explicit file with a caller-selected
input budget, typed failures for malformed, unsupported, oversized and
cancelled reads, and observed Evidence bound to the file path and
SHA-256. Mach-O inputs point to inspect_macho.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(native): describe portable PE and ELF export inventories

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(native): bound export inventories and read header-backed PE tables

Address review of the export-table reader:

- Charge every retained row and its name, forwarder and version text
  against shared 262144-row and 16 MiB allowances before storing it, so
  repeated long names or PE aliases cannot exhaust memory.
- Map PE RVAs through the headers as well as sections; the PE image
  reader now exposes its SizeOfHeaders mapping.
- Keep ELF exports with version "unknown" when .gnu.version lies outside
  the file, and report an empty version-definition name as unresolved.
- Reject a .dynsym without its mandatory null entry as malformed.
- Decode the ELF section directory once.
- Correct the docs on which gaps drop rows and which keep them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 01:30:05 -07:00
Matt Van Horn 2edf3b23c1 feat(elf): inspect PT_NOTE and SHT_NOTE tables (#4837)
Inspect selected ELF32/ELF64 PT_NOTE and SHT_NOTE declarations without executing
the artifact, retaining independent table identities, source ranges, descriptor
digests, GNU build-id/ABI fields and explicit coverage limitations.

Integrate mvanhorn's implementation and hardening with current main while
preserving byte-entropy registration and the Windows curated regression suite.
The maintainer follow-up uses ordinary merges/pushes, not history rewriting.

Executed validation: 96 focused/shared/docs tests, complete static/docs checks,
eleven real CLI/MCP pairs including GCC ELF32 and Clang big-endian PowerPC64,
and two actual Codex task traces checked against their Evidence. Full costs,
grader correction and verification limits are recorded in PR #4837.

Refs #6262.
2026-10-22 15:02:23 +08:00
7aa1b51282 feat(diagnostics): report a byte entropy profile for one local file (#2331)
* feat(diagnostics): report a byte entropy profile for one local file

The diff adds the MCP tool inspect_byte_entropy and the CLI command
inspect-byte-entropy, both implemented by ByteEntropyService. One
absolute regular file is read offline into observed Evidence: file-wide
SHA-256 and Shannon entropy, then fixed blocks and adjacent runs for an
optional window, using a power-of-two block size from 256 to 65536
(default 4096), with high at 7.2 or above and low at 1.0 or below. A
window past EOF, a missing path, or a non-file is an input error; a size
or identity change during the read is an artifact-changed error; empty
input reports entropy 0; cancellation is honored before and during the
read. Summary detail retains the complete series and returns file
entropy, counts, and the ten longest runs for inspect_analysis_view,
while the registered effect remains read-only Evidence and the
diagnostics docs record the operation and its errors.

* fix(diagnostics): flag zero-size files as not shown empty

Generated files such as Linux /proc entries report size 0 while holding
content, so inspect_byte_entropy read nothing and returned an empty-looking
report. A file that reports size 0 now carries a limitation that the result
does not show the file is empty. The result stays a success because the
tool reads the declared size, which the file-stability checks depend on.

* fix(mcp): reject unsupported diagnostic summaries before inspection

* fix(ci): repair integrated checks and Hopper test baseline

* test(entropy): use shared MCP schema verification after merge

* fix(catalog): list inspect_byte_entropy under its own provider

Adding inspect_byte_entropy to BINARY_DIAGNOSTICS_TOOL_CONTRACTS put it
under pwntools-elf in the generated product catalog, because the
pwntools group took every binary diagnostics tool except
inspect_pe_resources. The service reports provider byte-entropy.

Add a BYTE_ENTROPY_PROVIDER identity beside PE_RESOURCES_PROVIDER, use
it in ByteEntropyService, give it its own catalog group, and name the
pwntools tools (inspect_binary_layout, inspect_recorded_crash)
explicitly so a new diagnostics tool is not attributed to pwntools by
default. The catalog test pins both groups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KFTE4BHbGYzgf8Uhzcppdh

* fix(cli): resolve the byte-entropy path with absoluteCallerPath

main replaced the node:path resolve import in binaryDiagnosticsCommands.ts
with absoluteCallerPath (#4067), so the byte-entropy command's
resolve(args.path) no longer type-checks once the PR is merged with main.
Use absoluteCallerPath like the other commands, and add
src/filesystem/callerPath.ts matching main so the branch builds on its own.

* fix(diagnostics): retain entropy read cleanup ownership

* docs(diagnostics): explain entropy output capacity

* fix(diagnostics): preserve entropy cancellation outcomes

* fix(diagnostics): close the entropy input and warn on large reports

Public inspect_byte_entropy input now uses publicInputStrictObject before
detail is added, so unknown keys stay rejected on the advertised schema.
The tool description warns that complete output can become very large and
points callers to a shorter length or a larger block_size.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(diagnostics): keep byte-entropy registration mergeable with main

Register inspect_byte_entropy beside layout inspection and reject
unretained summaries before the file read, without editing workflows.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(diagnostics): register byte entropy with the shared tool options

Use toolRegistrationOptions so the handler typechecks on this branch and
on main, and still refuse unretained summaries before the file read.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 14:19:12 +08:00
ae09e3fe70 fix(native): recover macOS command deadlines (#6059)
* fix(native): recover macOS command deadlines

Promote native_command_timeout_ms (default 60000), native_ui_deadline_ms
(default 180000), and pwntools_timeout_ms (default 30000) as validated
per-call settings. Keep cpuSeconds, byte allowances, LLDB grace, and plist
probes fixed, and say those caps have no runtime override.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(native): report the deadline that actually expired

Pass the selected native command timeout through xcrun resolution, thread
the pwntools deadline into pwndbg failures, and state the selected UI
deadline apart from the fixed wait-step cap. SIGXFSZ and EFBIG recovery
names the file-size allowance.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(native): honor the selected deadline on helper stages

The UI helper compile and capture subprocesses used fixed 60s and 30s
exec timeouts, so a longer native_ui_deadline_ms still failed as a generic
provider error. Preparation timeouts reported the 60000 ms default instead
of the selected native_command_timeout_ms.

Memory resource-constraint recovery names memory again, and the Darwin
plist CLI expectation matches the byte-counted input allowance.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 02:59:27 +08:00
morlutoandTapraj-Pathak 279c590ef6 fix(cli): require cancellation through command finalization
Adapt the forwarding proposal in #4652 with a required signal before optional resource diagnostics. Migrate all callers and cover actual command registration during final close. Refs #4939.

Co-authored-by: Tapraj-Pathak <165466587+Tapraj-Pathak@users.noreply.github.com>
2026-10-18 09:48:11 +08:00
Kaoru0822andClaude Opus 5.5 fc791bb606 fix(paths): select caller paths through symlinks and .. as the filesystem does (#4067)
* fix: select caller paths through symlinks and .. as the filesystem does

CLI adapters, binary target resolution, the reverse-engineering service
and the objdump and Rizin command builders made caller-selected paths
absolute with path.resolve, which collapses `link/..` lexically. On
POSIX the filesystem follows `link` first, so these commands inspected,
hashed or launched a different file and returned internally consistent
Evidence for it.

absoluteCallerPath now owns that step: on POSIX it prefixes a relative
path with the working directory and keeps an absolute path as spelled;
on Windows, where `..` resolves lexically, it keeps win32.resolve.

Fixes #3864
Fixes #3911
Fixes #3912

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep firmware, WASM list and output-root paths on the selected file

Review follow-up. The CLI already passed firmware and WASM paths through
absoluteCallerPath, but snapshotFirmware and SafeOutputTree.create
re-resolved them lexically, and the WASM glue and candidate lists still
used resolve, so those inputs could still select a sibling file or
create output beside the intended directory.

absoluteCallerPath now also drops `.` segments and repeated or trailing
separators on POSIX, which never change the named file, so selected
paths such as `./module.wasm` keep matching their glue references
exactly. Every `..` is still left for the filesystem.

SafeOutputTree keeps host path syntax; its platform argument selects only
the Windows name policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep directory requirements and relative cwd in caller paths

Review follow-up. absoluteCallerPath stripped a trailing `/` or `/.`, so
`file/` selected the regular file instead of failing with ENOTDIR; it
now keeps one trailing separator. A relative cwd option was appended to
the root; it is now made absolute without collapsing `..`. WASM glue
matching resolved local literals lexically, so a module selected through
`link/..` matched only by basename; the adapter now compares both sides
through absoluteCallerPath and still reports each candidate as given.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 05:19:43 -07:00
7df85f16a0 fix(cli): align advertised analysis contracts with runtime
Advertise the nonnegative outline-depth bound after safe-range conversion, verify it against the runtime parser and Ajv 2020, and describe every retained view family and both supported recorded-core architectures. Reuse the existing CLI schema fixture instead of three duplicate capture helpers.

Fixes #3211

Fixes #3194

Fixes #3167

Co-authored-by: Anankequ <2983852214@qq.com>

Co-authored-by: gongfpp <1360187968@qq.com>
2026-10-14 15:20:03 +08:00
morluto b955b825fc fix(artifacts): retain read cleanup ownership through CLI and MCP shutdown
Keep failed stable-read handles and WABT runtime roots under retryable resource scopes. Preserve cancellation causes and primary errors, close the same service instances bound to MCP tools, and consolidate CLI operation/cleanup projection.

Validation: fast typecheck and lint, cached runtime build, docs checks, SDK schema validation, focused service and real-file cleanup tests, CLI cleanup regressions, and MCP lifecycle/shutdown workflows. Provider process fixtures simulate engine output; real WABT and Linux EVM execution are not established by this pass.
2026-10-13 16:08:41 +08:00
Yijie Luandmorluto 11fe5a13f8 fix(native): retain failed pwntools process and runtime cleanup (#1708)
* fix(native): retain failed pwntools process and runtime cleanup

Keep failed worker/debugger cleanup owners and their private files until
verified process shutdown and successful directory removal. Retry cleanup
before another inspection and expose shutdown through the shared services,
CLI and MCP server. Serialize acquisition without delaying cancellation of
queued callers, and preserve primary diagnostics when CLI cleanup fails.

The original decoder reproduction left a live owned Node child with its
runtime deleted and no retained cleanup owner; the regression now verifies
retention, admission blocking, retries and eventual process/file cleanup.

Validation: 10 lifecycle/public CLI/MCP tests, 20 service tests, test
discovery 814/814, build:cached and full check including architecture guards.
Actual POSIX process/filesystem boundaries used injected Node workers on
macOS; real Linux pwntools/GDB provider parsing was not exercised.

* test(native): verify retained recorded-crash cleanup lifecycle

* fix(native): finalize diagnostic cleanup before publishing results

* fix(native): retire decoder stages before reading runtime evidence

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 01:37:47 +08:00
Thang Luuandmorluto 905e4866c4 feat(artifacts): inspect PE resource identities and payload ranges (#1482)
* feat(artifacts): inspect PE resource identities and payload ranges

* fix(artifacts): reject header payloads overlapping PE sections

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:06 +08:00
morluto ad59531a96 refactor: remove forwarding exports and redundant aliases 2026-10-09 22:46:09 +08:00
Ysopwnable 163ee09a74 feat(native): inspect recorded crashes through pwntools and pwndbg (#1054)
* feat(native): inspect recorded crashes through pwntools and pwndbg

* fix(native): bind core note semantics to raw owner bytes

* fix(native): validate recorded core ABI and evidence scalars

* fix(native): require complete recorded note interpretations

* fix(native): bind physical core notes to original headers
2026-10-08 16:50:31 +08:00
Ysopwnable 4fc6565b0f feat(native): inspect offline ELF layout through pwntools (#1037)
* feat(native): inspect offline ELF layout through pwntools

* fix(build): prepare offline ELF verification on clean runners

* fix(native): preserve snapshot acquisition cancellation

* fix(native): handle sectionless ELF and retain decoder diagnostics

* test(native): verify malformed symbol table entry sizes

* fix(native): respect inherited limits and unused segment fields

* fix(native): preserve packed relocations and decoder launch constraints

* fix(native): validate symbol spans and preserve resource failures

* fix(native): preserve diagnostic completeness and memory failures

* fix(native): guard bridge imports against allocation failures

* fix(native): validate relocation symbol and section references

* fix(native): retain diagnostics through compounded cleanup failures

* fix(native): preserve unresolved relocation section references

* fix(native): bound linkage evidence and preserve CPU signal diagnostics

* fix(native): preserve file-size resource failure evidence

* fix(native): retain opaque linkage names and late cancellation output

* test(native): make CPU-limit fixture robust across runners

* fix(native): verify resource failure branches before interpreting exits

* fix(native): validate declared ELF string references

* fix(native): validate section-name table before decoding

* fix(native): enforce canonical ELF name-table escapes
2026-10-08 14:22:08 +08:00