Commit Graph
48 Commits
Author SHA1 Message Date
4ef916da03 feat(pe): inspect import and delay-load tables (#6509)
* feat(pe): inspect import and delay-load tables

Add inspect_pe_imports / inspect-pe-imports to read PE32/PE32+ import
and delay-load directories without executing the image. The report keeps
DLL names, named and ordinal functions, ILT/IAT RVAs, and a pefile
import hash of the standard import table. A missing directory is
observed absence, not proof the image never imported APIs.

* fix(pe): default PE import fixture options

Allow peImportImage() without an argument so CLI and filesystem tests
can use the KERNEL32 sample without repeating an empty options object.

* test(pe): keep import path cases on the dedicated MCP contract

inspect_pe_imports already rejects relative MCP paths in its own
boundary test. Leave the shared absolute-path matrix to tools whose
handler issue projection matches that suite's expected shape.

* fix(native): index virtual-to-file mapping lookups

mappedFileOffset scans every mapping twice per span, so a parser that
translates one span per table entry costs sections x entries. Add
fileMappingLookup, which builds an O(n log n) interval index once and
answers each span in O(log n) with the same accept, reject and
translation results. A differential test checks it against
mappedFileOffset over randomized overlapping mappings and zero fills.

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

* fix(pe): report partial import evidence and exact pefile hashes

- Withhold imphash with an explicit reason whenever the standard import
  table is partial (unreadable names or thunks, missing tables), or when
  pefile 2024.8.26 would hash a different row sequence: invalid or
  truncated names, ordinal 0, descriptors without functions, tables its
  bounds or repeat/spread heuristics discard, and its 8192-thunk import
  symbol cap. Delay-load issues do not withhold it.
- Hash ordinal imports with pefile's complete ordlookup tables and its
  ord<decimal> fallback instead of declining unmapped ordinals.
- Report a nonterminal descriptor whose FirstThunk is zero, and a
  delay-load descriptor whose IAT or INT RVA is zero, as malformed_entry
  partial coverage instead of a complete empty inventory.
- Directory evidence lists the file spans actually consumed for the
  descriptor array and terminator; discontiguous mappings produce
  separate spans and separate Evidence ranges.
- Carry exhausted limits as PeImportLimitFailure.limit and derive
  recovery from it; the fixed 16 MiB retained-text ceiling reports a
  fixed allowance instead of max_file_bytes advice.
- Translate RVAs through the indexed mapping lookup and yield with a
  cancellation check every 1024 table entries.

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

* fix(pe): read only own ordinal tables for DLL names

DLL names such as constructor and __proto__ pass pefile's name rule but
resolved inherited object members, throwing before the ord<n> fallback.

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

* fix(native): preserve PE import facts and prove hash compatibility

* test(native): verify PE import workflows and measured costs

* refactor(native): narrow PE facts across the container union

* docs(native): record integrated PE import validation

* fix(native): bound every PE import RVA span

* docs(native): measure RVA guard completed workflows

* fix(pe): reconcile import coverage with retained rows

* fix(pe): retain partial imports at descriptor mapping gaps

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-24 11:44:12 +08:00
FerroLx e93e3b1e7d feat(apk): inspect signing declarations with retained fact queries 2026-10-22 11:48:09 +00:00
2c3dd946d5 feat(python): inspect CPython pyc headers and marshal code objects (#4826)
* feat(python): inspect CPython pyc headers and marshal code objects

Add inspect_python_pyc / inspect-python-pyc to read one explicit local
CPython 3.7–3.13 .pyc without executing bytecode or recovering source.

* chore(python): drop unused PythonPycHeader export

Knip reported the type as unused after inspect_python_pyc landed.

* fix(python): bound pyc expansion and decode marshal like CPython

- Count a nested code object reached through TYPE_REF once per copy the
  report carries, against max_objects and max_file_bytes, before counting
  or validating the tree
- Charge long digits to max_string_bytes, reject out-of-range and
  unnormalized digits, build the value in one pass, and report integers
  above 256 bits by bit length only
- Decode TYPE_UNICODE with surrogatepass semantics and reject other
  ill-formed UTF-8
- Map only 3.11 magics 3494-3495 to the py311 layout
- Report non-finite float and complex parts as inf, -inf or nan
- Allow an empty co_filename
- Require bytes for co_linetable and co_exceptiontable
- Bind cleanup-failure errors to their retained descriptor leases

* fix(python): list pyc code objects once instead of a recursive tree

Report each distinct code object once in code_objects, top-level first,
with nested_code as indexes. A child shared through TYPE_REF is no longer
copied per reference, and the MCP output schema is no longer recursive.
Names repeated through TYPE_REF still count against max_file_bytes for
each copy the report carries.

* fix(python): bound shared pyc constants and reject malformed tables

- Cache byte-string digests so a buffer shared through TYPE_REF is
  hashed once instead of on every reference.
- Charge every reported co_consts entry, including tables shared
  through TYPE_REF, against max_objects before summaries are built.
- Resolve the inspect-python-pyc path with absoluteCallerPath so
  link/../file.pyc reads the file the filesystem selects.
- Reject TYPE_NULL inside marshal sequences, as CPython does.
- Reject a co_localspluskinds length that does not match
  co_localsplusnames in the parser and the report schema.

* fix(python): bound shared pyc names and read CPython marshal graphs

Charge each reported code-constant name, keep integer bit lengths on the
decoded value, and list code objects nested inside constant containers.
Accept self-referential lists and dicts, marshal version 0 text floats,
empty code names, the original string byte count, and Python set and dict
lengths. Pass the CLI cancellation signal into command cleanup.

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

* fix(python): bound pyc key expansion and shared nested code

Charge set and dictionary keys before a shared tuple doubles them, list each
nested code object once per owner, and accept code objects as CPython keys.

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

* fix(python): correct pyc equality, counts, and nested walks

Summarize code objects only after the marshal graph is complete, and
collect nested code with an iterative walk that shares wrapper results
instead of copying every descendant list. Keep tuple boundaries and the
original string bytes in equality keys, and reject negative CPython counts.

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

* fix(python): bound shared pyc names and keep the first dict key

Charge every copied name-table entry against the object budget before
building the report array, including empty strings that add no bytes.
When dictionary keys compare equal, keep the first key object and
replace only its value, matching CPython.

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

* fix(python): walk each pyc dictionary child list once

Keep a container's child array on the nested-code frame so a wide
dictionary is not copied on every step of the synchronous marshal walk.

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

* fix(python): reuse stored pyc dictionary children when combining

The nested walk keeps each container's child list on its frame.
Combining nested code rebuilt that list, and the 8,000-key regression
still accepted the old per-key copy. Use the stored list, and require
that dictionary to finish well under the copy's runtime while still
reporting a nested code object.

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

* fix(python): keep distinct pyc code objects and reject corrupt ones

Encode each name table's length and entry boundaries in the equality
key so a different name list cannot share a memo key. Walk tuple and
frozenset keys on an explicit stack so a long TYPE_REF chain does not
overflow. Treat code objects CPython rejects for an odd co_code or an
undersized local table as malformed instead of complete coverage.

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>
2026-10-22 19:00:08 +08:00
bfba99827e feat(erlang): inspect BEAM IFF chunks and tables (#4833)
* feat(erlang): inspect BEAM IFF chunks and tables

Replay the Erlang BEAM inspection workflow, including table bounds,
OTP 28+ atom layouts, the shared absolute-path policy, and empty-path
CLI coverage, without carrying GitHub workflow edits.

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

* fix(erlang): use publicInputStrictObject for BEAM tool input

inspect_erlang_beam advertised a public input built with bare
z.strictObject, so later shared input-policy changes would miss it.
Result and internal objects stay on their own constructors.

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 17:46:15 +08:00
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
gensokyo-dev aa51e43439 perf(mcp)!: default to compact input schema advertisements (#5975)
Use compact MCP input advertisements by default while preserving explicit full, canonical validation, output contracts and complete Evidence. Require an explicit selected catalog for runtime identity and honor both profiles in CLI status.

Real ripgrep/Zellij SDK tasks, independent ELF oracle, actual client trials, profile parity workflows and CI are recorded in experiments/analysis-efficiency/mcp-input-catalog.md. SDK token estimates improve; actual Codex token savings and general latency/memory gains are not established.

Refs #5861

BREAKING CHANGE: MCP input advertisements default to compact. Set REA_MCP_INPUT_SCHEMA_PROFILE=full for complete advertised guidance and nested constraints.
2026-10-22 00:17:11 +08:00
gensokyo-dev efab044f30 feat(gpu): inspect static CUDA and HIP code objects (#5813) 2026-10-21 19:06:44 +08:00
gensokyo-dev 98f4072f1f feat(model): inspect GGUF and safetensors declarations (#5603) 2026-10-21 00:50:50 +08:00
JANG BYUNGKUNandgensokyo-dev 833136507d feat(il2cpp): inventory Unity IL2CPP global-metadata images, types and methods (#3807)
* feat(il2cpp): inventory IL2CPP global-metadata images, types and methods

Add inspect_il2cpp_metadata (CLI inspect-il2cpp-metadata), a read-only
in-process decoder for unencrypted Unity global-metadata.dat version 39.
It reports header sections, serialized index widths, images, type
definitions (nesting from the nestedTypes section) and method names.

Unrecognized magic and other versions are unsupported; damaged headers,
overlapping sections, inconsistent record sizes, out-of-range indices and
invalid strings fail with a reason code and no partial success. MCP
detail summary retains the complete Evidence and pages rows through
inspect_analysis_view kind il2cpp-metadata.

Adds an opt-in verify:il2cpp:metadata -- --metadata PATH check.

* feat(il2cpp): deliver metadata summaries by default over MCP

A 112,232-method file produced a 10.5 MB complete response, above the
10 MiB stdio budget. Default MCP delivery is now the retained summary;
detail complete stays available, and the one-shot CLI requests it.

* fix(il2cpp): reject shifted strings, nesting cycles and method owner drift

Review fuzzing showed that moving the strings section offset by one byte
silently renamed every image, type and method. Name indices must now start
a string, which also bounds total decoding by the section size.

Nesting cycles and methods whose declaring type disagrees with the owning
type range are rejected instead of returned. Adds service, shutdown and
index-width coverage, and moves environment-specific measurements out of
the public guide and tool description.

* feat(il2cpp): decode global-metadata versions 29 and 31

Unity 2022.3 writes version 29 or 31 metadata: a 256-byte header of
(offset, size) pairs, fixed 4-byte indices, type records with
elementTypeIndex, and method records that gained returnParameterToken in
version 31. Record counts come from section sizes and must be whole.

Sections report a null count for these versions and index widths report
fixed-width-version. Image, type and method rows keep the same shape, and
the string, nesting and method-ownership checks apply to every version.

* fix(il2cpp): bound report size before serializing and tighten coverage

Rows share decoded names, so a 130 KB file could expand into gigabytes of
JSON before the 64 MiB budget check, ending in an internal RangeError. The
provider now refuses from a lower bound on the serialized rows first.

The decoder also rejects non-empty sections inside the header, methods
outside their declaring type's range and overlapping image type ranges, and
keeps a leading byte order mark in names. Layouts now carry one indexing
mode instead of two coupled flags, and the tool description explains
nested_type_start.

* fix(il2cpp): refuse oversized metadata before decoding rows

Address review findings on the IL2CPP metadata inventory:

- check a lower bound from header row counts before any row object is
  allocated, so a large rejected file no longer builds every row first;
- validate sealed parent Evidence and count its rows once per report
  instead of on every inspect_analysis_view page;
- decode version 39 fixtures with 2- and 4-byte type-definition,
  generic-container and parameter indices.

* docs(il2cpp): attach the decoder comment to readIl2cppMetadata

* fix(il2cpp): deliver complete rows by default like the other inspection tools

inspect_il2cpp_metadata defaulted to detail summary, the only inspection
tool to do so. Omitted detail now returns every row inline, as
inspect_artifact, decode_interface_builder and the capture tools do;
summary stays one argument away and the guide, CLI reference and skill
reference say to select it first for large games, whose complete MCP
delivery is refused at the stdio budget with retained Evidence.

* test(il2cpp): cover narrow-width -1 sentinels and fix the skill's default

An empty image stores its type start as the all-ones value of a one- or
two-byte index; the decoder reads it as -1, but no fixture exercised it,
so removing either conversion passed the suite. The fixture can now append
an empty image, and both widths decode it. The skill still described a
summary default; it now says to select summary first, as the guide does.

* docs(il2cpp): request summary explicitly in the summary example

* chore(il2cpp): hash the verifier metadata through owned file resources

* fix(il2cpp): count escaped name length without building the escaped string

* fix(il2cpp): keep the verifier's check failure and small-table last page

* feat(domain): count JSON string length without building the escaped string

* fix(il2cpp): keep descriptor cleanup owners and share the JSON length count

* test(domain): give the backslash case real backslashes

* fix(il2cpp): select the CLI path and finish the command like the other tools

Follow main's absoluteCallerPath (#4067) and pass the command signal to finishAnalysisCommand.

* fix(il2cpp): select the verifier input path like the CLI

Use absoluteCallerPath (#4067) so a path with a symlink followed by .. names the same file the CLI and MCP inspect.

* feat(il2cpp): add compact composable metadata queries

Retain source-indexed Evidence for filtered batch and field queries. Bound representation growth before serialization, yield decoding for cancellation, and share CLI Evidence publication with desktop inspection. Verify public Unity metadata against independent byte and managed-DLL oracles and exercise actual stdio SDK workflows.

* fix(il2cpp): retain the validated metadata header magic

* test(il2cpp): remove obsolete execution wording exception

* fix(artifacts): preserve export selection and completed source facts

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 07:20:47 +08:00
gensokyo-dev b4938aed58 feat(artifacts): triage desktop installation directories (#5207)
* feat(artifacts): triage desktop installation directories

* fix(artifacts): retain completed probes through failed file cleanup

* perf(artifacts): decode only assembly reference names for desktop triage

* fix(artifacts): enforce exact signatures and responsive directory probes

* fix(artifacts): recognize Unity bundles and bound FORM chunks

* fix(artifacts): retain bounded desktop omission evidence

* fix(artifacts): select ASAR targets before inventory probes

* chore: preserve tested upstream HTTP owner during integration

* fix(artifacts): reuse Mach-O signatures for FAT64 desktop probes

* fix(artifacts): expose bounded desktop probe diagnostics

* fix(artifacts): derive desktop snapshots from observed source identities

* fix(artifacts): admit desktop facts before JSON expansion
2026-10-20 04:01:36 +08:00
c1fd496e6a feat(kuna): serve procedures, pseudocode and assembly from Kuna exports (#3854)
* feat(kuna): serve procedures, pseudocode and assembly from Kuna exports

Register Kuna as a bring-your-own deep-analysis provider. It answers
list_documents, list_procedures, search_procedures, procedure_address,
address_name, procedure_pseudo_code, procedure_assembly and
analyze_function (and batch_decompile through composition) from the
verified project export. While a cold export builds in the background,
pseudocode comes from a single-function `kuna decompile` run on a private
copy and says so; assembly and data names wait for the export.

Each answer records its source and file span in raw_result, limitations
are scoped per operation, and the session-owned export is stopped on
close unless another session still waits for it. The literal/regex
procedure search predicate moves from the IDA runner into a shared
domain helper. `npm run verify:kuna` adds a real-provider lane with an
optional Ghidra comparison.

Refs #1957

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

* fix(kuna): refuse a Ghidra comparison without caller-built targets

Refs #1957

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

* fix(kuna): retry owned cleanup and keep answers bound to the opened Kuna

- Re-verify the Kuna executable's digest before every launch (memoized by
  file identity), so no answer names one build while another produced it.
- Keep the process supervisor of an unproven stop, and retry it on every
  later close in both the session and the cache; a failed close keeps
  failing until the stop is proven instead of reporting success.
- Report an abandoned export's retained cleanup from session close.
- Forget and rebuild an adopted export whose files another REA process
  evicted, instead of failing every later read.
- Close a private copy whose setup failed, and retry failed removals.
- Let the session own the shared quick inventory; each caller only stops
  waiting when it cancels.
- Report a failed export as `failed` with its reason.
- Lane: release the MCP client when open_binary rejects a target, and accept
  either valid source for the first answer.

Refs #1957

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

* fix(kuna): drain session requests before releasing workspaces

Combine caller cancellation with session shutdown and wait for active reads before releasing their process supervisors or private inputs. Retain unproven cleanup for later close attempts. Measure UTF-8 reply bytes without implying model token usage.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* perf(kuna): keep document metadata reads free of target analysis

Listing the selected path no longer initializes the project cache or starts an export that the request never consumes.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* fix(kuna): reject verification matrices with missing functions

Validate requested matrix coverage before building the fixture or opening providers. Empty matrices, unmatched names and partially matched function sets must fail instead of reporting an unperformed comparison as successful.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* fix(kuna): retain component provenance in function dossiers

Record each source facet as one file span and preserve both pseudocode and assembly digests/ranges in combined reports. Keep direct text source fields compatible and verify every combined span through the real MCP lane.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* fix(kuna): keep retired file cleanup bound to its export

Retain the export key with each failed file removal so a cancelled session reports and retries its own stopped resources. Preserve that association across sweeping and process-cleanup recovery without attributing unrelated cache failures to the session.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* docs(kuna): document the Kuna provider and list it in the catalog (#3855)

* docs(kuna): document the Kuna provider and list it in the catalog

Add the Kuna provider guide (configuration, answered tools, cold and warm
paths, provenance, cache ownership, verification lane), link it from the
README and its translations, the CLI, installation and index pages and the
site navigation, describe `npm run verify:kuna` in the testing guide, credit
Kuna in THIRD_PARTY_NOTICES, teach the agent skill when to select Kuna, and
register its identity and operations in the generated product catalog.

Refs #1957

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

* docs(kuna): state the Linux cache fallback, raw_result scope and comparison inputs

Refs #1957

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

* docs(kuna): note that cache pins hold within one REA process

Refs #1957

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

* docs(kuna): describe retired staging and retried cleanup

Refs #1957

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(kuna): supervise regex and bind reads to one export

Share a cancellable ECMAScript matching worker with Hopper while preserving its error contract. Bind C and assembly indexes to immutable project readers, retry whole dossiers after eviction, and enforce the existing buffered-text capacity before allocating cached spans. Document the verified Linux scope and keep complete exports accessible.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-15 00:53:26 -07:00
bcc141549a feat(electron): inspect packaged Electron fuse state without execution (#2399)
Add bounded, read-only inspection of packaged Electron fuse state for ELF, PE, and Mach-O applications through CLI and MCP workflows.

Preserve artifact provenance and unknown values, resolve app bundles without execution, reject malformed or overlapping containers before scanning, and keep output compact for agent use.

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: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-14 09:16:33 +08:00
4aa51bfe19 fix(reverse): reconcile cleanup ownership and mutation diagnostics (#2799)
* feat(process): add owned debugger shutdown lifecycle

* feat(reverse): add local inspection commands

* feat(gdb): add persistent debugger integration

* feat(cutter): add Cutter bridge integration

* test(reverse): enforce complete integration coverage

* fix(process): preserve debugger shutdown ownership

* fix(reverse): retain evidence across interrupted commands

* fix(gdb): honor captured provider environment

* test(process): cover debugger shutdown retries

* fix(reverse): retain evidence for interrupted providers

* test(process): cover debugger shutdown retries

* fix(reverse): retain evidence for interrupted providers

* fix(server): snapshot provider environment at creation

* fix(reverse): close review gaps with complete coverage

* fix(reverse): address inspection review findings

* fix(gdb): bound sessions and retain cleanup ownership

* fix(ci): require reverse-tools quality lane

* fix(process): unref inherited debugger output pipes

* fix(reverse): address remaining PR 1960 findings

* fix(gdb): address remaining PR 1961 findings

* fix(reverse): account for unrestricted provider execution

* fix(process): retain debugger ownership until safe shutdown

* fix(process): preserve replacement debugger sessions

* fix(reverse): preserve admission and output provenance

* fix(process): retain exited debugger until output settles

* fix(mcp): bound provider admission and debugger cleanup

* fix(reverse): preserve failure provenance and classify E2BIG

* fix(gdb): preserve startup cleanup and detach safety

* fix(process): retain debugger ownership after detach failure

* fix(reverse): preserve mutation and failure provenance

* fix(gdb): address debugger review findings

* fix(reverse): rebind sessions after external mutation

* fix(process): cap debugger output after exit

* fix(gdb): protect one-shot detach verification

* feat(debugger): add reverse tool coverage gate

* test(debugger): cover integrated failure paths

* fix(gdb): bound and preserve session observations

* fix(gdb): address review regressions

* style: format merged integration files

* fix(reverse): preserve session and output evidence

* refactor(gdb): share repeated test and partial result setup

* fix(gdb): invalidate TTY proof for Python aliases

* fix(reverse): retain failure output byte counts

* test(process): synchronize late debugger output

* fix(gdb): invalidate TTY proof for wrapped commands

* fix(gdb): recognize wit command abbreviation

* test(reverse): wait for cancelled descendant readiness

* test(reverse): bound descendant cancellation cleanup

* style(reverse): format integration tests and adapters

* style: format reverse engineering integration files

* test(reverse): remove duplicate environment harness

* test(gdb): share session startup assertions

* fix(gdb): invalidate output proof for command abbreviations

* test(reverse): share composition edge case scenarios

* fix(ci): recognize verification and mutation tool entries

* test(rizin): cover successful fake inferior detach

* test(cli): align full output failure envelope

* test(cli): isolate reverse command lifecycle service

* test(process): share debugger output fixture setup

* fix(binary): preserve high-bit Windows signature bytes

* style(binary): format Windows signature parser

* test(mcp): preserve call coverage in unchanged comparison

* fix(ci): include reverse tools Vitest configs in lint cache

* fix(mcp): preserve target content on delivery errors

* ci: align duplication ceiling with expanded suite

* test(reverse): allow signal admission mutants

* fix(reverse): bound retained cleanup failures to process owners

* fix(test): replace drifting mutation ranges with owned selectors

* fix(reverse): admit persistent commands and retain cleanup ownership

* fix(cutter): recover timed-out commands from exact receipts

* fix(cutter): reject unsupported bridge request kinds

* fix(ci): repair client format and shared verification fixtures

* fix(native): preserve debugger cleanup ownership and bridge authentication

* test(native): retain diagnostics without perfect coverage requirements

* chore(licenses): refresh locked dependency inventory and notices

* fix(test): exclude transient command locks from mutation sandboxes

* fix(gdb): admit only platforms with safe detach verification

* fix(cutter): retain bounded completion receipts until acknowledgement

* fix(cutter): acknowledge commands rejected before UI dispatch

* test(reverse): fail cancellation checks before fixture teardown

* test(gdb): clean up the retained broken-stdin fixture owner

* docs(test): clarify focused provider verification scope

* fix(rizin): retain close cleanup failures

* fix(gdb): wait for inferior stop and bound MI buffering

* fix(cutter): retain failed receipt acknowledgements

* fix(rizin): return retained session identity on rebind failure

* fix(gdb): preserve startup cancellation and lossy status

* fix(rizin): retain launch provenance and assemble frames once

* fix(cutter): recover receipts across callers and bound discovery

* docs: describe debugger evidence and bridge recovery

* fix(process): keep cleanup incomplete while writers remain

Stopping a debugger no longer reports success when inherited output
streams stay open, so BinarySession cannot reopen a binary a child is
still changing. Concurrent Cutter cleanup retries share one receipt
acknowledgement instead of treating a consumed receipt as failure.

* fix(debuggers): recover cleanup with captured process identities

* fix(analysis): retire sessions after unrestricted commands

* fix(cli): preserve completed evidence after cleanup recovery

* fix(cutter): bound frame collection and coalesce cleanup

* fix(windows): resolve selected provider paths absolutely

* fix(gdb): report decoding loss in failed startup evidence

* fix(rizin): scope decoding loss to collected command frames

* test(mcp): cover snapshot retirement in reverse tools CI

---------

Co-authored-by: Daniel Gonçalves Araujo <47118053+dandgabr@users.noreply.github.com>
Co-authored-by: REA Maintainers <noreply@github.com>
Co-authored-by: OpenAI Codex <codex@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-14 04:47:34 +08:00
0e6eca4085 feat(native): read embedded cargo-auditable Rust dependency lists (#2456)
* feat(native): read embedded cargo-auditable Rust dependency lists

* fix(native): trim PE section padding and compute dependency cycles iteratively

* fix(native): ignore SHT_NOBITS sections and validate dependency edges linearly

* fix(native): bound compiler path scanning and retained hashes

* fix(rust): pass package arrays as named parameterized test cases

* fix(rust): admit graph expansion and preserve resource units

* fix(rust): reject malformed packages, false cycles, and hidden compiler paths

Fail the first malformed cargo-auditable package before Zod collects an
issue per field. Require cyclic dependency indices to match the cycles in
package dependencies. Keep read-only ELF ranges when a section name does
not fit the bounded name window, so a rustc path in that range is still
reported.

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

* fix(go): verify Mach-O sections against segments

---------

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: Cursor Agent <cursoragent@cursor.com>
2026-10-14 02:50:30 +08:00
Thang LuuandThang Luu 911894d758 feat(wasm): compare retained core-module interfaces (#2464)
Squash merge of https://github.com/morluto/rea/pull/2464.

Co-authored-by: Thang Luu <76550342+thangldw@users.noreply.github.com>
2026-10-13 23:49:04 +08:00
Quentin LimoandN0zoM1z0 9581e067ad feat(pcap): add bounded capture summaries through CLI and MCP
Summarize saved Wireshark4.x captures with enforced native resource limits, serialized admission, stable snapshot verification and retained fact/text pages. Preserve complete inventories within resource budgets and source uncertainty; report cleanup failure with partial Evidence and retained ownership.

Verified six recorded corpora /13026 packets with independent Scapy/Python oracles, real CLI/MCP/schema parity,60 SNI names,132 DNS addresses and1000 URIs. Real TShark CI now exercises summary/paging. Actual Windows/Bun Wireshark remains unverified; macOS capture requires a separate enforceable-bound decision.

Co-authored-by: 3QL <85309073+3QL@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 04:53:03 +00:00
a2d8b94dd5 feat(fiddler): inspect native SAZ captures
Inspect bounded recorded raw HTTP/XML SAZ archives and page retained capture Evidence. Preserve exact stored bytes and provenance, validate ZIP/XML integrity, and require an enforceable decoder memory bound.

Verified 356 real recorded sessions against independent byte and metadata oracles, public CLI/MCP parity, retained pages, and related interface checks. Current Fiddler Everywhere GUI and non-Linux producer workflows remain unverified.

Co-authored-by: zahhak <1792039+zahhak@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-13 02:51:14 +00:00
YsopwnableandOlorinm 91b8f587cd feat(signals): decode recordings with bounded sigrok output (#2339)
Decode caller-selected protocols from existing recordings through shared
CLI/MCP Evidence. Page literal output lines after complete decoding;
preserve explicit full output, source identity and failed cleanup ownership.

Verified real sigrok-cli 0.7.2 workflows, published UART/SPI/I2C recordings,
independent UART values, selector limits, SDK schemas and cleanup regressions.

Co-authored-by: Olorinm <59321404+Olorinm@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 20:59:02 +00:00
YsopwnableandOlorinm f611d8ce72 feat(captures): inspect recorded packets with bounded TShark delivery (#2318)
Inspect selected fields in existing captures through shared CLI/MCP Evidence.
Page matching frames without changing dissection or two-pass read coverage;
retain failed descriptor/process cleanup ownership and reject excess admission.

Verified with real TShark 4.0.17 and 4.2.2, public Wireshark recordings,
owned HTTP application traffic, real CLI/MCP workflows and schema checks.

Co-authored-by: Olorinm <59321404+Olorinm@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 19:35:35 +00:00
YsopwnableandY0UW1SH aeee5074d1 feat(sqlite): inspect offline snapshots with selective evidence (#2271)
Add offline SQLite database/WAL inspection through the shared CLI/MCP.

Use compact inventory, selected-table schema, exact ordered columns and
bounded row samples while preserving source identity and lossless values.
Retain completed Evidence through late cancellation and private-root cleanup
failures, bound concurrent inspections, and recheck journal validity after
acquisition. Reuse prepared CI runtime artifacts across supported Node lines.

Co-authored-by: Y0UW1SH <29498139+Y0UW1SH@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-12 18:33:23 +00:00
e4d3e1399d feat(flutter): identify Dart snapshot builds and inspect AOT payloads by pure APK parsing (#1582)
* feat(flutter): identify Dart snapshot builds by pure APK parsing

Add a flutter-provider family with one operation, identify_flutter_build,
that reads an APK's lib/<abi>/libapp.so and libflutter.so through the
hardened ZIP reader and reports build facts as observations:

- The Dart VM snapshot hash, read 20 bytes after every snapshot magic
  (f5f5dcdc). The vm and isolate sections are cross-checked: agreeing
  sections collapse to one snapshot_hash, disagreeing sections keep every
  candidate with snapshot_hash null and partial coverage.
- Per-ABI library digests and byte sizes, plus the engine library's GNU
  build-id note and any labeled 'Dart VM version' or Android clang/LLVM
  toolchain strings, verbatim; release builds without a version string
  report null rather than a guess.
- The APK is digested before parsing so Evidence binds the observation to
  the exact input, and a target with no libapp.so reports not-detected
  with complete coverage.

The scanner is streaming with explicit pending-magic and rescan
bookkeeping, so chunk boundaries cannot double-count or drop sections, and
magic-free streams never accumulate. No engine, no external lookups: the
hash-to-SDK mapping stays with external datasets by design.

Verified against Flutter Gallery 2.9.2 (112 MB, three ABIs): every ABI
reports the same agreeing hash 65817c30a78bb44c3dc3771876b6010a from two
sections, per-ABI build-ids, and the clang toolchain line; a plain
aapt2-built APK reports not-detected with complete coverage. Scanner
goldens come from the same libraries. READMEs carry the new 'Flutter apps'
row in every supported language.

* feat(flutter): inspect Dart AOT snapshots through the ELF symbol table

Add inspect_dart_aot to the flutter family: for one ABI's libapp.so it
locates the four _kDart*Snapshot* symbols through the ELF dynamic symbol
table (ELF32 and ELF64 little-endian, bounds-checked reads; a payload
without exported symbols is refused), reports each section's offset and
size, validates data-section headers (magic, kind, length; instructions
sections honestly report nulls for the fields their layout does not
carry), and projects a bounded string pool from the isolate data section:
distinct package: source URIs (the app's dependency inventory), dart: SDK
URIs, and identifier-shaped tokens, each with counts, bounds, and partial
coverage when truncated.

The string pool is labeled as a byte-pattern projection, not deserialized
cluster semantics: typed class and function recovery remains an
SDK-specific parser, which the snapshot hash now unlocks. The ABI is
caller-selected with a deterministic default (arm64-v8a, x86_64, then
first available).

Verified against Flutter Gallery 2.9.2: all four symbols on both ELF64
(arm64-v8a) and ELF32 (armeabi-v7a) images, header validation, hash
agreement with identify_flutter_build, and a 756 package: / 201 dart:
URI pool from the isolate data section; goldens in DartElf.test.ts come
from the same libraries.

* fix(flutter): own snapshots, bound image reads, and preserve cancellation

Mirror the ownership bar the maintainers applied across the merged JEB,
ADB, and Apktool PRs:

- Copy the admitted APK into a provider-owned, read-only snapshot (EXCL
  create, chmod 0400) before digesting and parsing; every later read uses
  the snapshot, so a concurrently modified original cannot mix into one
  observation. The result reports the snapshot's byte size and digest.
- Retain failed snapshot-root cleanup in a provider set and retry it on
  close(), throwing an aggregate error when a root is still owned; root
  removal is injectable so the retention is testable.
- Allocate the AOT image buffer at exactly the declared library size
  before reading (bounded before allocation, not concat-after-stream),
  keep the 256 MiB ceiling, and check cancellation between digest and
  stream chunks through a captured abort reason.
- Accept APK paths containing spaces (covered by a fixture test) and
  escape the ABI pattern's dash for v-mode regex compatibility.

Also add tests for cleanup retention with close retry and for
cancellation before any snapshot root is created.

* docs(flutter): cover the Italian README with the Flutter row

The Italian translation landed between the merged feature PRs; its table
now carries every merged row plus this one, keeping its documentation-link
set identical to README.md.

* fix(flutter): make the ABI pattern portable for v-mode validators

Use a hex-escaped hyphen in the ABI character class, matching the form
the ADB portability fix uses, so clients compiling advertised schemas in
unicodeSets mode accept the inspect_dart_aot input schema.

* refactor(flutter): reuse shared harnesses and deduplicate the vertical

The duplicate-detection gate (jscpd, 2.5% threshold) tipped to 2.51% with
the flutter files added. Reuse the existing machinery instead of repeating
it:

- FlutterBuildAnalysisService delegates to executeProviderOperation, the
  shared admission/Evidence composition, instead of restating its body.
- The CLI registers both commands from one table-driven spec.
- Boundary tests use the shared serveCli and assertAdvertisedMcpContracts
  harnesses rather than hand-rolled equivalents.
- The provider test consolidates the four payload-shape cases into one
  table-driven case; the service test uses one admission table and
  distinct phrasings.

Duplicate lines fall from 2.51% to 2.48%, back under the gate.

* fix(flutter): address review findings from real-app verification

CassieFox23 verified the PR against three real F-Droid Flutter apps and
a control app, and found five gaps. All are fixed and re-verified against
cone (info.tangential.cone), one of the tested apps:

- Build-id: the scanner now reads the descriptor length from the note
  header instead of assuming 20 bytes, so 8-byte ids from older
  toolchains parse; the schema accepts 8-128 hex characters. Verified
  against cone's readelf-reported ids on all three ABIs.
- Compiler line: the toolchain capture bound rises from 200 to 500
  characters, keeping cone's 262-character clang line verbatim.
- Zero-byte libapp.so: the extraction target is created before streaming,
  so an empty entry yields a clean unsupported_target refusal for
  inspect_dart_aot and elf_header_valid: false with partial coverage for
  identify_flutter_build, instead of a raw ENOENT with code UNKNOWN.
- Truncated library: identify_flutter_build marks fewer than two snapshot
  sections as partial coverage with a limitation naming the count, and a
  missing ELF magic gets its own limitation.
- Docs: the default ABI preference now matches the code exactly
  (arm64-v8a, x86_64, x86, armeabi-v7a, then the rest alphabetically).

Also: every test that read the author's /tmp/opencode goldens now builds
a self-contained synthetic ELF64 image with dynsym, four snapshot
symbols, two snapshot sections, and a string pool, so the suite runs
anywhere; the verify lane now requires a present hex build-id per ABI
instead of accepting null.

* fix(flutter): address the Codex review findings

Eight findings, all applied:

- P1: SnapshotHashScanner keeps candidates in a Set (no quadratic
  Array.includes) with a 64-distinct-hash cap, so a hostile payload of
  magic+hash records cannot stall the scan or bloat the response.
- P1: projectStringPool stops admitting new distinct entries once each
  category reaches twice its projection bound and reports
  collectionCapped; allocation and sorting now track the response, not
  the payload.
- P2: ZIP reader rejections during entry iteration or entry streaming
  map into the typed error algebra (cancellation vs input refusal)
  instead of escaping as unhandled exceptions in both operations.
- P2: magic_valid now marks coverage only for the *Data symbols; a
  complete four-symbol image with valid data magics reports complete
  coverage (the instruction symbols intentionally lack the magic).
- P2: the MCP server closes the Flutter provider during shutdown, so a
  retained snapshot root is retried and reported, not leaked.
- P2: LabeledStringScanner commits matches only when a printable run is
  delimiter-terminated; the carry grows to 600 bytes so a 500-character
  toolchain line survives any chunk boundary untruncated.
- P2: both Flutter tool effects declare writesFilesystem: true; the
  owned APK snapshot and extracted libapp.so are temporary writes.
- P2: the verify lane asserts every ABI agrees on exactly one snapshot
  hash instead of discarding the computed set.

* fix(flutter): address the second Codex review round

Nine findings on the first-round fixes:

- P1: identify_flutter_build enforces a cumulative extraction budget
  (768 MiB) across every library entry, not just per library, so an APK
  with many ABIs cannot stream an unbounded total.
- P1: a single NUL-free printable run stops materializing at 1024 bytes
  and marks the pool capped, so an adversarial one-run section cannot
  allocate unbounded strings.
- P1: ELF cString bounds the NUL-terminator scan to the name maximum
  plus one, so malformed symbol tables cannot scan the whole image per
  entry.
- P2: mapReaderFailure distinguishes ArtifactReaderFailure texts —
  budget/limit rejections map to resource constraints, integrity
  failures (CRC/overlap/signature) to their own input refusal — instead
  of collapsing all reader failures into one message.
- P2: the labeled-string carry is cleared when a delimiter commits a
  run, so consecutive toolchain lines are never concatenated.
- P2: string-pool counts are renamed *_count_at_least and documented as
  lower bounds, because capped collection discards values beyond twice
  the projection bound.
- P2: inspect_dart_aot marks hash disagreements, non-pair source counts,
  and candidate-cap saturation as partial coverage.
- P2: only valid lowercase-hex hash records count as snapshot sources;
  complete magic records with non-hex fields do not inflate agreement.
- P2: the per-entry size refusal in inspect_dart_aot moves after ABI
  selection, so an oversized unselected ABI no longer refuses a small
  request.

* fix(flutter): address the third Codex review round

Five findings:

- P2: the owned snapshot revalidates the source after the copy (size,
  mtime, inode), so an in-place replacement or swap mid-copy refuses
  the observation instead of publishing mixed bytes.
- P2: a failed ZipArtifactReader close retains the snapshot root for
  close() retry instead of silently swallowing the descriptor leak,
  in both operations.
- P2: snapshot headers are parsed within their symbol bounds and a
  symbol smaller than the 16-byte header reports magic_valid false,
  so trailing-image bytes can no longer fake a valid data section.
- P2: the verify lane counts provider.close() cleanup failures as
  lane failures instead of certifying a run with retained roots.
- P2: LabeledStringScanner reports toolchain_capped when further
  distinct matching lines are observed past the 4-line projection;
  identify marks such results partial with a naming limitation.

* fix(flutter): address rounds three and four of the Codex review

Round three (one missed finding) plus round four (five findings):

- P2: the GNU build-id note descriptor size is decoded from all four
  bytes of the little-endian field, rejecting nonzero high bytes
  instead of masking them to 16 bits.
- P1: the Flutter MCP handlers route through createContractToolHandler
  and the session's analysisAdmission, so close_binary and snapshot
  operations drain in-flight Flutter calls instead of racing them.
- P2: the owned-snapshot copy is a streamed, abort-checked write (no
  copyFile), so cancellation stops the write promptly while the
  source-identity revalidation (size, mtime, inode) still guards
  against mid-copy replacement.
- P2: identify marks any snapshot_hash_sources value other than exactly
  two as partial, matching the inspection path's pair requirement.
- P2: the verify lane refuses to run without --apk (exit 2) instead of
  printing a false-green pass, and the engine check requires every
  libapp-carrying ABI to have a present libflutter with a valid hex
  build-id rather than filtering missing engines away vacuously.

* fix(flutter): address the fifth Codex review round

Six findings plus the upstream duplication baseline:

- P2: the flutter-provider kind reports available in the capability
  inventory, so binary_session no longer lists always-registered
  Flutter tools as provider_missing.
- P2: printable runs that exceed the 1024-byte cap are discarded at
  their delimiter instead of emitting their truncated prefix as a
  fabricated observation.
- P2: ELF symbols must fit inside the file-backed portion of their
  PT_LOAD segment (p_filesz), so addresses in gaps or BSS are refused
  instead of accepting unrelated bytes.
- P2: the build-id carry spans the complete 80-byte maximum note
  (16-byte header + 64-byte descriptor) so chunk-boundary splits
  cannot drop the first byte.
- P2: the labeled-string carry is sized for the toolchain pattern's
  true 605-byte maximum, not the previous 600.
- P2: the AOT completeness predicate requires exactly two sources and
  one candidate unconditionally, so zero-source images with valid data
  magics report partial instead of complete.

Also: the shared ELF fixture builder and snapshot-section helper moved
to a dedicated FlutterTestFixtures module, eliminating cross-file test
duplication; jscpd now passes at 2.50% while main sits at 2.52%.

* fix(flutter): address the sixth Codex review round

Five findings:

- P2: snapshot-hash scanning is bounded to the exported data symbols'
  byte ranges, so decoy or stale magic/hash sequences elsewhere in the
  image cannot inflate source counts or contribute candidates.
- P2: labeled-string runs longer than the carry bound are rejected
  instead of truncated, preventing a regex prefix from being published
  as a verbatim source string.
- P2: the AOT image reread checks cancellation between file reads and
  before the synchronous parsing stage, so a cancelled caller cannot
  receive a success from a completed 256 MiB read.
- P2: the verify lane requires exactly two snapshot sources per ABI,
  matching the provider's pair requirement, instead of accepting any
  count >= 2.
- P2: ELF section and program header entry sizes are validated against
  the class-defined minimum widths before walking either table, so
  undersized entries cannot cause field reads to cross into
  neighboring bytes.

* fix(flutter): address the seventh Codex review round

Six findings:

- P2: data-symbol ranges are deduplicated by offset and size, so aliased
  symbols mapping to the same bytes are scanned once and the result
  marks partial coverage with a limitation naming the shared range.
- P2: openEntrySafely forwards return/throw to the underlying Readable's
  iterator, so an early for-await exit closes the ZIP entry stream and
  releases its producer instead of leaking a backpressured pipe.
- P2: inspect_dart_aot now reports snapshot_hash_candidates and
  snapshot_hash_sources alongside snapshot_hash, so a null hash from
  conflicting evidence is distinguishable from missing hash data.
- P2: overlong printable runs only set toolchain_capped when they begin
  with a recognized label prefix (Dart VM version: or Android (); other
  long strings such as license text are skipped without marking partial.
- P2: readElfSymbol falls back to PT_DYNAMIC/DT_SYMTAB when section
  headers are absent (e_shnum 0, ET_DYN), so stripped Flutter libraries
  with exported snapshot symbols are no longer refused; the dynamic
  table is bounded by DT_STRSZ, DT_SYMENT, and the image end.
- P2: the verify lane exercises inspect_dart_aot for every ABI carrying
  libapp.so, not just the preferred default.

* fix(flutter): address the eighth Codex review round

Five findings:

- P2: each data-symbol range gets a fresh SnapshotHashScanner so the
  carry from one noncontiguous slice cannot fabricate a record spanning
  into the next; results are aggregated after scanning.
- P2: dynsym name lookups are bounded to the linked string table —
  st_name offsets outside the table and terminators beyond it are
  rejected instead of reading unrelated payload bytes as symbol names,
  in both the section-header and PT_DYNAMIC paths.
- P2: identify_flutter_build routes its reader.entries and reader.open
  calls through the same collectEntriesSafely and openEntrySafely
  wrappers as inspect_dart_aot, so malformed ZIPs surface as input
  refusals instead of AnalysisProtocolError.
- P2: mapReaderFailure recognizes ArtifactReaderFailure texts carrying
  a cancelled reason, mapping them to AnalysisCancelledError instead
  of AnalysisInputError.
- P2: the cumulative extraction cap is enforced inside the chunk loop,
  not after each library completes, so refusal happens before the
  remaining bytes are streamed and hashed.

* fix(flutter): harden streaming, sizes, and cancellation after self-review

Four issues found in a systematic self-audit across all bug classes
from eight Codex rounds:

- createReadStream in both the digest function and the owned-snapshot
  copy now receives the AbortSignal directly, so cancellation aborts
  the filesystem read at the source instead of waiting for the next
  chunk to arrive on a slow filesystem.
- The owned snapshot enforces a 2 GiB APK-level size cap before any
  copy I/O, so a path pointing at an enormous file is refused before
  disk usage grows.
- identify_flutter_build preflights the sum of declared entry sizes
  against the 768 MiB cumulative budget, refusing before any ZIP
  extraction when the declared total already exceeds it.
- The LabeledStringScanner triple result() call is collapsed to a
  single invocation (the previous code called result() three times in
  the emission, relying on end() being idempotent).

No behavior change for valid inputs; all 36 tests, check:fast, and
the cone verify lane pass unchanged.

* fix(flutter): require structurally parseable ELF headers for complete coverage

CassieFox23's third corrupt-header case: an ELF with valid magic but
zeroed section/program header offsets passes the 4-byte magic check
and the byte scanner still finds hash patterns in the data sections,
so identify_flutter_build reports complete coverage for a structurally
broken file.

The elf_header_valid check now also verifies beyond the magic:
e_type must be a known value (ET_REL/ET_EXEC/ET_DYN), at least one
of e_shoff/e_phoff must be non-zero, and at least one of
e_shnum/e_phnum must be non-zero. A file with valid magic but zeroed
structure reports partial coverage with the existing ELF-magic
limitation.

* fix(flutter): validate ELF and snapshot coverage

Share bounded ELF header parsing between identification and inspection. Accumulate headers across ZIP chunks and validate table entry widths and extents before claiming complete identification coverage.

Bind AOT hashes to the exported VM and isolate headers, validate stored snapshot lengths including the magic bytes, and preserve partial evidence for missing, malformed, aliased, or overlapping data headers.

Preserve native stream cancellations and APK resource constraints across both operations. Bound snapshot copies while streaming and retain useful input-failure diagnostics and lower-bound count wording.

Validation: 72 focused tests; check:fast; check including formatting; docs:check; test discovery; jscpd; real cone APK and non-Flutter control on Linux. Verified CLI/MCP parity for valid and corrupted ELF headers and AOT inspection across three ABIs. Native Windows and macOS were not run.

* fix(flutter): unify artifact ownership and bound ELF evidence

* fix(flutter): preserve ELF provenance and partial coverage

Read GNU build IDs only from bounded ELF note ranges and retain conflicting candidates. Preserve source versus owned storage failures and honor cancellation through parsing and final cleanup.

Separate snapshot structure from string-pool coverage. Verify every Gallery ABI with digest-bound engine labels and URI counts, and document the supported snapshot-kind layout.

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 22:35:55 +08:00
Daniel Gonçalves AraujoandN0zoM1z0 4a4ae9b2b9 feat: add Frida instrumentation support (#1359)
* feat: add Frida instrumentation support

* fix: resolve Frida CI checks

* test: cover Frida contract validation branches

* docs: link Frida instrumentation guide

* fix(frida): handle cancellation cleanup safely

* fix(frida): address PR review findings

* fix(frida): preserve resume and message observations

* fix(ci): use canonical registry for rolldown

* fix(frida): declare foreign code effects

* fix(frida): retain failed startup resources for cleanup retries

Keep failed startup session and spawn handles owned until detach, resume,
and remote lease cleanup complete. Serialize retries and release each
remote reference once. Await CLI provider cleanup while preserving the
primary failure and any completed observations.

Add regressions for retained startup resources, concurrent cleanup,
shared remote leases, and CLI cleanup outcomes.

Validation: 41 focused tests pass on the PR head and its latest-main
integration; serial static and docs checks pass. Real Linux Frida 17.23.2
workflows and the native spawn/controlled-failure cleanup probe pass.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-12 22:01:58 +08:00
You Wishandmorluto a1b5d51a8d feat(go): inspect embedded binary build metadata (#1363)
* feat(go): inspect embedded binary build metadata

* fix(go): preserve byte metadata and validate container mappings

* fix(go): support moduleless legacy build metadata

Recognize optional module string headers in declared zero-filled memory while rejecting ambiguous and unmapped pointers. Preserve the original module-pointer field as the zero-byte source anchor.

Classify initial symlink-loop and overlong-path failures as invalid input, with CLI and MCP regressions.

* fix(go): reject undersized PE optional headers

* fix(native): stabilize ELF memory checks and clean up exec wrappers

Use existing parent/group/run-token ownership for caller-selected Python launchers, which can exec through a shell or prlimit. Add cancellation regressions for the valid wrapper and wrong-parent/token cases.

Replace the timing-dependent 30,000-section memory workload with a valid 32 MiB padded ELF under a 64 MiB address-space limit. Check the same image successfully through CLI and MCP before requiring a typed memory failure, preserving the production timeout and all error assertions.

Validation: npm run check and check:fast passed; 61 focused tests passed including Go CLI/MCP and session snapshots. Real decoder probes with pinned packages passed on Python 3.12.3 and 3.12.14. The full local ELF verifier is blocked by this container's procps/process-ownership boundary; the exact pushed head requires GitHub's real-binary-layout lane.

* test: repair Electron fixtures and stabilize catalog startup checks

Declare Electron imports in option, preload override, and path-resolution fixtures after upstream began requiring proven API provenance. Retain all option and preload assertions and adjust exact source ranges for the added import line.

Use the existing bounded acceptance timeout for the cold catalog lifecycle test instead of a separate 15-second ceiling. This retains the coverage allowance and all catalog, error, and cleanup assertions without retries.

Validation: npm run check, final check:fast, formatting and diff checks passed. Source path regression and Go boundary/MCP/service checks passed. All 20 Go CLI cases and both supported-host runtime cases passed on rerun; two macOS-only cases skipped on Linux. A prior contended local run timed out once in a Go CLI diagnostic; that case passed on rerun. Electron process-boundary verification is blocked locally by procps namespace inspection and requires fresh CI.

* test(mcp): isolate nested schema references between tool contracts

Clear Ajv's non-meta schema registry after each root, including compilation failures. Disabling root registration alone leaves nested IDs available to later tools and can let a dangling reference pass the catalog gate.

Add regressions for leakage after successful and failed compilation while retaining shared meta-schema validators. The regression failed before the fix; all 11 schema cases and full npm run check pass. Reviewed independently.

* test(ci): align Go effects and source-map verification contracts

Audit the Go inspector wording as static metadata inspection. Assert retained source declaration indexes in BOM reconstruction and the compiler-derived nested-map oracle. Keep a 45,000-map admission control below the 32 MiB output budget and the 50,000-map overflow case above it with the expanded representation.

Validation: reproduced all four failing assertions, then passed 120 focused tests and the final admission suite. npm run check and real Chrome 154 / esbuild 0.25.10 source-map verification passed, including all four nested-map scenarios and verified process lineage.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 11:34:02 +08:00
Thang Luuandmorluto ffaf2c12f1 feat(wasm): inspect local artifacts with WABT (#1533)
* feat(wasm): inspect local artifacts with WABT

* fix(wasm): preserve custom names and failed cleanup ownership

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 19:49:00 +08:00
96fd98cce0 feat(apktool): decode Android resource tables through a caller-supplied launcher (#1556)
* feat(apktool): decode Android resource tables through a caller-supplied launcher

Add an Apktool family with two operations over the caller's apktool
launcher (REA_APKTOOL_COMMAND, absolute, or apktool on PATH):

- inspect_apktool_client: resolved launcher, selection source, and
  version; decodes nothing.
- decode_android_resources: apktool d --no-src in a provider-owned
  workspace that is removed before the result returns. Projects the
  decoded AndroidManifest.xml (bounded at 512 KiB), apktool.yml version
  and SDK facts exactly as printed, string resources verbatim (default or
  one locale, bounded at 2000 entries, nested-markup entries counted as
  unparsed), available string locales, and the decoded file count with a
  hard cap. The target APK is digested with SHA-256 before decoding so
  Evidence binds the observation to the exact input.

Smali production is skipped by design: Java-source recovery belongs to
the JADX family. Workspace cleanup happens before results return; an
unremovable workspace is named in the limitations instead of abandoned.

Verified against apktool 2.7.0-dirty (Debian packaging) on Linux with
OpenJDK 25 against a signed aapt2-built probe APK with two resource
locales: launcher version, on-disk digest agreement, metadata projection,
manifest package agreement, and both string tables (default and de).
Parser goldens come from the same decode. READMEs carry the new
'Android resources' row in every supported language.

* fix(apktool): own snapshots and bound decoded resource reads

* docs(apktool): describe owned resources and bounded projection

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:04:12 +08:00
749e58772a feat(jeb): add JEB engine provider over its MCP interface (#1536)
* feat(jeb): add JEB engine provider over its MCP interface

Add a bring-your-own JEB provider that serves project, unit, and
decompilation inspection from a caller-started JEB client speaking MCP
(streamable HTTP, selected with REA_JEB_MCP_URL). Expose four provider-neutral
operations through shared CLI/MCP workflows: inspect_jeb_client,
open_jeb_project, list_jeb_units, and decompile_jeb_item, each returning
Evidence with engine identity, endpoint, and preserved refusal reasons.

The adapter keeps JEB's envelope semantics: success fields are parsed
format-aware at the boundary, message-only refusals become unsupported-target
errors with the engine's own reason, transport failures become availability
failures with recovery guidance, and unit pagination derives coverage from the
engine's 100-item page cap. Explicit unknowns (implicitly selected unit,
omitted filters) are reported instead of guessed.

Verified against a real JEB 5.48.0 licensed build serving jeb-mcp-server 1.3.0
headless: client inspection, unit listing, and method decompilation were
exercised through the CLI, MCP boundary, and scripts/verify-jeb.mjs.
JEB 5.48.0 headless instances do not advertise open_project; the refusal is
preserved and documented.

* fix(jeb): verify against a real signed APK and fix CLI option surface

Verify the provider against a locally built, v1/v2/v3-signed probe APK
(binary manifest, classes.dex with a launcher activity) on JEB 5.48.0: the
full unit tree (apk, manifest, three certificate units, dex bytecode,
decompiler), wildcard-filtered and paginated unit listing with derived
coverage, parent-restricted listing, and launcher-activity method
decompilation through both CLI and MCP, including dexdec's inline
constant folding of the probe's obfuscated tag.

Move list-jeb-units filter/pagination and decompile-jeb-item unit selection
from positional arguments to options; the MCP schemas are unchanged.

* fix(jeb): preserve engine refusals through the real MCP boundary

Testing against the published Signal 8.30.3 universal APK exposed a boundary
bug the scripted provider tests missed: decodeJebToolResult raised a protocol
error for isError results before the provider could map JEB's
{success:false, message} envelope, so real engine refusals surfaced as
unreadable output instead of the engine's own reason. Decode refusal
envelopes like any structured result and let the provider preserve the
reason; cover the decoder directly, including contentless and unparseable
results.

Signal verification: full 109 MB R8/Kotlin/Compose APK with four signature
schemes and native arm64 ELF units parsed; MainActivity.onCreate and R8
synthetic lambdas decompiled through CLI and MCP; paginated, filtered, and
parent-restricted unit listing; refusal path confirmed on the live engine.

* docs(jeb): record Flutter Gallery verification on the real-engine lane

Verify the provider against the official Flutter Gallery 2.9.2 release APK
(112 MB): per-ABI libapp.so Dart AOT snapshot images analyzed as native code
with 75k methods on arm64, snapshot internals and wrapper methods decompiled
through both CLI and MCP with explicit unit selection, decoded manifest, and
filtered native-library unit discovery. Note that JEB 5.48.0 headless does
not expose the dedicated Dart snapshot processor or run_script; both remain
GUI-only engine surfaces.

* docs(jeb): translate the README JEB row for every supported language

The JEB row was inserted in English across all translated READMEs; each now
carries its own label, capability summary, requirements, and guide link
following that language's Android-row conventions.

* fix(jeb): enforce local endpoints and preserve cancellation

* fix(jeb): refuse redirects across the local MCP boundary

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:03:27 +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
fef6f73064 feat(adb): complete ADB device support for Android reverse engineering (#1552)
* feat(adb): acquire installed APK sets from connected Android devices

Add a read-only ADB device-acquisition family over the caller's adb binary:
inspect_adb_client, list_adb_devices, inspect_adb_device, list_adb_packages,
and pull_adb_package, exposed through the CLI and MCP with shared admission,
Evidence provenance (binary, version, serial, transport), and fixed argv
vectors that never reach a shell.

pull_adb_package acquires the complete split set reported by pm path into a
package-named directory that must not exist, digesting every file with
SHA-256 and keeping per-file failure reasons and partial coverage. Device
kind is reported as an inference with its basis; getprop whitelisting keeps
build identity bounded. REA installs nothing and never manages devices or
emulators; the first device query may start the caller's local adb server,
recorded when observed.

Verified against adb 34.0.5 on Linux with an Android 14 (API 34) x86_64
emulator: full 224-package inventory, a real two-APK split set pulled with
byte-exact digests, and a 73.9 MB system-package pull. npm run verify:adb
records the lane; parser goldens come from the same device. READMEs carry
the new row in every supported language.

* feat(adb): complete the adb surface with observation, transfer, and lifecycle tools

Extend the ADB family from five to twenty-four operations, all through
fixed adb argument vectors with no shell exposure:

Observation: read_adb_logcat (bounded dump, count/buffer/pid), inspect_adb_package
(dumpsys package projection), list_adb_processes (ps -A), list_adb_directory
(ls -la with kinds and symlink targets), list_adb_features (hex GL versions),
list_adb_services (AIDL slash-suffixed names), inspect_adb_display (wm size and
density), inspect_adb_window (focus declarations), read_adb_setting (device-side
nulls reported as such), capture_adb_screen (exec-out screencap with PNG
dimensions), collect_adb_bugreport (digested device archive).

Transfer and search: pull_adb_file and push_adb_file (device-side sha256sum
verification, explicit overwrite authority), resolve_adb_packages (substring
package search with exact-match flag — the find step of an easy get).

Lifecycle for dynamic analysis, each declaring mutatesTarget:
install_adb_package and uninstall_adb_package preserving the device's
Success/Failure verdict, start_adb_app (resolve-activity then am start -W),
start_adb_activity (typed extras as --es/--ez/--ei/--el/--ef), and stop_adb_app
(am force-stop).

Verified end-to-end against adb 34.0.5 on Linux with an Android 14 (API 34)
x86_64 emulator: 287 services, 92 features, split-set pulls with byte-exact
digests, verified push/pull roundtrip, sized screen capture, and the full
install → resolve → start → observe-in-ps → force-stop → uninstall lifecycle.
Fixed a v-mode regex incompatibility in the settings key pattern and added
argument descriptions required by the CLI catalog audit.

* fix(adb): quote remote shell operands and protect captured output

* test(adb): cover bugreport destinations containing spaces

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:24 +08:00
morluto abc4f47683 build: separate runtime artifacts and supervise command ownership 2026-10-09 20:11:17 +08:00
Matt Van HornandMatt Van Horn db675f1d52 feat(mcp): select views of retained analysis results (#1180)
Add explicit summary, facet, item and paged views of retained analysis Evidence without repeating analysis. Preserve captured observations, graph validation, artifact identity, coverage and complete default results.

Fixes #1050

Verified with focused source, CLI, pinned-SDK schema and MCP tests, serial static checks, and one complete native Windows Notion ASAR workflow. Real Hopper/Ghidra verification was not performed for this provider-independent projection change.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-10-09 12:45:48 +08:00
Ysopwnable 7af7bc88ce feat(evm): inspect offline bytecode interfaces through EVMole (#1051)
* feat(evm): inspect offline bytecode interfaces through evmole

* fix(evm): distinguish unsupported bytecode targets

* style(evm): format verifier string-prefix checks
2026-10-08 15:32:05 +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
2bf3663f65 feat(browser): inspect historical web network captures (#992)
* feat(browser): inspect retained HAR and mitmproxy capture evidence

Add independent offline format adapters, inline CLI/MCP evidence, bounded
owned decoder processes, and real producer verification.

Refs #882

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): preserve capture boundaries during cancellation and decoding

Honor cancellation during owned-command cleanup, retain opaque HAR
extension content, and clean verifier resources on every failure path.

Refs #882

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): exclude sensitive capture fields across representations

Normalize known native transport URLs for both bytes and strings, including backups. Exclude explicitly sensitive text fields with null so redaction markers cannot reintroduce declared literals. Cover both provider identities in catalog conformance.

Refs #882

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): exclude sensitive capture identities and bound diagnostics

* fix(browser): validate excluded HAR subtrees before projection

* fix(browser): distinguish capture input limits from decoder failures

* fix(browser): preserve decoder failure categories

* fix(browser): validate excluded native credential values

* test(browser): report capture verifier assertions directly

* fix(browser): classify native representation failures precisely

* fix(browser): exclude URL userinfo after header whitespace

* fix(browser): preserve capture evidence and failure boundaries

* fix(browser): exclude sensitive literals from capture limitations

* test(browser): check limitation values without JSON syntax

* fix(browser): preserve acquisition integrity and exclude selection diagnostics

* fix(browser): preserve capture acquisition and declaration boundaries

* fix(mcp): project sensitive capture argument validation

* fix: preserve capture bytes and prelaunch cancellation

* fix(browser): exclude sensitive HAR record ancestry

* fix(browser): preserve transport URL and parameter exclusions

* fix(browser): preserve numeric redaction and canonical capture provenance

* fix(browser): cover derived capture values and ownership preparation deadlines

* fix(browser): exclude explicitly sensitive artifact digests

* chore: regenerate generated metadata

* fix(browser): reject lossy HAR member normalization

* test(browser): assert the advertised unsupported-profile outcome

* fix(browser): preserve JSON visitor nesting failure locations

* fix(browser): exclude explicitly sensitive native source ranges

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-08 07:53:41 +08:00
Ysopwnableandmorluto b5afa5f91e feat(browser): attribute native execution and listener sources (#917)
* feat(browser): attribute native execution and listener sources

Integrate finite native precise-coverage windows and direct DOM listener inspection through shared CLI/MCP workflows, exact session script identities, inline source evidence and owned instrumentation cleanup.

Refs #881, #774

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): preserve runtime identity and settle fixture cleanup

Retain complete reported initiator objects, reject changing loader availability, propagate the selected operation through main-frame authorization and complete effect/help inventories. Close only the synthetic owned Chrome via its native endpoint, await process-group settlement and preserve primary verification errors during cleanup.

Refs #881

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): settle invalid events and preserve document evidence

Accept same-document URL changes with proven stable loader identity, retain metadata without inventing ownership, terminate malformed event collection immediately, and sanitize known transport URLs without erasing sourceURL declarations.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): end detached target windows and sanitize coverage identities

Reuse the existing flat-session event matcher, retain prearming termination, and apply the source identity policy to coverage URLs. Add real MCP target-close verification and producer regressions for detachment orderings.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): retain final sample metadata and settle fatal protocol failures

Keep source inventory open through the resetting sample, propagate fatal wire failures without outstanding commands, and check listener collection failures after final document validation.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): require default execution worlds for website attribution

Preserve native context and world metadata without treating same-frame isolated or unknown contexts as website sources. Verify actual Chrome isolated function execution before excluding its coverage, and cover ambiguous world metadata with producer regressions.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(browser): revalidate runtime source joins and selector failures

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-07 21:45:07 +08:00
ysopwnable b808e2d6bb refactor(provider): declare deep capabilities from source (#892) 2026-10-07 15:41:50 +08:00
morlutoandCursor Agent e0fd8207a1 feat(application): wire Android and Apple inventory graph tools (#852)
* feat(application): wire Android and Apple inventory graph tools

Expose project_android_application_graph and project_apple_application_graph
through CLI and MCP so authenticated inventory Evidence can be projected
without a provider launch.

* fix(application): use producer root occurrence IDs in graph examples

Catalog examples constructed root occurrence IDs from artifact_id +
logical_path, but inventory validation authenticates "." with
{ root: root_artifact_id }. Align the examples and regenerate catalogs
after rebasing onto main (application family count 11).

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-07 13:34:48 +08:00
N0zoM1z0 166dcd21d0 feat(javascript): recover readable modules with Wakaru (#848)
* feat(javascript): recover readable modules with Wakaru

Integrate pinned upstream source behind a typed optional recovery port,
preserve source identity and producer provenance, and publish verified
artifacts for existing JavaScript analysis through CLI and MCP.

Add focused real-tool CI with genuine bundler fixtures and bounded
resource, cancellation, cleanup, schema and packaged-artifact checks.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(javascript): align recovery catalog and browser verification

Share canonical Wakaru provider identity, describe CLI mode options, and
format the new workflow test. Disconnect the real page transport after
its observation readiness progress instead of a fixed delay.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* refactor(javascript): consume the investigation evidence writer

Verify that the SDK recovery handler records complete Evidence through the newly shared investigation owner.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

* chore(test): account for isolated recovery fixture compilers

* fix(javascript): validate recovery paths before acquiring the engine

Return field-specific invalid_format diagnostics for relative paths and verify compiled CLI/MCP parity even when the optional engine is unavailable.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-07 12:46:13 +08:00
N0zoM1z0 472b72a530 feat(web): export captured scripts for JavaScript application analysis (#801)
* feat(web): export captured scripts for JavaScript application analysis

Add capture adapters, conservative source path projection, verified exclusive publication and a shared CLI/MCP workflow. Retain source identities, missing content and competing URL versions in a complete manifest for existing static analysis.

Refs: #774
Closes: #799
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* test(web): include script export in independent effect audit

Register the new contract family in the independent inventory audit and verify the filesystem, session, network and idempotence metadata of the named export contract.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* fix(web): preserve capture limitation values in export manifests

Align the export boundary with passive capture’s string contract instead of rejecting an admitted empty limitation. Cover the publisher boundary and regenerate canonical schemas and identities.

Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-07 05:24:32 +08:00
N0zoM1z0 8238232485 feat(ida): add read-only GUI and headless MCP providers (#754) 2026-10-07 01:47:05 +08:00
N0zoM1z0 5a7c769692 feat(firmware): integrate Binwalk and Unblob analysis
* feat(firmware): integrate Binwalk and Unblob analysis

* fix(firmware): verify published files and namespace source references

* test(firmware): isolate extractor dependency failure from process cleanup

* fix(firmware): retain actionable report and cleanup diagnostics

* test: assert retained batch output failure diagnostics
2026-10-06 14:16:04 +00:00
N0zoM1z0 904d03e987 feat(android): integrate static APK analysis with headless JADX (#738)
* feat(android): integrate static APK analysis with headless JADX

* test(android): include APK tools in explicit effects audit
2026-10-06 12:46:48 +00:00
morluto 5295d56b10 refactor(contracts): split tool contracts by family (#634)
Move official, enhanced, and session contract arrays with their
builders into officialToolContracts, enhancedToolContracts, and
sessionToolContracts. toolContracts keeps the ordered assembly and
resolver. Migrate all importers including catalog scripts. No
re-export shims; generated catalog output is unchanged.
2026-10-06 05:20:11 +08:00
morluto 8f229ede70 feat(electron): add autonomous Electron runtime analysis (#464)
* feat: add autonomous Electron runtime analysis

* feat(electron): add lifecycle and boundary telemetry

* feat(electron): capture runtime boundary evidence

* fix(electron): package boundary hook helper

* feat(electron): report active capture coverage

* fix(electron): account for bring-your-own runtime

* feat(electron): expand agent-owned runtime scenarios

* fix(ghidra): keep fixture credentials out of argv

* perf(test): serialize local test and docs workloads

* fix(electron): harden active runtime capture

* fix(inspector): require exact runtime target authorization

* fix(docs): make managed manifest host independent

* fix(ci): make generated catalog portable

* fix: unblock autonomous command and electron flows

* fix(electron): close popup and detached helper gaps
2026-08-05 19:07:46 +08:00
morluto 035e1144b0 feat(server): advertise available tools dynamically 2026-07-24 13:18:58 +00:00
morluto 1a99a60a29 refactor(adapters): split oversized provider workflows 2026-07-18 05:49:14 +00:00