Compare commits

...
Author SHA1 Message Date
N0zoM1z0 c2e2ed9aa2 test(firmware): retain unverified workers before further launches 2026-10-11 02:38:48 +08:00
N0zoM1z0 1ae4bec45b Merge remote-tracking branch 'origin/main' into test/maintenance-boundary-contracts-20261011 2026-10-11 02:38:48 +08:00
N0zoM1z0 058bc0af35 test: verify current maintenance boundary behavior 2026-10-11 02:34:45 +08:00
morluto dce81ca400 perf(javascript): count candidate relevance without a second adjacency
Scan eligible candidate relations directly for query ambiguity instead of allocating and sorting another traversal index. Preserve direction, relation filters and cycle handling.

Semantic graph and builder suites plus public application workflow CLI tests passed. Full query outputs matched on a generated 20000-node graph; the single repeated-query timing run is indicative only.
2026-10-11 02:32:11 +08:00
morluto bb764d26bd perf(artifacts): stop parsing parent paths after a missing branch
Walk delimiter-terminated parent segments lazily instead of splitting full paths before discovering that no deeper observed parent exists. Preserve canonical paths and observed ancestry.

Verified real ZIP inventory with multiple 30000-component siblings and the full entry-order suite. A 96-member deep ZIP benchmark retained an identical full inventory digest and reduced median scan time from 517.5 to 464.5 ms across five measured inventories.
2026-10-11 02:32:04 +08:00
morluto acd8d86898 perf(android): validate prerequisites once per retained JADX session
Resolve current paths and JVM options and rehash source identities for each request. Probe Java modules and engine capabilities only when creating a new session; remove the superseded full configuration resolver.

Focused configuration, session retirement, cancellation, cleanup and Android MCP boundaries passed. The 34-operation retained session now performs one prerequisite probe. Protocol fixtures do not establish real JADX or JDK performance.
2026-10-11 02:31:57 +08:00
morluto e6d0b3993d perf(process): batch liveness rechecks within ownership phases
Recheck unreadable token and identity observations against one fresh live process snapshot per phase. Preserve token mismatches, fail closed on inspection errors, and retain liveness failure diagnostics.

Validated with focused process ownership, native capture, CLI and MCP boundaries. An eight-member injected-unreadable workload using native ps reduced snapshots from nine to two with equivalent failures; real permission-denied provider behavior was not exercised.
2026-10-11 02:31:07 +08:00
morluto 92a901e0db perf(process): share settlement probes across captured groups 2026-10-11 02:21:50 +08:00
morluto cef6d6d3c4 perf(artifacts): reuse trie membership for case-folded siblings 2026-10-11 02:21:40 +08:00
morluto bd972bf80b perf(javascript): reuse capture completeness during load classification 2026-10-11 02:21:35 +08:00
morluto ac9709a80a perf(reconstruction): index semantic evidence contexts per derivation 2026-10-11 02:21:28 +08:00
morluto d1e6fe2eca test(artifacts): close owned Mach-O readers after each case 2026-10-11 02:11:13 +08:00
morluto a147ecd4b4 perf(artifacts): index observed parents for deep archive paths 2026-10-11 02:10:50 +08:00
morluto 22fdcb8ab7 perf(process): share batched token observation across ownership checks 2026-10-11 02:10:44 +08:00
morluto b22d817073 perf(process): batch ownership tokens during rooted cleanup
Use the host bulk token reader for each cleanup validation while preserving identity checks before and after token reads. Fall back for unsupported readers or omitted rows, retain explicit unavailable observations, and preserve batch and individual failures. Source ownership regressions and real owned-process boundary tests pass; a warm Darwin validation probe reduced median time from 90 ms to 52 ms.
2026-10-11 01:59:30 +08:00
morluto 3d876c5c1a perf(javascript): validate semantic factory inputs once
Construct typed semantic records directly from cloned, normalized input and derived commitments instead of reparsing the same fields. Keep full graph integrity validation and verify caller mutation isolation. Four alternating cold runs preserved complete result digests while median projection time fell about 8 percent and 17 percent for the two 20,000-node capacity workloads.
2026-10-11 01:54:46 +08:00
morluto cf346368c4 perf(javascript): reuse graph buckets and query indexes
Append overlapping observations to node buckets instead of recopying groups, and share one node index across semantic seed admission and traversal. Preserve merged provenance and absent-seed behavior.
2026-10-11 01:54:36 +08:00
morluto e52c0a72c5 fix(browser): retain incomplete WebMCP replay coverage
Mark malformed WebMCP event envelopes, tool lists and entries as invalid protocol values while preserving valid siblings and out-of-scope classifications. Verify toolsAdded and toolsRemoved replay uncertainty through CDP discovery and capture comparison.
2026-10-11 01:54:26 +08:00
morluto 999e3e2098 fix(android): cancel admitted snapshot copies with their operation
Forward caller and timeout cancellation through engine and APK snapshots, release stream handles before removing partial output, and retain the existing root cleanup authority. Verify cancellation after destination bytes appear with a sparse filesystem fixture.
2026-10-11 01:54:20 +08:00
dakjdakdandYsopwnable c1217e711b fix(javascript): retain runtime scope in bundled module relationships 2026-10-11 01:36:12 +08:00
morluto 0d89978333 fix(android): release snapshot streams before closing file handles
Retain both non-auto-closing copy streams and destroy them after verification, before awaiting their FileHandle closure. This releases stream-held descriptor references on success and failure instead of deadlocking Android snapshot cleanup.

Validation: all 33 JADX subprocess integration tests passed on macOS with Node 24.18.0; check:fast and formatting passed. No real JADX provider execution or Linux/Windows verification was performed locally.
2026-10-11 01:12:48 +08:00
morluto 11e3fae697 fix(ci): repair boundary regressions and evidence assertions
Detach cancelled CDP sessions within the cleanup budget and retain event-finalization failures across retries. Honor Git filesystem encodings and exclude the promise-API probe from source-read failures.

Align existing integration regressions with retained process resources, filesystem-order-independent truncation, owned skill files, explicit native access facts and streamed JSON errors.

Validation: 132 acceptance tests passed (2 skipped), 83 affected boundary tests passed, Git/JSON/CLI boundary regressions passed, check:ci, docs:check and test discovery passed. Local verification used Node 24.18.0 on macOS; cross-platform CI remains pending.
2026-10-11 01:00:30 +08:00
morluto 603d04ee3a fix(ci): repair format gate and pin maintenance skill destinations
format:check failed on ApktoolProvider; existingMaintenanceScope now
returns skillDestinations (consumed by maintenance planning), so pin
the field in the exact-shape scope assertions.
2026-10-11 00:33:36 +08:00
morluto 472f313232 refactor(native): match UI controls by explicit object identity 2026-10-11 00:28:39 +08:00
morluto 1f7e279aa2 fix(adb): retain rollback ownership and cancelled acquisition facts 2026-10-11 00:28:39 +08:00
morluto db8ccaa251 fix(android): bind JADX snapshots and hashes to admitted sources 2026-10-11 00:28:25 +08:00
morluto 5daff4d67e fix(artifacts): retain Mach-O source identity through inventory 2026-10-11 00:28:25 +08:00
morluto a9fd1aecae fix(application): verify configuration and reference input reads 2026-10-11 00:28:24 +08:00
morluto abb8e81d3a fix(filesystem): bound and verify admitted file and JSON reads 2026-10-11 00:28:24 +08:00
YsopwnableandGitHub 6d8f95e38d fix(clients): preserve portable MCP schemas in native workflows (#1580)
* test(clients): verify native Command Code workflows

* docs: synchronize Italian provider guide links

* fix(contracts): make ADB identifier patterns portable

* fix(contracts): preserve portable ADB patterns after formatting
2026-10-11 00:09:43 +08:00
morluto c1b5ccf0a4 refactor(server): admit complete evidence workflows and share handlers
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:24 +08:00
morluto 5f30ea6ff2 fix(engines): serialize JEB acquisition and respect IDA cancellation
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:23 +08:00
morluto d438675677 fix(process): retain capture resources and bound filesystem snapshots
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:23 +08:00
morluto a84dea5500 fix(apktool): join active work and retain cleanup authority
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:22 +08:00
morluto 2a66ec9094 fix(browser): retain startup owners and coordinate retryable close
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:22 +08:00
morluto d1235fadc9 fix(providers): retain worker cleanup owners through shutdown
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:21 +08:00
morluto a01148553e fix(setup): preserve recovery backups and retain installer cleanup
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:21 +08:00
morluto a6f76f5da9 fix(graphs): separate source identities from display representations
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:20 +08:00
morluto 2ca3ad2386 fix(reference): preserve exact paths and unify symlink lookup
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:20 +08:00
morluto 5d0a883605 fix(native): bound metadata projection and compact Mach-O bind runs
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:19 +08:00
morluto 0f0d6e4d43 fix(managed): budget decoding before representation expansion
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:19 +08:00
morluto 6d4cefc4f7 fix(artifacts): admit bounded reads and preserve source identity
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:18 +08:00
morluto 2a0b58e440 refactor(cleanup): share failure composition and retain native UI owners
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:18 +08:00
morluto 6543405252 fix(adb): escape portable patterns for unicodeSets consumers 2026-10-10 23:40:37 +08:00
morluto cca7bf0022 fix(ci): repair option alias, pattern portability, and Italian doc links 2026-10-10 23:34:57 +08:00
morluto bb742110a4 fix(ghidra): build bridge script paths with the target platform syntax 2026-10-10 23:22:44 +08:00
morluto a97bd5ed29 fix(ci): share provider workflows to restore static gates 2026-10-10 23:15:02 +08:00
Jay-Alexander ElliotGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
bddddccdee feat(native): admit bounded MIPS ELF analysis through Ghidra (#1362)
* feat(native): admit bounded MIPS ELF analysis through Ghidra

Retain MIPS ELF identity and interpretation through Evidence and snapshots.
Keep provider admission bounded to ELF32 ET_EXEC o32 MIPS32r2, without
implicitly widening Hopper, IDA or Windows P0 coverage. Add source-owned
fixtures and an optional real-provider verifier; real Ghidra verification
remains pending in this contribution environment.

Refs #718

* fix(ghidra): bound MIPS floating-point mode admission

Reject explicit EF_MIPS_FP64 and EF_MIPS_NAN2008 declarations until their
semantics have a real-provider verification lane. Add PSP PRX/Allegrex,
o64/EABI and floating-point-mode refusal regressions. Document that the
header gate is not a full .MIPS.abiflags check and advance the profile lane
identity to invalidate older interpretation bindings.

Validation: 24 standalone checks against the transpiled production profile
module passed; the two new flag cases failed before this change. Clang 17
and LLD compiled the source-owned fixture for both endian targets. The
complete Vitest/typecheck suite and real Ghidra verification remain pending.

Refs morluto/rea#718; PSP support remains follow-up morluto/rea#1330.

* fix(native): validate MIPS ABI records before Ghidra admission

Read bounded ELF32 PT_MIPS_ABIFLAGS and SHT_MIPS_ABIFLAGS records through
the already-open target handle. Preserve declared ABI fields, reject
conflicting/duplicate/truncated records, and keep missing records unknown.
Wire inspection into target resolution before provider selection. Require
compatible declarations for the deliberately narrow Ghidra lane and bind
all ABI fields into profile identity (v3) for snapshot invalidation.

Clang 17 produced eight source-owned fixtures spanning both byte orders
and FPXX/FP32/FP64/soft-float modes with identical ELF header flags. The
new reader and policy distinguish them. 24 focused regression test bodies
passed after TypeScript transpilation using node:test in place of Vitest;
strict isolated TypeScript checking of the reader and target/result types
passed. These are limited checks, not full Vitest/project typechecking or
real-Ghidra verification, which remain pending.

Advances morluto/rea#718. PSP/Allegrex remains morluto/rea#1330 follow-up.

* fix(native): repair MIPS integration boundaries and test resolver behavior

Keep ELF targets out of Hopper Mach-O preparation and scope existing PE fixture types correctly. Move ABI tests into the filesystem boundary lane, use shared cleanup, add resolver regressions, apply the pinned formatter, and register the real MIPS verifier through the existing package-command pattern. Validated with repository-pinned Node/npm, check:ci, actual focused Vitest, discovery and docs:check. Real Ghidra conformance remains pending.

* fix(test): honor caller-selected JDK in real MIPS verification

* test(native): strengthen MIPS Ghidra conformance

Cross-check the source-owned fixture with bounded GNU readelf inspection, compare production ELF/ABI interpretation and independent symbol addresses, and verify effective Ghidra language/compiler identity through existing public operations. Add a source-owned fixed-encoding probe for immediate and conditional branch checks plus global/string byte assertions.

Add 16 assertion/producer-boundary regression cases without widening production admission, changing provider contracts, or introducing proprietary dependencies. Local focused suite: 99 passed, one existing root-permission test skipped. Typecheck, lint/module boundaries, formatting and 700-file discovery pass; full hosted checks and real Ghidra verification remain pending for this checkpoint.

* fix(ghidra): preserve native-tool architecture checks after MIPS integration

The conflict-free upstream merge failed TypeScript compilation because includes on the union of MIPS-only and other architecture arrays requires never. Use equality-based membership without casts or changing accepted native hosts. Extend the existing native-decompiler rejection table with a MIPS executable at a Linux x64 tool path; retain upstream FAT and unknown-header behavior. Hosted verification follows this commit; no success is claimed yet.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-10 23:04:27 +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
ded59689ce fix(javascript): accept the Wakaru 1.x release line and verify 1.14.0 (#1540)
* fix(javascript): accept the Wakaru 1.x release line and verify 1.14.0

Exact --version equality rejected every Wakaru build except 1.13.0, and
strict report schemas rejected any added field, so each upstream release
broke recovery until REA re-pinned. Wakaru now documents that --version,
--json and provenance.json change only by addition within a major version.

Admit ^1.13.0 with the verified/compatible split used for Binwalk and
Unblob, report the observed version instead of the pinned constant, and
add a limitation for unverified releases. Parse reports with loose
objects and keep the reported module status as a string; path, identity,
range and file-set checks stay exact.

Move the audited pin, submodule, CI binary and verifier to 1.14.0, and
document where to get the binary from the refusal message.

* fix(javascript): project known Wakaru warning fields

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:15 +08:00
0363e5a8e1 fix(reference): join internal symlink targets with the inventory NFC normalizer (#1535)
* fix(reference): join internal symlink targets with the inventory NFC normalizer

checkSymlinks resolved an internal symlink target with bare
posix.normalize and looked the result up in the inventoried path set.
A target that a filesystem reports in NFD (macOS readlink commonly
does) joined to an NFD spelling while the inventory holds NFC, so
validation reported "Internal symlink target must resolve to an
inventoried entry" for a target the inventory actually contains.

Route the join through normalizeJoinedLogicalPath, the same inventory
identity normalizer #1513 applied to the runtime, HTML/module, and
import joins from #1488. The feature-seed NFKC query fold stays a
query.

Refs #1488

* fix(reference): preserve source spelling during symlink lookup

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:10 +08:00
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
f6009d0077 fix(browser): keep the first DOM attribute when the name is repeated (#1516)
* fix(browser): keep the first DOM attribute when the name is repeated

When an element in a captured DOM tree carries duplicate attribute
declarations (e.g. repeated href, action, or src), domMetadata folded
the attributes into a Map using pairs.set(), overwriting earlier
declarations with the last one.

HTML specifies that the first declaration is kept when an attribute
name is repeated. This aligns domMetadata and attribute_names to retain
the first occurrence case-insensitively, matching HTML and ensuring that
attribute_names and dom_urls reflect the same attributes.

Fixes #1496

* fix(browser): preserve case-sensitive DOM attribute names

* test(browser): align repeated attribute coverage with deduplication

---------

Co-authored-by: taljeri <318237806+taljeri@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:00 +08:00
4d8d76b253 fix(electron): support packaged app.asar pages and rewritten unpacked companions (#1400)
* fix(electron): resolve pages served from inside app.asar

Packaged Electron applications load their renderer pages from file URLs
inside app.asar. The host filesystem cannot stat those paths, so
list_electron_targets excluded every such page as unsupported_url and
inspect_electron_page could not select it.

Resolve these URLs the way Electron's file protocol does: the first .asar
path component that is a regular file is the archive, and the remainder
must name a regular file in its header. Directories, links, and missing
members stay rejected. Parsed headers are cached by archive identity.

* fix(artifacts): extract and explain rewritten ASAR unpacked companions

Packaging tools commonly sign or strip .asar.unpacked native binaries after
writing the archive header, so their declared hashes no longer match.
analyze_javascript_application already accepts integrity_policy, but
extract_artifact did not, and inspect_artifact and extract_artifact still
told callers to "get a fresh copy", which cannot help for a shipped app.

- Accept integrity_policy on extract_artifact (MCP and CLI). The default
  still fails closed; record-and-continue writes the observed bytes and
  returns the extracted files' integrity_contradictions records.
- Name the unpacked entry and the post-packaging cause in integrity
  failures, and point every operation that accepts integrity_policy at
  record-and-continue.
- Report an active unpacked entry whose companion file is absent as
  unavailable with its logical path instead of a format failure.
- Share one integrity_policy schema across the inventory, extraction, and
  JavaScript application inputs.

* fix(electron): bound ASAR headers before allocation

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:54 +08:00
162f9bf7ff fix(ghidra): clear wrong no-return flags before serving a session (#1419)
* fix(ghidra): clear wrong no-return flags before serving a session

Auto-analysis can flag ordinary functions as no-return (stream readers,
__cxa_guard_acquire, ...). Their callers then end at the call and the
decompiler truncates them. Run a postScript before the bridge that clears the
flag on functions containing a real RET and re-disassembles the call sites that
were terminators.

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

* fix(ghidra): refit in place and scope no-return call-site repair

Keep function types by refitting the owning functions with fixupFunctionBody
instead of removing and recreating them. Only redo call sites whose callee was
actually cleared (including thunks to it), skip sites followed by a function
start or x86 padding so real end calls do not run on, and always log the result.

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

* fix(ghidra): constrain no-return repair to admitted return evidence

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:50 +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
YsopwnableandGitHub efd81f9776 test(clients): verify native Grok Build workflows (#1571) 2026-10-10 22:59:43 +08:00
5156ba44c5 feat(native): return a retained summary view of binary layouts on request (#1570)
inspect_binary_layout accepts the same optional detail input as
analyze_javascript_application. The default complete delivery is
unchanged; detail "summary" retains the complete layout Evidence in the
session and returns its inspect_analysis_view summary, whose
parent_evidence_id selects sections, symbols, mitigations or linkage
later. Both tools share one detail schema and output projection.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:57:42 -07:00
c19e15a2b3 feat(javascript): return a retained summary view on request (#1568)
analyze_javascript_application returns the complete application graph
inline, which repeats tens of kilobytes even for a few source lines and
exceeds the default 10 MiB MCP frame for a 300-function source file.

The new optional detail input keeps complete delivery by default. With
detail "summary" the server records the complete analysis Evidence in
the session and returns its inspect_analysis_view summary, whose
parent_evidence_id lets callers page modules, select items, or pass the
retained reference to application workflows. A server without Evidence
retention refuses summary detail with capability_unavailable rather
than returning a summary whose analysis cannot be reached.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:37:37 -07:00
ClaudeandYsopwnable 649661dc8b fix(javascript): stop reading media preload attributes as Electron preloads
HTML audio and video elements have their own `preload` attribute ("none",
"metadata", "auto"). A React renderer compiles `<audio preload="metadata">`
to `jsx("audio", { preload: "metadata" })`, and the `property:preload`
heuristic reported it as an Electron preload script named `metadata`.

Skip `preload` properties in the props object of a call whose first
argument is the static tag `audio` or `video`. The callee is not checked,
because minified element factories have arbitrary names.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPY2GmufMNGQKoEgRUx1pd
2026-10-10 22:12:56 +08:00
YsopwnableandGitHub e4cc0f09de fix(setup): reject invalid OMP profiles before fallback writes (#1562) 2026-10-10 22:11:14 +08:00
a53689c55d fix(mcp): stop advertising complete Evidence in input examples (#1560)
Hosts forward every tool's input schema to the model on each request.
Seventeen tools advertised a canonical example that embedded a complete
producer Evidence record, up to 22 KB each, accounting for 116 KB of the
450 KB of advertised input schemas.

Advertised examples now show an embedded Evidence record as its exact
retained-evidence reference when the canonical input accepts one, and
omit an example that can only carry inline Evidence. Canonical contract
examples, their executable tests, and validation are unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:10:38 -07:00
morluto 2d426c924c fix(native): format runtime convention guard 2026-10-10 21:50:55 +08:00
a929c9f714 fix(mobile): bound framework conventions to path segments (#1506)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:42:03 +08:00
YsopwnableandGitHub 8c47a9ce4b fix(javascript): yield during receiver and reference classification (#1557) 2026-10-10 21:40:16 +08:00
de619bd334 fix(ida): canonicalize the headless workspace root before opening (#1481)
On macOS the default workspace root is os.tmpdir() under /var/folders,
and /var is a symlink to /private/var. idalib-mcp reports the canonical
input path from idb_open/idb_list, while REA compared it against the
uncanonicalized private copy with normalize(), so every headless IDA
analysis failed its identity check (surfacing as unreadable_output) and
the spawned idalib worker was never released.

Resolve the workspace root with realpath() when allocating the private
workspace so the input path REA sends already matches what upstream
reports.

Co-authored-by: Xingchuan Ma <xingchuan.ma@msn.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:39:33 +08:00
24d9337649 fix(native): preserve compact reference provenance (#1438)
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 21:39:28 +08:00
2ec93ba166 docs: celebrate 60,000 GitHub stars 🎉 (#1559)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:31:58 -07:00
afdaf98117 fix(hopper): treat a directory launcher path as missing (#1426)
`HOPPER_LAUNCHER_PATH` availability was decided by an `X_OK` access check
alone, which a searchable directory also passes. Pointing it at the
`Hopper Disassembler.app` bundle instead of its launcher made `rea providers`
report Hopper as available and `rea doctor` report it healthy, while analysis
then failed with an unrelated `version_unresolved` rejection.

Require a regular file in both the provider availability probe and the
doctor executable probe, matching the Ghidra launcher check. A directory now
reports `executable_missing`, and doctor reports `config_drift` with its
existing HOPPER_LAUNCHER_PATH remediation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:31:26 +08:00
944981d8d5 docs: correct stale logging, Ghidra host, and example path statements (#1420)
- CONTRIBUTING: CLI logs go to stderr, not stdout. `createLogger` writes every
  mode to fd 2 so protocol and `--json` stdout stay parseable.
- Get started: Ghidra supports Linux arm64 (`GhidraInstallation` maps
  `linux.arm64`), as installation.md already states.
- Browser guide: drop the caption claiming the hosted request path carries a
  `/rea/` prefix. The guide now targets rea.tools, where the example is served
  at `/examples/notes-web/`, as the evidence table above it shows.
- JavaScript workflows: six CLI commands accept inline JSON or a JSON file,
  not five; `inspect-analysis-view` was added after the sentence was written.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:29:31 +08:00
b32a11e1a7 docs: correct host requirements in the README analysis tables (#1422)
- EVM bytecode and recorded crashes: state the Linux x64 host requirement.
  `EvmoleInterfaceProvider` and `PwntoolsDecoder` refuse every other host
  with `capability_unavailable`, but only the neighbouring offline ELF layout
  row said so.
- Translations: Android analysis has supported Windows x64 since 6.2.0
  (#1276), which updated only the English table; 16 translations still said
  Linux/macOS.

Translated cells reuse each README's own wording: the recorded-crash cell
copies that file's ELF-row pwntools phrase, and the EVM and Android cells
follow the construction the same table already uses for host platforms.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:29:03 +08:00
0e19db9fce fix(javascript): unify package resolution and resolve exact exports subpaths (#1424)
* fix(javascript): resolve exact package export subpaths

Bare module specifiers with subpaths now resolve against the selected
package's exports map instead of staying external. An exact subpath key
selects its target through the existing condition, array, and null
semantics, and the selected target resolves as one exact file with no
extension or index fallback. A declared exports map encapsulates every
other subpath lookup, and packages without an exports map keep legacy
file and directory-index resolution.

Package-private import aliases remain external pending a separate
increment (#1365).

Verification: npm run check:fast; focused and full
src/application/javascript source tests on Windows;
verify:test-discovery; docs:check. Four pre-existing failures in
JavaScriptFileUrlPaths and JavaScriptModuleSpecifierPaths reproduce on
unmodified main on Windows because their fixtures write file names
containing '?'.

* fix(javascript): unify package path resolution

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:26:02 +08:00
YsopwnableandGitHub 66a9ad58fc test(clients): verify native GitHub Copilot CLI integration (#1555) 2026-10-10 21:23:11 +08:00
4b985e5021 fix(artifacts): take nested container families from bytes (#1553)
Inventory gave nested members a ZIP or ASAR family from their path
suffix. Byte classification replaced it only for ZIP magic, so text named
`.apk` or `.asar` stayed a container, and encrypted entries and symlinks
kept the suffix guess. A filesystem `.asar` without an ASAR header failed
the whole inventory as a malformed archive.

Nested ZIP families now follow ZIP magic and ASAR follows its header
pickle, shared with root classification. An unread member named like a
container has an unknown format and a limitation naming the suffix. ASAR
expansion requires the header.

The Android projection adds a limitation when no root AndroidManifest.xml
was observed, and its rejection names the observed root format.

Fixes #1491

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:40 -07:00
Rudy CelekliandYsopwnable c8fd2f152b fix(apple): scope keyed archive traversal to the selection
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 21:17:35 +08:00
morluto 02ef2b1c41 docs(zh): rename title to 逆向一切 2026-10-10 21:10:30 +08:00
morluto 961471205c fix(docs): format Italian README tables 2026-10-10 21:08:41 +08:00
a6d6e595f3 docs: add Italian (it) README translation (#1455)
* docs: add Italian (it) README translation

Adds README_it.md (full Italian translation of the English README) and updates the language nav bar in all existing READMEs to include the new [Italiano] link, appended at the end of the bar (after Bahasa Indonesia) to match the repository's convention for adding new languages.

Rebuilt on top of current main to resolve the merge conflict caused by the recently added Bahasa Indonesia (README_id.md) translation.

Closes #1453

* docs: fix Italian README showcase anchors

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:03:39 +08:00
N0zoM1z0 9ffc6210a4 test(javascript): remove duplicate escaped-receiver cases 2026-10-10 20:53:47 +08:00
GeekwolfandYsopwnable b973b1b1ec test(javascript): cover returned object scaling 2026-10-10 20:53:47 +08:00
GeekwolfandYsopwnable 47947eb01c perf(javascript): index returned object targets 2026-10-10 20:53:47 +08:00
YsopwnableandGitHub 2d99e1e3b2 test(ghidra): preserve Node heap options in adapter verification (#1550) 2026-10-10 20:27:45 +08:00
5d6eeb22fb fix(javascript): yield during the largest AST traversals (#1545)
After #1542 the longest event-loop blocks on large bundles were single AST
traversals inside one analyzer: member-mutation collection with its
fixpoint, static source analysis, and function fingerprints, each about
one second on Obsidian's 3.7 MB app.js.

- traverseJavaScriptAstSteps yields every 1,024 visited nodes with the
  same visit order; traverseJavaScriptAst drains it, so every existing
  caller is unchanged.
- Member mutations, static analysis and fingerprints run as steps. The
  member-mutation fixpoint yields every 64 references, and fingerprints
  yield between callables.
- The now-unused synchronous member-mutation and fingerprint wrappers are
  removed.

Graph IDs and complete result digests match main on three inputs,
including obsidian.asar. Over two runs there, the longest block falls
from about 920 ms to 740 ms, the second from 860 to 595 ms, and blocks
over 250 ms from 27 to 18, with total time within 1.5%.

Refs #1462

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:27:41 +08:00
N0zoM1z0 e964a06b83 fix(website): preserve template-owned HTML formatting 2026-10-10 20:27:01 +08:00
N0zoM1z0 5aa30b8b86 chore(website): simplify maintenance and detect documentation drift 2026-10-10 20:27:01 +08:00
YsopwnableandGitHub 8c7569aca7 test(clients): verify native Claude Code integration (#1549) 2026-10-10 20:16:41 +08:00
YsopwnableandGitHub 539a0f95b5 test(clients): verify native OpenCode integration (#1546) 2026-10-10 19:51:30 +08:00
N0zoM1z0 c73cf0ab76 fix(verification): reuse shared output schemas in Electron checks 2026-10-10 19:29:16 +08:00
PeterandYsopwnable aa7008f8a5 fix: reuse validators for identical output schemas 2026-10-10 19:29:16 +08:00
PeterandYsopwnable 1887e1120e fix: reuse validators for identical output schemas 2026-10-10 19:29:16 +08:00
ca7ef69c0c fix(javascript): yield inside semantic analysis and large projection passes (#1542)
* fix(javascript): yield inside semantic analysis and large projection passes

After #1525 the longest event-loop blocks were single stages on very large
files: semantic analysis of Obsidian's 3.7 MB app.js ran 5.8 s in one piece,
and its object projection 1.8 s.

- analyzeParsedJavaScriptSemanticsSteps yields between the analysis phases
  and between the eight derived collectors; the synchronous function drains
  it, so results are unchanged.
- Per-file analysis yields between open-receiver classification and static
  analysis and drives the semantic steps.
- Semantic node creation, definitions and references, and the object and
  frontier passes yield every 64 items. Node creation keeps source order,
  which the per-file node budget depends on.

On obsidian.asar the longest block falls from 5,355 ms to 907 ms with the
same total time (40.6 s to 39.5 s). Graph IDs and complete result digests
match main on five inputs. Remaining blocks up to about 0.9 s are single
AST traversal passes inside the analyzers.

Refs #1462

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

* refactor(javascript): drop the unused synchronous derived-semantics wrapper

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 04:20:50 -07:00
YsopwnableandGitHub b9c439831d test(clients): verify native Gemini CLI integration (#1541) 2026-10-10 19:17:55 +08:00
YsopwnableandGitHub bace2c5a4f fix(javascript): avoid argument limits when expanding escaped receivers 2026-10-10 19:11:00 +08:00
N0zoM1z0 3cd80cbb88 test(process): prepare SDK validation before cancellation timing 2026-10-10 18:54:57 +08:00
N0zoM1z0 6cd5ea0fb2 fix(process): coalesce delayed capture progress
Retain one pending intermediate observation and drop stale live status before terminal cleanup. Preserve monotonic counts and final delivery while an observer is slow or rejects an update.

Verify the send rate at its controlled-clock owner and lifecycle notification density at the CLI/MCP boundary, where receive timestamps include buffering and scheduling.
2026-10-10 18:54:57 +08:00
Cursor AgentandYsopwnable 706bba6e13 feat(process): report live capture progress through CLI and MCP
Long captures emitted only a final result, so a quiet child looked idle.
Pass the shared rate-limited progress reporter through the capture lifecycle
and report the observed phase, elapsed time, and collected-unit counts.
CLI writes those lines to stderr; MCP forwards them only when the client
supplied a progress token. Final Evidence on stdout keeps its shape.
2026-10-10 18:54:57 +08:00
YsopwnableandGitHub 9964af6b79 fix(ci): synchronize browser fixture events before inspection (#1534) 2026-10-10 18:44:49 +08:00
YsopwnableandGitHub 3059d8a40f test(clients): verify native DeepSeek Harness integration (#1524)
* test(clients): verify native DeepSeek Harness integration

* fix(ci): avoid load-sensitive escape regression timing
2026-10-10 18:29:00 +08:00
86b223b33e fix(setup): follow and validate Hermes sticky profiles (#1528)
* fix: follow Hermes sticky profile for setup paths

* test: cover Hermes sticky profile paths

* fix: honor Hermes profiles with home overrides

* style: format Hermes profile lookup

* style: format Hermes profile tests

* fix(ci): avoid load-sensitive escape regression timing

* fix(setup): validate Hermes sticky profile identity

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-10 18:19:51 +08:00
92741187ec docs: list all supported clients in the REA skill (#1523)
docs: include all supported clients in the REA skill

Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 18:18:26 +08:00
5fdb0636b4 fix(javascript): yield during per-file projection and graph construction (#1525)
analyze_javascript_application ran several long phases with no event-loop
turn, so MCP ping and cancellation waited: each file's parse, analysis and
semantic projection; building every application node and relationship
before the application graph's first sealing step; and whole-graph schema
parses inside both immutable graph factories.

- Each file runs as steps (parse, static analysis, semantic analysis, then
  each projection pass), driven by the existing time-sliced checkpoint.
- Application graph input construction yields between phases, per module
  link and per file of findings.
- The pipeline transfers its privately built graph inputs to new sealing
  steps that validate the graph's own fields synchronously and elements,
  content checks and the digest in steps. The public copying factories
  keep their synchronous capture.

Results are unchanged: graph IDs and the complete result digest match main
on five inputs including Obsidian's 23 MB obsidian.asar. On the issue's
1,200-function fixture the longest event-loop block falls from about
290 ms to 90 ms, and ping after abort from up to 286 ms to at most 56 ms.
On obsidian.asar it falls from 10.9 s to 5.4 s; the rest is one analyzer
stage of a single very large file.

Refs #1462

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 03:14:37 -07:00
N0zoM1z0 72b3209f3a docs(website): explain autonomy and oracle lessons in Touhou reconstruction 2026-10-10 18:09:13 +08:00
YsopwnableandGitHub f9ce32b474 test(javascript): verify escaped receivers through CLI and MCP 2026-10-10 17:50:36 +08:00
46c9cba03a fix(javascript): expand an escaped receiver's methods once (#1495) (#1517)
Since #1471, escaping an object also escapes every method's results. Each
call through the object escapes it as the receiver, and each escape
re-expanded all of its methods. N methods returning one shared object,
each called once, did N times N work: 2,000 calls took 3.0 s of semantic
analysis and 4,000 took 12 s.

Expansion below references depends only on syntax, so escapes now reuse
it per expression and path. Identifiers that resolve to the same binding
and path collapse to one, because the escape walk treats them alike.
Every escape site is still recorded. The semantic IR is byte-identical
on 50 sources, and the issue's case takes 253 ms at 2,000 and 638 ms at
4,000.

Closes #1495

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:16:30 -07:00
b4db35f092 fix: bind identity and coverage to the producing rule (#1513)
* fix: bind identity and coverage to the producing rule

Logical paths, container families, examined bytes, path-segment conventions, destination collisions, file-id leases, Mach-O CPU selection, and firmware cleanup now follow the observation that owns each rule.

* fix: fail unmatched Mach-O slices and keep firmware roots independent

A fat target whose architecture lipo did not list now stops before slice tools run. Chained fixups still count unread LC_DYLD_INFO rebase bytes, and a firmware cleanup failure no longer blocks the next workspace.

* test: cover path identity and runtime families at the projection boundary

NFC joins and segment conventions are now asserted by the path resolver, the Apple projection, and a real APK inventory instead of helper unit tests.

* test: expect unread dyld rebase bytes in the Apple dispatch fixture

The legacy LC_DYLD_INFO fixture keeps a rebase range this reader does not decode, so the public CLI and MCP check now requires that partial coverage beside the bind opcodes.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 17:14:47 +08:00
7a56fe6260 fix(setup): honor active client configuration and skill roots (#1504)
* refactor(setup): resolve skill destinations per client

* fix(setup): honor active client configuration and skill roots

* fix(setup): validate effective client scopes and Gemini trust

* fix(setup): treat empty OpenCode overrides as unset

An empty OPENCODE_CONFIG_DIR now stays on the XDG directory, and doctor
and setup inspect global OpenCode files when a custom directory is absent.
Uninstall reports one status per client so a missing earlier layer does
not hide a removed registration.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 17:03:43 +08:00
YsopwnableandGitHub b25922e4e8 test(clients): verify native Qwen Pi and Hermes workflows (#1511) 2026-10-10 16:59:32 +08:00
b6ad1f2c3d feat(mcp): compact input schema profile for size-capped providers (kimi-cli/Moonshot) (#1514)
* feat(mcp): add compact input schema profile for size-capped providers

Moonshot's function-calling API rejects a request while any single tool
parameters schema exceeds its literal serialized size cap, so clients
such as kimi-cli fail every request while the default catalog is
attached (#1484).

Add an opt-in REA_MCP_INPUT_SCHEMA_PROFILE=compact server presentation.
Each advertised input schema is rendered within a 13,312-byte budget,
measured to sit below the observed provider cap: annotation prose
(nested descriptions, examples, defaults, titles) is dropped, repeated
annotation-free subschemas are shared through schema-local $defs/$ref
references the provider validates without expansion, and the three
structurally oversized schemas are advertised in a documented reduced
form. The canonical catalog, tool set, output schemas, and server-side
canonical validation are unchanged; the default full profile is
byte-identical to today's advertisement.

Boundary tests pin every compact schema to the budget, keep them valid
JSON Schema that still accepts every canonical example, hold reduced
presentations at three or fewer, and verify canonical rejection still
guards a permissive advertisement. Verified against the real Moonshot
API through kimi-cli: prompts succeed with the compact catalog attached
where the default catalog fails every request with 400.

* fix(mcp): preserve compact schemas through Kimi conversion

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:58:43 +08:00
N0zoM1z0 2b6f14f528 fix(process)!: version literal scenario replacement semantics
Keep caller-selected replacement text literal with a callback, preserving
empty-search positions instead of changing their split/join behavior.
Commit the replacement interpretation for captures using custom patterns so
legacy records cannot report this producer correction as a target change.

BREAKING CHANGE: Captures with custom normalization patterns use
literal-replacements-v1 and cannot be compared with legacy unversioned
pattern captures. Capture both sides with the same replacement semantics;
legacy captures remain readable and captures without patterns are unaffected.
2026-10-10 16:57:06 +08:00
openhandsandYsopwnable f51503ef1c fix(process): normalize scenario replacements literally
capture_process_scenario declares normalization patterns as literal text, but\nreplaceAll expands \$&\, \$\`, and \$1\ in the replacement as a replacement\npattern. A caller normalizing text that contains a dollar sign silently gets\nduplicated, spliced, or dropped content in the recorded Evidence instead of\nthe requested literal replacement.\n\nUse split/join, which is literal on both sides and is already the idiom used\nfor exact-literal scenario rules in browserScenarioNormalization.ts.
2026-10-10 16:57:06 +08:00
2bf812772d fix(apple): bound binary plist expansion before decoding keyed archives (#1515)
inspect_keyed_archive passed caller-selected binary plists straight to
plist.parseBinary, which recurses on every object reference and copies
shared containers. A 484-byte archive of forty nested [next, next] arrays
grew the process past 4 GB until it died with no result, which would also
end an MCP server. A 125-byte self-referencing array overflowed the stack
and was reported as an artifact too large to process.

The iterative reference walk that already guards decode_interface_builder
now runs first, with an 8x keyed-archive decode budget. Over-budget depth
or expansion is a limit; a reference cycle is a malformed archive. Its
"decoder" bounds admit the same layouts plist.parseBinary reads, so
accepted archives stay accepted. Interface Builder behavior is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:44:46 -07:00
a936303723 fix(json): name a leading byte-order mark in rejected JSON input (#1510)
Strict JSON file inputs reject a leading UTF-8 byte-order mark, but the
diagnostic was the parser's own message, which quotes the invisible U+FEFF
as the unexpected token: Unexpected token '', "{"invento"... is not
valid JSON. Editors such as Windows PowerShell 5.1 write that mark by
default, and nothing in the message showed it.

CLI JSON files (whole and streamed), Evidence and snapshot JSON files, and
process scenario files now report that the input begins with a UTF-8
byte-order mark and how to save it. Acceptance is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:37:41 -07:00
93ca276921 fix(browser): accept HAR files that begin with a byte-order mark (#1509)
HAR 1.2 lets writers emit a UTF-8 byte-order mark and requires readers to
ignore it. The decoder passed ignoreBOM: true to TextDecoder, which keeps
the mark in the decoded text, so a BOM-prefixed export failed as "HAR is
malformed JSON." Decoding now uses the default, which skips one leading
mark. The artifact digest still covers the selected file bytes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:31:31 -07:00
911323c5dd fix(native): page every retained function dossier collection (#1507)
inspect_analysis_view is the recovery path when an analyze_function
dossier exceeds the MCP response budget, but its native facets covered
only procedure, pseudocode, assembly, callers/callees, references, and
value flow. Basic blocks, comments, unresolved calls, referenced strings
and names, and the native API record could not be read from retained
Evidence at all; basic blocks grow with the function just like assembly.

These are now facets: collections page by rows, and native_api is a
singleton. A dossier without an unresolved_calls record reports "not
recorded" rather than the value-flow failure reason.

Refs #1247 and #1065.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:31:15 -07:00
f63f12d8ff docs: align the Indonesian README with the other translations (#1512)
Keep the Bahasa Indonesia onboarding text from #1508, and fix the formatting
that left it outside the shared README layout: drop the leading space, point
in-page links at the translated headings, align the analysis table, and link
Bahasa Indonesia from every language selector.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Dev Cee <24010110166@universitasbumigora.ac.id>
2026-10-10 16:26:52 +08:00
983b070d4d fix(artifacts): record each case collision once at its diverging segment (#1505)
Inventory paired every path under one case spelling with every path under
each other spelling and listed all of them on each occurrence. An archive
with Foo/ and foo/ subtrees of N files each produced N-entry lists on 2N
occurrences: 4,000 such ZIP members yielded a 120 MB inspect_artifact
result and close to 1 GB of memory. The trie walks also recursed once per
path component, so a ZIP name with tens of thousands of components threw
RangeError.

A collision is now recorded at the segment where spellings diverge and
shared down that subtree by an iterative walk. Each occurrence names the
colliding prefix and the first other spelling, plus a count of further
spellings, each of which is its own occurrence.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:16:16 -07:00
9e22da845b feat(setup): add native Pi client support (#1376)
* feat(setup): add native Pi client support

* fix(setup): isolate invalid Pi agent directory overrides

Keep malformed Pi path evidence on its client entry so unrelated selected clients can complete setup and doctor. Preserve explicit Pi rejection and block filesystem operations rather than falling back to another directory.

* fix(setup): parse Pi configuration as strict JSON

Pi's installed MCP loader reads mcp.json with a bare JSON.parse and no
BOM tolerance, so comments, trailing commas, a BOM, or an empty existing
file yield loader errors and no servers. Parsing the Pi dialect with
objectSchema.parse(JSON.parse(text)) before the shared empty/JSONC
shortcut rejects those files at every mutation boundary instead of
reporting configured registrations Pi cannot load. A missing file still
initializes a fresh strict-JSON document, other dialects keep their
JSONC/BOM/empty tolerance, and malformed files are never rewritten.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:10:39 +08:00
f970b886aa feat: add Hermes as a supported MCP client (#1403)
* feat: add Hermes as a supported MCP client

Hermes Agent reads stdio MCP servers from `mcp_servers.<name>` in
`config.yaml`. REA had no Hermes client, so setup could not register it and
Hermes users had to wire the server up by hand.

- SupportedClients: add the `hermes` format and client definition, resolving
  the config path from HERMES_HOME, else the platform default that Hermes's own
  resolver uses (LOCALAPPDATA/hermes on Windows, ~/.hermes elsewhere), including
  HERMES_DATA_DIR_SUFFIX.
- ClientConfigurationDocument: parse and serialize Hermes YAML, upserting the
  rea entry into the parsed document so user comments and unrelated settings are
  preserved; emit `enabled: true` since Hermes connects entries unless disabled.
- ClientRegistrationStatus: forward the Hermes location variables so status
  checks resolve the same path as setup.
- Tests: cover path resolution on both platforms and the register/read/uninstall
  round trip, and clear the Hermes location variables between tests.

- delilah 🌸

* docs: document the Hermes client and its config path

- delilah 🌸

* refactor(setup): resolve skill destinations per client

* fix(setup): install Hermes skills in the active profile

* fix(setup): identify each client skill action uniquely

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:03:25 +08:00
a0e5e9db2b perf(artifacts)!: name each edge's child through its occurrence (#1493)
Every inventory edge is created from one occurrence and copied that
occurrence's artifact_id and logical_path as child_artifact_id and
logical_path. Edges now keep the occurrence_id reference alone. Edge IDs
still hash the same child and path, read from the occurrence, so they are
unchanged; validation and artifact comparison read the occurrence too.

inspect_artifact output: Transmission.app 1.10 MB to 0.97 MB, Visual
Studio Code.app 15.37 MB to 13.48 MB.

BREAKING CHANGE: Artifact inventory edges no longer include
child_artifact_id or logical_path; read them from the occurrence named by
occurrence_id. The graph commitment changes, so inventory Evidence
recorded by earlier versions no longer validates.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:58:05 -07:00
1f692c83e2 perf(artifacts): stop repeating every artifact path as Evidence locations (#1492)
inventory_artifact, inspect_artifact, and extract_artifact copied each
occurrence or extracted file path into Evidence locations, although the
result already names every one. inspect_artifact did so twice, in its own
Evidence and in the nested inventory Evidence. Like other whole-target
Evidence, these now report no locations.

Visual Studio Code.app: inspect_artifact 15.37 MB to 13.07 MB,
extract_artifact 1.40 MB to 1.06 MB.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:47:51 -07:00
YsopwnableandGitHub 782e0147cd fix(javascript): retain returned-reference mutation uncertainty (#1471) 2026-10-10 15:46:24 +08:00
9defed9725 perf(mcp): stop advertising placeholder input descriptions (#1479)
Input schema presentation gave every undescribed property a generic
"Value for <name>." sentence. That only restates the property name, yet
it covered 1,958 properties: 70 KB of the 522 KB of advertised input
schemas that clients load into model context. Authored descriptions,
referenced descriptions, and the name-pattern sentences that add meaning
(maximums, digests, paths, Evidence IDs) remain; other properties now
advertise no description.

The schema validity test now rejects placeholder descriptions instead of
requiring a description on every property.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:32:29 -07:00
5f6bb7a5ba perf(apple): state each NIB object's class, label, and ID once (#1477)
The NIBArchive projection synthesizes customClass, label, and objectID so
its records share the ibtool dictionary parser. The parser then returned
those values as class_name, name, and the object ID, and the graph node
kept the synthesized copies in attributes as well. Attributes now omit a
key whose value its canonical field already carries; differing authored
values stay. Transmission.app decode_interface_builder output shrinks
from 6.45 MB to 6.14 MB.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:31:00 -07:00
morluto 2596f8da14 test(android): retry verified cleanup during fixture teardown 2026-10-10 15:29:42 +08:00
morluto b12d0c6361 test(artifacts): respect destination filesystem case sensitivity 2026-10-10 15:29:42 +08:00
N0zoM1z0 cbcba2902d docs(website): align Blog community links with the site 2026-10-10 15:28:13 +08:00
N0zoM1z0 07d416505c docs(website): finalize the Touhou essay for publication 2026-10-10 15:28:13 +08:00
N0zoM1z0 3ea0233342 docs(website): simplify the Blog introduction 2026-10-10 15:28:13 +08:00
N0zoM1z0 cf6957e796 feat(website): link the Blog from the homepage introduction 2026-10-10 15:28:13 +08:00
N0zoM1z0 ed200a2302 docs(website): emphasize the reconstruction essay takeaways 2026-10-10 15:28:13 +08:00
N0zoM1z0 7df2050606 docs(website): write the Touhou reconstruction essay 2026-10-10 15:28:13 +08:00
N0zoM1z0 130ffdf6bc docs(website): outline the Touhou reconstruction workflow 2026-10-10 15:28:13 +08:00
N0zoM1z0 b09d02d93c feat(website): add a blog for methods and project notes 2026-10-10 15:28:13 +08:00
1f0775684b fix(artifacts): keep case-distinct archive names in inventory (#1480)
ZIP member names are case-sensitive. Inventory was folding them with a
filesystem case rule, so shrunk APKs never became evidence for the Android
application graph. Logical registration now keeps both spellings and records
an English Unicode case-folding limitation. Extraction fails only when the
destination directory already holds the other spelling.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 15:21:16 +08:00
7296f2b5bf perf(javascript)!: stop repeating the semantic identifier strategy per fact (#1474)
Every semantic graph node and relation carried an identifier_strategy
object whose schema admits exactly one value per record type. The
constant made up about 9% of analyze_javascript_application output
(Obsidian app.asar: 12.04 MB to 10.96 MB), and semantic traces repeated
it on every returned fact.

The node_id and relation_id schema descriptions now state how each
identifier is derived.

BREAKING CHANGE: Semantic graph nodes and relations no longer include
identifier_strategy, and relation IDs no longer hash that constant.
Evidence recorded by earlier versions does not validate against the new
semantic graph schema.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:13:34 -07:00
3c7b176a3d perf(artifacts): deliver the inspected artifact graph once (#1473)
inspect_artifact nested the complete inventory Evidence and then restated
every artifact node and occurrence as an observation and every edge as a
derived relationship. No caller reads those copies; comparison and tests
use the nested inventory Evidence. On Transmission.app the result shrinks
from 2.46 MB to 1.10 MB.

Observations keep the root manifest and integrity findings.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:12:17 -07:00
aa23ec883f feat(clients): register Qwen Code during setup (#1415)
* feat(clients): register Qwen Code during setup

* fix(clients): honor Qwen home and shared skill discovery

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 15:12:09 +08:00
keemsisiandGitHub 934ffd28d1 perf(javascript): derive the application graph ID once
createJavaScriptApplicationGraph hashed the whole graph to derive its
graph_id, then parsed it with the public schema, whose invariant check
hashed the same content again to verify that ID. Validate the content
with every other invariant first, then derive graph_id once from the
validated copy. The public schema still verifies graph_id for stored
and untrusted graphs, and created graphs are unchanged.
2026-10-10 15:09:18 +08:00
79f6756239 docs(website): link the Discord community and REA on X (#1469)
Add an X link beside the GitHub and Discord header icons on every content
page, name the footer links "Join the community" and "Follow us on X", and
close the homepage with a "Join the community" section.

On narrow screens, pad the footer so the floating Top link no longer
covers its last row of links.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:00:09 +08:00
YsopwnableandGitHub 78e1308f49 docs(process): clarify normalized terminal line representation 2026-10-10 14:58:15 +08:00
YsopwnableandGitHub 4e3d335439 test(android): retain incomplete cleanup failure reasons (#1443)
Include the full stop disposition in the fixture assertion message, so incomplete owned teardown retains its typed reason in Vitest failure reporters. Preserve the existing cleanup requirement without retries or relaxed ownership checks.

Seven process-boundary tests, full serial typecheck/lint/duplication/format checks, and 19 final-head CI checks pass after integrating the combined-main fixture fix. A controlled failure-rendering probe verifies that the explicit message preserves the reason. The original CI cleanup failure remains unreproduced; this is diagnostic work with a synthetic JADX producer, not a root-cause or real-engine fix.

Refs #1441, #1446, #1448, #1065.
2026-10-10 14:37:49 +08:00
YsopwnableandGitHub ea92328775 fix(mcp): validate doctor probe against its discovered output contract (#1461)
Validate the target-free probe against the named definition discovered from the complete production catalog. Preserve initialized server and inventory observations when the SDK rejects the probe, and retain the schema failure reason, absolute deadline and owned-child cleanup.

The negative stdio replay regression fails on original main and passes the fix; actual production-boundary fault injection confirms rejection. Nine doctor/help tests, serial full static checks and real small-target CLI/MCP parity pass. Successful doctor reports remain byte-identical. No performance or model-token reduction is claimed.

Closes #1454. Refs #1065, #723, #1433.
2026-10-10 14:33:57 +08:00
morlutoandGitHub 28d3cb545c Merge pull request #1463 from morluto/codex/fix-skill-source-discovery
fix(skills): expose authored skill to repository discovery
2026-10-10 14:28:42 +08:00
b118f04492 perf(apple): stop repeating the archive path in Interface Builder evidence (#1460)
Every Interface Builder node and edge evidence record prefixed its
description with the archive's relative path, which artifact_path in the
same record already states. Bundles carry thousands of objects across
localized nibs, so the repeated path made up 6-10% of
decode_interface_builder output (XLD: 7.38 MB to 6.62 MB).

Descriptions now name only the decoded item, such as "object 81" or
"outlet o_quality".

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:21:24 -07:00
ef96657d6b perf(javascript): hash each semantic evidence context once (#1457)
The semantic graph's evidence-context registry canonicalized the full
provenance context three times for every node, relation, unknown and
fingerprint: once to hash its ID and twice more to compare against the
stored row. A file has only a few distinct contexts, so nearly all of
that work repeated a known answer.

Interning now keys contexts by their canonical text. Each fact
canonicalizes once, and only a new context is hashed and checked for a
digest collision. IDs and output are unchanged; Obsidian's 334 MB
Evidence is byte-identical and analysis drops from about 47.0 s to
44.4 s.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:21:07 -07:00
morluto 696fb834b8 fix(skills): expose authored skill to repository discovery 2026-10-10 14:20:22 +08:00
2781cad201 perf(process): stop padding rendered terminal lines to full width (#1450)
Rendered frames padded every visible row with trailing spaces to the
terminal width. Blank rows cost a full row each and every frame repeats
them, so the padding made up 14-39% of capture Evidence (2 KB of sparse
output produced 228 KB). The padding carried no information: columns is
recorded and serialized_state keeps the exact terminal state.

Lines are now trimmed after normalization, so line.padEnd(columns)
restores the previous value. The comparison contract commits
rendered_line_format so older padded captures do not compare as the
same contract.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:18:13 -07:00
YsopwnableandGitHub c89c8f5318 docs(mcp): record real Windows first-query recovery 2026-10-10 14:05:56 +08:00
1ec490f361 fix(javascript): stop replaying earlier writes for each object property write
Repeated property writes to one object made member-mutation collection
cubic. Each write evaluated its target binding to rule out a primitive,
and every evaluation folded all earlier mutation paths, copying every
slot once per path. 2,000 writes to one object took 27 s and 4,000 took
203 s.

- A recorded write always leaves a non-primitive binding value, so only
  the first write to a binding needs the primitive check.
- Apply mutation paths per slot in one pass with the same ordering
  semantics instead of one full slot copy per path.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 14:04:31 +08:00
YsopwnableandGitHub 66863b609f test(javascript): reuse comparison node fixtures
Use the established typed graph fixture constructor while retaining right-hand comparison provenance assertions. Restore the unchanged duplicate-code gate on combined main.

Closes #1446. Refs #1434, #1443, #1065.
2026-10-10 14:02:02 +08:00
morlutoandGitHub 817efaca9a Merge pull request #1391 from marnixpluim/fix/electron-import-aliases
fix(javascript): recognize Electron APIs through renamed bindings
2026-10-10 13:57:24 +08:00
morluto 0d2082d36b fix(javascript): recognize unchanged var and let Electron aliases 2026-10-10 13:56:40 +08:00
morlutoandGitHub f1231d4a2c Merge pull request #1382 from BaaRai/fix/cross-branch-multiblock-callee
fix(ghidra): keep the cross-format branch callee multi-block
2026-10-10 13:50:51 +08:00
morlutoandGitHub a957f397ad Merge pull request #1303 from kvalls/codex/windows-ghidra-native-dlls
feat(ghidra): support native PE DLLs on Windows
2026-10-10 13:50:11 +08:00
YsopwnableandGitHub e09cfe9b59 fix(javascript): invalidate references stored through property targets (#1445)
* fix(javascript): invalidate references stored through property targets

* refactor(javascript): share rest keys and return-shape fixtures
2026-10-10 13:47:15 +08:00
morluto ea1dbda1c7 test(ghidra): share result projection client setup 2026-10-10 13:47:06 +08:00
morluto 7633dd8d5d fix(ghidra): publish Windows verification success after cleanup 2026-10-10 13:43:01 +08:00
morluto 941dc425ca chore: merge main into Windows DLL support branch 2026-10-10 13:42:54 +08:00
33b9b31a6f perf(javascript): index change-graph nodes once per comparison
Resolve each compared graph node through a per-side index while preserving right-hand evidence selection and complete comparison results.

Refs #1065.

Co-authored-by: keemsisi <7439375+keemsisi@users.noreply.github.com>
2026-10-10 13:21:13 +08:00
Kaoru0822andGitHub eeb83f6581 perf(cli): defer Playwright and isomorphic-git until a command needs them
Load browser composition after CLI scenario validation and load Git support only for local reference trees with Git metadata. Preserve default outputs and actual command behavior.

Refs #1065.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-10 13:16:44 +08:00
YsopwnableandGitHub bb6fa1c6f5 docs(process): verify independent full-report hashing budgets (#1440) 2026-10-10 13:13:05 +08:00
YsopwnableandGitHub ce16f7bc95 test(native): verify macOS provenance through real CLI and MCP
Verify five native operations through the public CLI and real SDK stdio MCP using a source-built macOS fixture. Retain normalized provenance, response parity and unchanged input bytes.

Refs #1430, #1065, #723.
2026-10-10 13:05:12 +08:00
YsopwnableandGitHub 0a14ca41b4 fix(javascript): preserve effects through yielded array references (#1437) 2026-10-10 13:00:11 +08:00
YsopwnableandGitHub dc5af6d68f perf(mcp): reuse output validators across catalog refreshes (#1433)
Advertise content- and dialect-bound identities for self-contained output schemas so the SDK can reuse unchanged Ajv validators after complete tools/list refreshes. Preserve explicit IDs and relative reference bases.

Verify changed schemas, availability transitions, reconnects, numeric and selector constraints, explicit IDs, relative references, and advertised dialects through the pinned SDK boundaries.

Refs #1065, #723
2026-10-10 12:49:09 +08:00
0b9815b6e7 docs(skill): save CLI application Evidence and read a summary view (#1429)
The skill's CLI fallback printed the complete application Evidence to
stdout. A real ASAR produces hundreds of megabytes (334 MB for Obsidian),
which an agent then reads into its context. Save the Evidence to a file
and project a summary or module page with inspect-analysis-view instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:38:52 -07:00
6375ccaf04 perf(native): record macOS command provenance once in its Evidence (#1430)
inspect_macho, inspect_signature, inspect_plist, list_architectures and
demangle_swift already return their command provenance inside the
normalized result. The provider also copied the same array into
raw_result, so every response carried it twice. raw_result now stays
null, as docs/mcp-contracts.md describes for results without a distinct
provider representation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:35:50 -07:00
c29931ce81 fix(javascript): scan direct returns without recursive stack growth
Use the shared AST child enumeration with an explicit stack, preserving return order and nested callable boundaries.

Refs #1065.

Co-authored-by: rudycelekli <47457359+rudycelekli@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 12:25:00 +08:00
YsopwnableandGitHub f4a0c1ce95 fix(javascript)!: avoid event payload copies in graph metadata (#1427)
Share the canonical string identity rule with endpoint projection, scope event keys to each emitter, and keep complete event/listener names in properties. Verify real CLI and stdio MCP with large names, registration/removal, distinct emitters, exact name seeds, reserved-prefix values, and unresolved dynamic names.

BREAKING CHANGE: New analyses use digest-based IDs for long or reserved-prefix event names and shorter event/listener display labels. Select IDs from the parent graph and read exact names from event_name properties. Stored graphs and their original IDs remain accepted for semantic tracing.
2026-10-10 12:20:05 +08:00
a9ee2360fd feat(native): inspect oversized retained function dossiers via bounded views
Add caller-selected native dossier facets with preserved Evidence identity, provenance, unknowns and transport recovery.

Refs #1247 and #1065.

Co-authored-by: jhuang-tw <77732008+jhuang-tw@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 12:18:50 +08:00
YsopwnableandGitHub 4d95f2b2e7 fix(validation): retain unmatched union correction details
Preserve actionable field paths and schema-declared variants for unknown or missing discriminators.

Closes #1421. Refs #1065.
2026-10-10 12:15:11 +08:00
28595276fa fix(javascript): bound member-mutation paths through reassignment loops
Fixes #1401. Refs #1065. Preserve exact member facts and equal-depth write effects while bounding the observed reassignment-loop expansion.

Validated with the JavaScript semantic/application suite, focused alias regressions, full static checks, real compiled CLI and SDK MCP Notion workflows, and all 20 checks on the final PR head.

Co-Authored-By: Marnix Pluim <286664873+marnixpluim@users.noreply.github.com>
Co-Authored-By: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-10 12:03:13 +08:00
YsopwnableandGitHub 98022a8352 fix(javascript)!: avoid endpoint payload copies in graph metadata (#1423)
Keep exact endpoint observations and request properties while using compact display labels and collision-safe canonical value digests for long artifact-local endpoint keys. Verify real CLI/stdio MCP tracing and version comparison without truncating evidence.

BREAKING CHANGE: New analyses use compact endpoint labels and digest-based IDs for long or reserved-prefix endpoint keys. Select IDs from the parent graph and read full values from endpoint properties. Previously stored graphs retain their original identities and remain valid workflow inputs.
2026-10-10 12:02:24 +08:00
YsopwnableandGitHub 81cdafc132 docs: celebrate 50,000 GitHub stars 🎉 2026-10-10 03:45:42 +00:00
YsopwnableandGitHub 4d8ef3f350 perf(javascript): aggregate semantic family coverage once (#1410)
Reduce repeated semantic relation and unknown family scans while preserving exact complete Evidence and coverage.
2026-10-10 11:30:42 +08:00
ca3131b36c perf(cli): write compact JSON when output is not a terminal (#1413)
`--json` / `--format json` always indented its streamed result. Agents and
scripts read REA through pipes and redirects, where indentation carries no
information: on real application results it added 16-45% model tokens
(o200k proxy) and 25-73% bytes. The skill's CLI fallback uses `--json`.

Indent only when stdout is a TTY, as `gh --json` does; piped or redirected
JSON is compact. The JSON value, `jsonl`, `--filter-output`,
`--full-output` and the token-window paths are unchanged. `jq .` restores
indentation for files.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:29:48 -07:00
YsopwnableandGitHub de8fc67195 fix(javascript): retain shorter literal metadata encodings (#1408)
Choose the shorter complete JSON or digest key and string display label.
Short values keep their existing identities and labels, while large values
retain the payload-copy reduction without an arbitrary truncation limit.
2026-10-10 11:23:47 +08:00
YsopwnableandGitHub 8550913cda fix(javascript)!: stop copying literals into semantic metadata (#1407)
Commit literal values with canonical JSON SHA-256 in semantic role keys
and use a type label for strings. Preserve complete values, provenance and
literal queries while avoiding two payload copies in each string node.

Verify real compiled CLI/default stdio MCP, typed union seeds, empty
strings and trace continuation with a large source-owned fixture.

Refs #723

BREAKING CHANGE: Newly produced semantic literal node IDs use
value-sha256 role keys, and string labels read "string literal". Read exact
values from properties.value and obtain node IDs from the selected parent
graph. Previously stored Evidence and its original IDs remain valid.
2026-10-09 20:00:53 -07:00
1f0f728c63 perf(hopper): stop repeating Hopper replies as raw_result (#1405)
HopperProvider passed the bridge reply as rawResult and, for every
operation except address_to_file_offset, the same object as the result.
Every Hopper Evidence record (decompilation, procedure and string
listings, xrefs, ...) therefore carried its complete result twice, and
an MCP response four times counting its text copy.

raw_result is now null unless REA transformed the reply, which only the
file-offset mapping does; that case keeps Hopper's original reply.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:00:35 -07:00
7623e21ff0 perf(native): record pwntools diagnostics once in their Evidence (#1404)
inspect_binary_layout and inspect_recorded_crash passed the decoded report
as both result and rawResult, so every Evidence record carried the whole
report twice (and an MCP response four times, counting its text copy).
The decoded report is the only representation, so raw_result is now null,
as for other single-representation operations.

The real pwntools verifiers asserted the duplicate; they now assert null.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:00:11 -07:00
499e2f54ef perf(evidence): stop copying normalized results into raw_result (#1402)
createAnalysisExecution defaulted an omitted rawResult to a second
complete copy of the result. Every caller that had no distinct provider
representation therefore doubled its Evidence: decode_interface_builder,
inspect_keyed_archive, inspect_asset_catalog, trace_dylib_resolution,
inspect_native_dispatch_metadata, observe_native_calls,
observe_native_ui/capture_native_ui_scenario (including screenshots), and
small Ghidra/IDA lifecycle records. Sibling operations of the same
providers already recorded null.

An omitted rawResult now records null. Normalized results are unchanged.
MCP responses repeat Evidence in text and structured content, so each
response and its share of the 10 MiB transport budget shrink by the same
half; e.g. trace_dylib_resolution on a real app bundle drops from
3,217,119 to 1,612,524 bytes per representation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:52:54 -07:00
6875d4a64c fix(cli): accept JSON files for web capture and screenshot comparisons (#1397)
compare-web-captures and compare-web-screenshots parsed their arguments as
inline JSON only, unlike every other JSON-input command. Screenshot
artifacts and scenario captures embed base64 PNG bytes, so a typical
viewport screenshot exceeds the command-line length limit (128 KiB per
argument on Linux, 1 MiB total on macOS) and could not be compared from
the CLI at all, while MCP accepts it. A file path was reported as
malformed JSON, and screenshot schema failures returned no issues.

Each argument now accepts inline JSON or a JSON file path through
parseCliJsonInput; file failures keep its path diagnostics, malformed
inline JSON keeps the field issue, and screenshot validation reports
projected schema issues. The tests share one CLI JSON process fixture.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:42 -07:00
2b6e9ec03f fix(browser): classify selected web trace file failures by cause (#1396)
trace_web_module_imports and trace_web_source_location reported a missing
or non-file manifest, source map or import map as artifact_operation_failed
("Artifact could not be read or written" / "unsafe or conflicting internal
path"). These are caller selections: report ENOENT/ENOTDIR and non-regular
files as invalid input on the selected field, and EACCES/EPERM as a host
access denial. A missing manifest-derived source file stays an artifact fault.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:31 -07:00
498cec042a fix(cli): stop advertising multi-letter single-dash option aliases (#1395)
Incur's `alias` map registers one-letter short flags and already accepts
kebab-case spellings of camelCase options. Twenty options registered their
kebab-case long name as an "alias", so help and completions advertised
flags such as `-case-sensitive` and `-relative-path` that the parser reads
as stacked short flags and rejects with "Unknown flag: -c".

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:20 -07:00
Minghang ChamlingandGitHub 5fc4d792ca fix(javascript): handle oversized inline source maps (#1386)
* fix(javascript): handle oversized inline source maps

* fix(javascript): avoid source map directive regex overflow
2026-10-10 10:24:38 +08:00
Claude e4a8e0b728 fix(javascript): recognize Electron APIs through renamed bindings
Electron recognition matched callee spellings, so a bundler rename such as
esbuild's `import { ipcMain as ipcMain2 } from "electron"`, or a destructured
`const { contextBridge: bridge } = require("electron")`, hid every IPC
handler, BrowserWindow, contextBridge and utility process behind it.

Resolve each call and construction root lexically to its Electron import or
require origin, and classify the callee under that export's name. Shadowed
locals keep their own meaning.

On Hermes Desktop v0.21.6, whose main process is one esbuild ESM bundle,
recognized main IPC handlers rise from 1 to 204, BrowserWindow constructions
from 0 to 11, and paired renderer transmissions from 1 to 201.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPY2GmufMNGQKoEgRUx1pd
2026-10-10 00:44:32 +00:00
GRAB Racem e17290cd2a ci: re-run the suite on the corrected main checkpoint
b8a8190b restored the guarded-mutation uncertainty the failing test
encodes, so the shard should pass against the new merge base.
2026-10-10 02:34:52 +02:00
GRAB Racem 40f632a155 ci: re-run the suite after the main-branch shard flake
The failed shard is the JavaScriptSemanticGraphBuilder short-circuit
mutation test, which also failed on main run 38003459598 at the same
base commit (08ec2bf8) before this branch started CI, and passed on
main run 38003459600 minutes later at the same commit.
2026-10-10 02:06:15 +02:00
morluto 7aa4d768eb chore(release): sync corrected 6.3 checkpoint 2026-10-10 07:57:04 +08:00
morlutoandGitHub 74cf9e1401 Merge pull request #1383 from morluto/release-please--branches--release/6.3.0--components--rea-agents
chore(release/6.3.0): release rea-agents 6.3.0
2026-10-10 07:56:11 +08:00
morluto bf58eac4ef docs(release): restore complete 6.3 migration and ancestry notes 2026-10-10 07:42:17 +08:00
github-actions[bot]andGitHub 565f2efa03 chore(release/6.3.0): release rea-agents 6.3.0 2026-10-09 23:41:35 +00:00
morluto b8a8190b2f fix(javascript): retain conditional mutation ordering uncertainty 2026-10-10 07:40:25 +08:00
GRAB Racem e10c934d5a fix(ghidra): keep the cross-format branch callee multi-block
The cross-format oracle requires a callee whose recovered control flow
has more than one basic block, and rea_cross_branch provided it through
a symmetric if/else of tail calls. Clang 21 folds that shape into a
conditional negate plus one tail branch, a single basic block, so the
lane rejected a correct Ghidra analysis of the fixture.

Give the branch a loop whose trip count depends on a volatile global:
no compiler can eliminate the backedge, and the callee stays multi-block
at every optimization level on every toolchain.
2026-10-10 01:36:11 +02:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
08ec2bf82f chore(main): release rea-agents 6.3.0 (#1341)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-10 07:14:55 +08:00
morluto 001851fde6 fix(javascript): preserve capture-time guards and ordering 2026-10-10 07:13:48 +08:00
39dabd0608 fix(mcp): advertise object roots for union input schemas (#1373)
* fix(mcp): advertise object roots for union input schemas

Anthropic tool input schemas reject anyOf, oneOf, and allOf at the root.
Since 63bf9140 removed root flattening, compare_web_captures,
inspect_web_page, inspect_electron_page, and
project_managed_application_graph advertised root unions: Claude Desktop
disabled compare_web_captures and Claude Code exposed the tools without
parameters.

Present a root union of plain-reference object branches as one strict
object with the union of properties, shared required fields, a
minProperties bound, and a description of the accepted input groups. The
canonical Zod union still validates every call, so mixed input groups are
rejected before the handler runs. Branches whose reference siblings cannot
be merged keep their root alternatives.

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

* test(browser): keep comparison input boundary within lint limits

Express advertised and runtime expectations as one case table so the
boundary test stays under the 150-line function limit.

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

* fix(mcp): preserve input group dependencies in object schemas

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 07:03:12 +08:00
BaaRaiandGitHub 73a664bc78 fix(ghidra): verify dense jump tables on an optimized fixture (#1374)
The dense jump-table oracles (inspect-native-api CLI and the
analyze_function dossier) ran against the -O0 debug fixture, which
assumes the host compiler lowers dense switches to tables at -O0. GCC 16
and later expand them as compare chains instead, so on those hosts the
lane rejected a correct provider and Ghidra build with empty
jump_tables.

Build the same inventory source once more at -O2 as a dedicated
jump-table variant, run both strict dense oracles there, and keep the
debug dossier at its complete generic shape. The dedicated switch lane
already compiles at -O2 for the same reason.
2026-10-10 06:58:29 +08:00
355a292198 fix(javascript): preserve uncertainty after references escape to calls (#1292)
* fix(javascript): preserve uncertainty after references escape to calls

* fix(javascript): track iterator root escapes and preserve static captures

* fix(javascript): scope comparison unknowns to their evidence

* fix(javascript): track parameter origins at function body entry

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 06:53:42 +08:00
Akshit KhokhaniandGitHub d0e606930a fix(javascript): honor module-sync package exports (#1361) 2026-10-10 06:49:43 +08:00
You WishandGitHub a9f5dad5a8 fix(javascript): resolve exported callables through lexical bindings (#1351)
* fix(javascript): resolve exported callables through lexical bindings

* fix(javascript): preserve export scope and hoisted writes

* test(javascript): consolidate export binding assertions

* fix(javascript): account for skipped initializers and loop binding writes

* fix(javascript): preserve parameters copied into body variables
2026-10-10 06:39:56 +08:00
You WishandGitHub 1c0cc8a675 fix(snapshot): preserve complete investigation revision histories (#1354)
Select residual unknown histories as complete units and retain referenced registry mutation Evidence regardless of the active target at edit time. Prune incompatible dependency histories atomically instead of retaining stale dispositions.

Verify public MCP save/read/reopen for verified, withdrawn, and out-of-scope resolutions, and document target scope rules.
2026-10-10 06:39:29 +08:00
f504c2a351 fix(javascript): decline source-map UNC references with an unusable host (#1372)
* fix(javascript): decline source-map UNC references with an unusable host

A source map can name a Windows share whose host a file URL cannot carry,
such as `\\bad host\share\a.js`. On the Node builds `engines` admits,
`pathToFileURL(path, { windows: true })` fails a native assertion and calls
`abort()` on Node 22.19-22.22, 24.11-24.15 and 26.0, so the process dies
with exit 134 instead of declining the reference. Node 22.23 and 24.16 raise
`ERR_INVALID_URL` instead, and older builds silently drop the host, so the
same reference resolves three different ways depending on the runtime.

Validate the UNC host before handing the path to Node. A host carrying a
forbidden host code point, a percent escape or nothing at all now resolves as
`unresolved` on every admitted build, and `npm test` passes the existing
`\\bad host\share\a.js` row everywhere. Well-formed UNC hosts and
drive-letter paths are untouched.

* fix(javascript): validate UNC hosts through IDNA before conversion

Reject Unicode source-map UNC hosts that URL/IDNA processing cannot use or normalizes to an empty hostname before calling Windows pathToFileURL. Keep the original source identity and preserve usable normalized hosts.

Exercise the built reference resolver in owned subprocesses, including U+00AD and U+200C as source names and source roots. The original PR implementation aborts under Node 22.22.2; the new regression isolates those signals from the test runner. Add this test to the existing Node 22 Windows CI step.

Validation: 64 focused tests pass on Node 22.22.2 and 24.18.0; npm run check and test discovery pass. Local verification ran on macOS; Windows verification remains with CI.

---------

Co-authored-by: Yi-111-a <yi-111-a@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 06:38:47 +08:00
You WishandGitHub f91f2798b4 fix(process): keep unobserved file contents unknown (#1358) 2026-10-10 06:36:35 +08:00
keemsisiandGitHub 037709a52c perf(javascript): validate the version change graph once (#1370)
compareJavaScriptApplicationVersions built the change graph with
createJavaScriptApplicationGraph, which validates it and re-derives
every node, observation, edge and graph ID, then parsed the result
with a schema that embeds the full graph schema, repeating all of
that work. Seal the change graph with the owned immutable factory and
accept that exact sealed graph in the result parse, as owned analysis
results already do. Items, coverage and the public result schema are
unchanged; output is byte-identical.
2026-10-10 06:34:21 +08:00
morluto 810107a2ad fix(cli): stream JSON results at the shared command boundary
Route ordinary CLI results through the bounded JSON writer after command registration, including managed member inspection. Remove JavaScript-specific output plumbing while preserving filters, envelopes, cancellation, and failure exits.

Measure formatted UTF-16 expansion before Incur token counting and return resource_constraint above the runtime string limit, with recovery guidance.

Validate output above the real V8 string limit by SHA-256 and exercise the compiled managed provider. Clean-worktree validation: npm run check; 76 focused tests passed, with 2 optional-provider skips; test discovery passed.

Fixes #1371.
2026-10-10 06:23:26 +08:00
morluto ecc67cab2d ci: enforce architecture guards with portable checkout paths 2026-10-10 06:20:28 +08:00
morluto 4bcea1aa76 fix(javascript): retain array identity after length mutations
Keep unknown element coverage on arrays whose length may have changed, preserving intrinsic length presence and subsequent slot mutations through semantic graph and export-return consumers.
2026-10-10 06:20:28 +08:00
morluto 4951a897c5 fix(browser)!: preserve payload shapes and WebMCP declarations
Retain primitive and nested array types with typed paths, and compare only mutually observed body shapes while preserving selected coverage uncertainty. Return full untrusted WebMCP input declarations with canonical digests, without resolving references or invoking tools.

BREAKING CHANGE: JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
2026-10-10 06:20:28 +08:00
morluto d79317cda0 fix(artifacts): bind ASAR interpretation to owned snapshots
Verify captured container bytes against their inventoried digest before listing or reading packed members. Isolate per-reader ASAR metadata, preserve original unpacked companions, and retain complete inventories when snapshot cleanup fails.
2026-10-10 06:20:28 +08:00
BaaRaiandGitHub bf934d5592 fix(hopper): probe interior navigation from multi-byte instructions (#1285)
The real-Hopper navigation probe derived its interior coordinate as
anchor + 1, which assumes the fixture procedure's first instruction is
longer than one byte. Host toolchains without endbr64-style prologue
padding (Kali gcc 16, or any build with -fcf-protection=none) compile
rea_entry to start with the one-byte push rbp, so anchor + 1 is itself
an instruction boundary: goto_address correctly observes that boundary
and the boundary-contract run rejects a correct bridge.

Advance the probe to the first instruction followed by a coordinate gap
larger than one byte and derive the interior-coordinate assertions from
that instruction, so the probed coordinate is never an analyzed-object
boundary on either prologue encoding.
2026-10-10 06:07:01 +08:00
morluto 392f1f3107 refactor: consolidate boundary semantics and prune redundant tests
Share parser modes and collision-free composite keys, enforce architecture guards, and consolidate redundant unit assertions into filesystem, CLI, MCP, and producer-backed workflows. Preserve concurrent upstream boundary fixes and exclude legacy Objective-C class-name bookkeeping labels.

Validation: source/composition suites (3358 passing), focused canonical digest and MCP checks, typecheck/lint, Knip, formatting, architecture guards, and real Foundation archive and Apple legacy simulator CLI/MCP verification. No real Hopper, Ghidra, or IDA verification claim.
2026-10-10 05:56:01 +08:00
morluto 077d6c407b docs: correct MCP error and capture import guidance 2026-10-10 05:41:52 +08:00
morluto 7a0c800851 docs: remove retired architecture and migration artifacts 2026-10-10 05:41:45 +08:00
morluto 7738c1f6a9 docs: add repository-local REA tool design skill 2026-10-10 05:30:02 +08:00
morluto 5d79387505 docs: prune repeated contributor and tool design instructions 2026-10-10 05:28:13 +08:00
morluto ba4422296d docs: consolidate agent guidance around ownership and boundaries 2026-10-10 05:22:35 +08:00
morluto 614fb7681e fix(evidence): order canonical projections independently of locale 2026-10-10 05:13:53 +08:00
morluto 0f10499245 refactor(javascript): share Babel child traversal 2026-10-10 05:13:53 +08:00
morluto 617cd84d27 fix(browser): retain malformed redirect diagnostics 2026-10-10 05:13:53 +08:00
morluto abf5e243c4 fix(update): preserve disabled client registrations 2026-10-10 05:13:53 +08:00
morluto 5aa200285a fix(artifacts): infer legacy Mach-O simulator platforms 2026-10-10 05:13:53 +08:00
morluto 5751f5caac fix(artifacts): preserve archive facts and Unicode path identity 2026-10-10 05:13:53 +08:00
morluto 70bad53847 fix(native): distinguish symbol definitions from metadata 2026-10-10 05:13:53 +08:00
morluto 890bb66b35 fix(ida): compare admitted document paths consistently 2026-10-10 05:13:53 +08:00
YsopwnableandGitHub 53ed942a85 fix(mcp): preserve JavaScript workflow identity validation (#1366)
Preserve canonical distinct-source and unique-native-observation refinements after resolving inline or retained JavaScript workflow inputs. The shared application entry points now return structured invalid_request errors before graph parsing and computation, avoiding another complete graph capture.

Six focused tests, actual compiled CLI/SDK stdio workflows, JSON Schema dialect checks, static/document checks, and a real Notion ASAR analysis/recovery/trace/close workflow passed. All 20 final-head checks, including real JavaScript recovery, passed. Native-provider acceptance is not claimed for this provider-neutral validation change.

Fixes #1364
Refs #1065
2026-10-10 05:11:38 +08:00
YsopwnableandGitHub 6ce3288f3b fix(cli): stream JSON inputs beyond the whole-document string limit (#1360)
Stream large CLI JSON files through a strict UTF-8 decoder and standard JSON parser using the same admitted regular-file handle. Preserve native parsing for small inputs, typed malformed-input/resource/access-denied errors, cancellation, and complete Evidence.

Verified with focused public CLI regressions, a 768 MB whitespace-padded valid request, and the Windows native decoder boundary. Individual strings and the assembled object graph remain subject to native runtime limits. All 27 final-head checks passed.

Refs #1331
2026-10-10 04:53:09 +08:00
Dery FerdikaandGitHub 3728c8267b fix(ghidra): reject a native decompiler built for another host (#1280)
Reject positively identified foreign-only Ghidra decompiler binaries and non-regular native prerequisites before provider startup, while retaining unknown classifications for incomplete or unrecognized headers.

Verified with 54 focused tests and real Linux Ghidra CLI/MCP admission, decompilation, cleanup, wrong-host PE rejection, and non-blocking FIFO rejection. All 19 final-head checks passed.

Fixes #1192

Co-authored-by: Dery Ferdika <114888155+DeryFerd@users.noreply.github.com>
2026-10-10 04:52:25 +08:00
f39e71ce18 fix(skill): pin packaged commands to the shipping package version (#1346)
Fixes #1338.

Use canonical product identity for bundled command versions and keep build-cache fixtures aligned. Verified 10 focused tests, actual CLI installation/repair/uninstall scenarios and all 19 final-head CI checks.

Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
2026-10-10 04:47:10 +08:00
morluto 048b79878c test(native): retain trace diagnostics when observed hits differ 2026-10-10 04:39:17 +08:00
morluto 7ad353fa8b fix(native): retain LLDB cleanup ownership through client close 2026-10-10 04:35:03 +08:00
morluto 0bfb6e00ab test(filesystem): bound FIFO regressions at consumers 2026-10-10 04:23:03 +08:00
morluto 5291bca108 refactor(artifacts): remove unused root classifier 2026-10-10 04:16:29 +08:00
morluto 7829b1aeef fix(filesystem): reject unstable artifact targets 2026-10-10 04:14:54 +08:00
morluto 66a20a2597 test(managed): include shared dossier fixture in artifact inputs 2026-10-10 04:09:45 +08:00
morluto 5b3715ef82 docs: correct README setup and runtime guidance 2026-10-10 04:08:05 +08:00
morluto 37fcea78ce fix(cli): avoid duplicate primary cleanup diagnostics 2026-10-10 04:02:41 +08:00
morluto ac356c46ad test(javascript): share semantic graph test facts 2026-10-10 04:02:41 +08:00
morluto ca9010936a test(package): share validated native dossier fixtures 2026-10-10 04:02:40 +08:00
morluto 5d32e42529 test(cli): remove duplicate malformed JSON assertion 2026-10-10 03:53:12 +08:00
morluto 79d5b9a826 test(process): report cleanup details on cancellation failures 2026-10-10 03:52:35 +08:00
morluto 961c3c3de7 test(android): allow provider readiness under load 2026-10-10 03:52:35 +08:00
morluto d761d7358b test(ghidra): allow rollback tests to reach spawned process 2026-10-10 03:52:35 +08:00
morluto 006b295f1d refactor(javascript): parse runtime evidence into one verified owner 2026-10-10 03:52:35 +08:00
morluto 415145d04f fix(process)!: retain per-file digest open failures
BREAKING CHANGE: Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
2026-10-10 03:52:35 +08:00
morluto f62b44971d fix(mcp): advertise primitive semantic literal seeds 2026-10-10 03:52:35 +08:00
morluto 218c13160e fix: report malformed application evidence as input errors 2026-10-10 03:52:35 +08:00
morluto 55a46f7c71 fix(javascript): resolve query-only HTML references to their document 2026-10-10 03:52:35 +08:00
morluto 08daf056cc fix(cli): classify JSON input permission denials 2026-10-10 03:52:35 +08:00
morluto a4ba8aecd5 fix(contracts)!: require observed provider output metadata
Reject omitted segment bounds, procedure classification and body facts, unresolved-call observations, dossier facets, and Ghidra parameter flow metadata. Providers emit explicit nulls for unsupported facets. Verify those unknowns in the real Hopper workflow.

BREAKING CHANGE: Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
2026-10-10 03:52:13 +08:00
morluto e3bbb9ac45 refactor(javascript)!: share semantic evidence at fact construction
Intern shared provenance in a graph-scoped context registry while retaining exact locations on every fact. Semantic traces carry their referenced context subset, and portable graph validation rejects stale or dangling commitments.

BREAKING CHANGE: Semantic graph facts now store evidence context IDs and locations. Graph and semantic trace results require an inline evidence_contexts table.
2026-10-10 03:52:13 +08:00
YsopwnableandGitHub 9c4a68bc19 fix(json): preserve runtime limits across JSON file readers (#1350)
* fix(cli): preserve runtime JSON string-limit diagnostics

* test(json): check actionable oversized Evidence recovery

* fix(json): decode large UTF-8 inputs by character length

* test(json): reject truncated UTF-8 after large input decode
2026-10-09 19:39:35 +00:00
morluto 750fb65650 refactor(artifacts): test inventory changes at materialization boundary 2026-10-10 02:49:46 +08:00
morluto e36afa112f docs(contracts)!: explain canonical URL and skill metadata ownership
BREAKING CHANGE: source-map URLs now live in target observations selected by declared_url_sha256, and doctor skill identity no longer emits installed_catalog_digest. Use the documented observation join and identity.skill.state instead.
2026-10-10 02:49:46 +08:00
morluto a959a8309d test(json): remove assertions covered by CLI output consumers 2026-10-10 02:49:46 +08:00
morluto c867bcd0aa test(javascript): share primitive expansion producer fixtures 2026-10-10 02:49:46 +08:00
morluto 449d57075e refactor(javascript)!: remove obsolete scope truncation statistic
BREAKING CHANGE: remove the never-incremented truncated_scopes statistic from JavaScript application analysis results and schemas.
2026-10-10 02:49:46 +08:00
morluto b4a19193fe fix(setup): install the skill for Claude Code 2026-10-10 02:49:46 +08:00
morluto ed8fcae94b fix(javascript): store source map URLs once 2026-10-10 02:49:46 +08:00
morluto 7915ee5178 feat(javascript): record Electron integrity mismatches 2026-10-10 02:49:46 +08:00
morluto f0dc233d64 fix(setup): recognize supported Nobara hosts 2026-10-10 02:49:46 +08:00
morluto f7cf4c890d fix(cli): classify oversized JSON inputs 2026-10-10 02:49:46 +08:00
morluto db171be6e5 fix(javascript): preserve agreeing module provenance 2026-10-10 02:49:46 +08:00
2793672ee2 fix(skill): pin packaged commands to the shipping package version
The generated skill rewrote `rea-agents@latest` to the version it ships with, so a pinned install no longer needs a local edit that `doctor --skill` reports as stale.

Co-Authored-By: OpenCode <opencode@opencode.ai>
2026-10-10 02:49:46 +08:00
LucienandGitHub 1ac8389c5c test(artifacts): verify extraction races with real filesystem changes
Co-authored-by: dakjdakd <164857476+dakjdakd@users.noreply.github.com>
2026-10-10 02:38:33 +08:00
LucienandGitHub f6cfbfcc55 fix(browser): release attached viewport overrides without resizing the external page
Co-authored-by: dakjdakd <164857476+dakjdakd@users.noreply.github.com>
2026-10-10 02:33:56 +08:00
YsopwnableandGitHub 6c9161d617 docs: explain CI scope and native runner reuse (#1348) 2026-10-09 18:28:43 +00:00
YsopwnableandGitHub d5cb8aee06 fix(ci): scope verification and reuse native runners (#1344)
* fix(ci): scope documentation checks and cancel superseded runs

* ci: reuse package runners for native Inspector checks

* test(ci): share deterministic workflow Git fixtures
2026-10-09 18:22:03 +00:00
You WishandGitHub 1c123493a2 fix(hopper): allow restart after verified owned-provider shutdown
Co-authored-by: YouWish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-10 02:12:33 +08:00
keemsisiandGitHub b1e85ad711 perf(javascript): index version relationships once per comparison (#1347)
relationshipSignature rebuilt a node map and scanned every graph edge
for each side of each matched pair, so comparison cost grew as
pairs x (nodes + edges). Build node and adjacency indexes once per
graph in ItemContext; signatures, sorting and output are unchanged.
At 4000 matched modules, end-to-end compare: 5.7s -> 2.9s (2 edges
per node) and 10.4s -> 5.8s (6 edges per node); 8000: 3.3x and 2.5x.
Output JSON is byte-identical on the base commit.
2026-10-10 02:07:30 +08:00
3f59a84bd1 fix(contracts): advertise NUL with a portable hex escape
Use the equivalent hex NUL spelling in named public contracts while preserving current path and reserved-name validation. Verify converted JSON Schema and real stdio catalog consumers.

Closes #1329

Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
2026-10-10 01:54:42 +08:00
You WishandGitHub 5f16124a31 fix(files): reject nonregular capture and JSON inputs
Verify selected files through a nonblocking opened handle before reading. Preserve regular-file symlinks and return actionable CLI/MCP diagnostics without publishing output.

Co-authored-by: YouWish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-10 01:49:54 +08:00
morluto cfce91d418 fix(browser): serialize attached scenarios through cleanup settlement 2026-10-10 01:45:01 +08:00
morluto 4940a867e2 test(process): use owned CLI and workspace fixtures 2026-10-10 01:45:01 +08:00
morluto 74be52611e test(process): publish capture readiness atomically 2026-10-10 01:45:01 +08:00
morluto 377df715ea refactor(reference): simplify malformed UTF-8 handling 2026-10-10 01:45:01 +08:00
morluto 5a61562dc2 test(browser): report redirect status cases independently 2026-10-10 01:45:01 +08:00
morluto 96b2b245fd test(javascript): verify distinct module origins through reconstruction 2026-10-10 01:45:01 +08:00
morluto 41a228c1b0 fix(electron): preserve unrepresentable numeric option evidence 2026-10-10 01:45:01 +08:00
morluto 3e19875c7f fix(javascript): retain unresolved value frontiers in provenance queries 2026-10-10 01:45:01 +08:00
morluto b628bba1fa refactor(javascript): normalize erased expression syntax once 2026-10-10 01:45:01 +08:00
morluto cfb12e47dc fix(artifacts): validate only active extraction entries 2026-10-10 01:45:00 +08:00
ACandmorluto 7a4f2685d4 fix(javascript): reject invalid package exports configurations 2026-10-10 01:45:00 +08:00
ACandmorluto 2b4abbf1cc fix(javascript): distinguish prefix-only builtins from packages 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 9367dc13bd test(browser): avoid duplicating source-map listener setup
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 82bbe74333 fix(browser): follow only HTTP redirect statuses for source maps
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto f166a2ae15 fix(reference): report malformed UTF-8 before import parsing
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 9055bd695b fix(javascript): avoid positive-zero evidence for signed zero 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 2bd7de6f8c fix(javascript): retain distinct module provenance path components 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto e995b19f83 fix(javascript): preserve semantic evidence through satisfies 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 4896adcd0f fix(javascript): parse declaration artifacts in ambient mode 2026-10-10 01:45:00 +08:00
dakjdakdandmorluto a0523b375e fix(browser): retain attached scenario emulation until cleanup 2026-10-10 01:45:00 +08:00
dakjdakdandmorluto 5e8fb531e2 fix(artifacts): reject incomplete inventoried extraction 2026-10-10 01:45:00 +08:00
YsopwnableandGitHub 3edb2172de Merge pull request #1334 from morluto/docs/celebrate-40000-stars
docs: celebrate 40,000 GitHub stars 🎉
2026-10-10 01:35:02 +08:00
YsopwnableandGitHub 8c1bec42ba chore(release): sync 6.2.0 checkpoint into main (#1340)
Preserve the published 6.2.0 tag ancestry and main's later implementation changes.
2026-10-10 01:31:46 +08:00
N0zoM1z0 0c3aa98a3e chore(release): sync 6.2.0 checkpoint into main 2026-10-09 17:13:44 +00:00
morluto 8c96baab80 refactor(catalog): import CLI metadata from its owner 2026-10-10 00:49:14 +08:00
morluto 4144e454f3 refactor: remove single-use forwarding helpers 2026-10-10 00:49:14 +08:00
morluto 070339af50 refactor(process): remove duplicate observation and trace entry points 2026-10-10 00:49:14 +08:00
morluto d1983a4576 refactor(browser): open scenario sessions without a factory wrapper 2026-10-10 00:49:14 +08:00
morluto 87f0051496 refactor(providers): use canonical artifact and managed identities 2026-10-10 00:49:14 +08:00
N0zoM1z0 5ecc98a5ea docs: celebrate 40,000 GitHub stars 🎉 2026-10-09 16:43:35 +00:00
1b73b5ab4b fix(native): refuse to list architectures of non-Mach-O targets (#1325)
list_architectures ran lipo on every admitted target. For a PE DLL, ELF
binary or plist, lipo's refusal surfaced as execution_failure with
"Retry once; if it continues, run rea doctor", which neither can fix.
Refuse non-Mach-O targets as capability_unavailable before running
lipo, as inspect_macho already does.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:41:03 -07:00
56598beb4e perf(json): encode streamed JSON iteratively (#1322)
The streamed JSON encoder delegated every token through one recursive
generator per nesting level and yielded each token separately. Writing
analyze-javascript-application output for Typora (873 MB) spent 22 of
66 s there. Encode with an explicit stack into bounded 16 KiB parts:
identical bytes, 3-6x faster encoding, and the same laziness, error
and surrogate-pair guarantees.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:40:45 -07:00
morluto d83cbd2abf test: share snapshot replay and managed graph fixtures 2026-10-10 00:35:17 +08:00
morluto a27794c246 fix(artifacts): retain DMG ownership through uncertain attachment 2026-10-10 00:35:17 +08:00
morluto 35f121f4ac fix: retain completed observations when later analysis steps fail 2026-10-10 00:35:17 +08:00
morluto e11f4d371a fix(mcp): admit composed analysis through result bookkeeping 2026-10-10 00:35:17 +08:00
morluto e64678e8f9 fix(mcp): retry failed shutdown resources and retain failure reasons 2026-10-10 00:35:17 +08:00
morluto 25711ad259 test: exercise source test selection through Git and Vitest 2026-10-10 00:35:17 +08:00
morluto f3c4a332f7 fix(targets): cancel resolution before provider admission 2026-10-10 00:35:17 +08:00
morluto 44c92f88c5 refactor: remove obsolete source exclusions and identity wrapper 2026-10-10 00:35:17 +08:00
morluto 07675f78c6 fix(ghidra): retain process ownership after failed launch rollback 2026-10-10 00:35:17 +08:00
morluto cc7b5af077 fix(managed): bind graph facts to their source Evidence 2026-10-10 00:35:17 +08:00
morluto b112d44a39 fix(native)!: preserve unknown Objective-C metadata
BREAKING CHANGE: Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
2026-10-10 00:35:16 +08:00
morluto e10f1f0901 docs: keep license sections text-only 2026-10-10 00:09:46 +08:00
5d16be2a71 test: share the client registration command to restore the jscpd gate (#1317)
After #1301 merged, main's duplicated-line share rose to 2.503%, over
jscpd's 2.5% threshold, so Static checks fail on every PR. The new OMP
test repeated the dialect test's imports and npx registration command.
Export that command from the shared client test fixture instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:09:08 -07:00
morluto ccfbe87e98 docs: align translated README artwork and layout 2026-10-10 00:03:14 +08:00
morluto 4b8e744d90 docs: add README artwork and refine closing sections 2026-10-10 00:00:41 +08:00
8b4c359135 feat(setup): register OMP during setup (#1301)
* feat(setup): register OMP during setup

Add OMP (oh-my-pi) as a setup, doctor and uninstall client. Setup writes
a type: stdio entry to the user-level agent mcp.json that OMP reads,
following PI_CONFIG_DIR, an absolute PI_CODING_AGENT_DIR and the
OMP_PROFILE/PI_PROFILE named profile. It removes rea from OMP's
disabledServers denylist, which would otherwise hide the registration,
and doctor reports a listed registration as stale.

Closes #1257

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

* fix(setup): honor OMP's enabledServers allowlist in doctor

OMP's user enabledServers allowlist forces an entry with enabled: false
on, unless disabledServers also lists it. Doctor reported such a working
registration as stale. Also format the FAQ client list.

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

* fix(setup): keep OMP's allowlisted entry in update maintenance

rea update skipped an owned OMP entry with enabled: false even when
OMP's enabledServers allowlist runs it. Apply the same forced-enable rule
as doctor. Share the client-location environment reset across the client
tests instead of repeating it in each file.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:51:12 -07:00
morluto 24673aaae4 test(mcp): remove arbitrary schema inventory thresholds 2026-10-09 23:35:19 +08:00
morluto 765e809e36 refactor: use canonical implementations and types directly
Remove forwarding wrappers and shadow aliases, migrate callers and verification scripts to their owners, and share one exhaustive semantic resource-bound projection.
2026-10-09 23:35:19 +08:00
morluto 3283a45d09 refactor(captures)!: require canonical producer metadata
Require process retention accounting, browser network transaction identity, and all web comparison dimensions. Remove obsolete omission repairs and derive completeness from the owning producer facts.

BREAKING CHANGE: Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected.
2026-10-09 23:35:19 +08:00
morluto dea3498b2b fix(inspector): retain observations after capture failures 2026-10-09 23:35:19 +08:00
kvalls be6863e9a1 feat(ghidra): support native PE DLLs on Windows 2026-10-09 16:11:13 +01:00
1181 changed files with 76267 additions and 16916 deletions
+20
View File
@@ -0,0 +1,20 @@
---
name: rea-tool-design
description: Design or change REA investigation tools, CLI/MCP contracts, provider capabilities, and Evidence semantics.
---
# REA tool design
Use the [tool-design guide](../../../docs/tool-design.md) for tool boundaries,
contract semantics, provider ownership, and discoverability. Inspect the current
contract and nearest existing tool relevant to the analyst question; source,
documentation, and live catalogs may describe different versions.
For a design request, return the proposed boundary, input/result shape, Evidence
semantics, nearest alternative, and verification approach. Implement when
requested, preserving the user's scope and existing authorization.
For implementation or verification, consult [testing](../../../docs/testing.md)
for the affected consumer and provider lanes, and
[contributing](../../../CONTRIBUTING.md) for generated-file ownership. Read
provider/workflow guides only as the task requires.
@@ -2,7 +2,7 @@
name: reverse-engineer-anything
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
metadata:
version: "34"
version: "36"
---
# REA
@@ -31,7 +31,7 @@ When tools are absent or registration is stale:
`npx -y rea-agents@latest doctor --client codex --json`. Substitute the current
supported client: `claude_code`, `claude_desktop`, `codex`, `cursor`,
`gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`, `copilot_cli`,
`commandcode`, `vscode`, `grok_build`, or `grok_bot`. `grok_bot` has no local
`commandcode`, `qwen_code`, `vscode`, `grok_build`, `omp`, `pi`, `hermes`, or `grok_bot`. `grok_bot` has no local
file registration: doctor reports the Grok Bot chat step, and setup does not
write `mcp.json`. If the client is unknown, use `doctor --json` and
inspect its registration results before choosing a setup scope.
@@ -62,13 +62,20 @@ with a version-pinned `rea-agents` package or continue through the CLI.
A concrete CLI fallback for an operator-supplied JavaScript tree or ASAR is:
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json > app-evidence.json
jq -c '{source: {kind: "inline", evidence: .}, view: {kind: "summary"}}' app-evidence.json > app-view.json
npx -y rea-agents@latest inspect-analysis-view app-view.json
```
No MCP registration or native engine is required. Read the returned Evidence,
graph, limitations, and unknowns with the same care as an MCP result; the CLI
returns the Evidence record directly. This fallback does not establish that
MCP is configured. Native CLI tasks still require their selected engine.
No MCP registration or native engine is required. The CLI returns the complete
Evidence record directly, and a real application can produce hundreds of
megabytes, so save it to a file rather than reading it into context. Start from
the summary view, then request a module page
(`{"kind": "page", "collection": "modules", "offset": 0, "limit": 32}`) or one
module the same way, or pass the saved Evidence inline to
`trace-application-feature`. Read graph, limitations, and unknowns with the
same care as an MCP result. This fallback does not establish that MCP is
configured. Native CLI tasks still require their selected engine.
## Route the target first
@@ -114,6 +121,9 @@ explicit path or endpoint and do not need it.
Historical PIDs do not select live processes. Request `include_debugger_context`
only when core-only mapping candidates help; see the
[recorded crash guide](https://github.com/morluto/rea/blob/main/docs/recorded-crashes.md).
- PE resource type/name/language trees and static icon group references:
`inspect_pe_resources` with an explicit path. This portable operation requires
no active target or engine; opaque payloads retain file ranges and SHA-256.
- Native executable, library, or analysis database: `open_binary`, then
use focused analysis tools directly; call `binary_overview` when metadata or
inventory context is useful and available from the selected provider.
@@ -143,6 +153,10 @@ list stays complete; availability depends on the operation, target, and host.
## Work summary-first
Start with the default result and use its inline Evidence and graph context.
For a JavaScript application or ELF layout whose size is unknown or large,
call `analyze_javascript_application` or `inspect_binary_layout` with
`"detail": "summary"`, then inspect the retained `parent_evidence_id` with
`inspect_analysis_view`.
Do not repeat an identical tool call. Make a focused follow-up only when the
returned result leaves a specific question unanswered.
@@ -34,6 +34,15 @@ cross-references. Addresses and recovered pseudocode are analysis observations,
not original source. Provider unavailability and unsupported metadata remain
unknown rather than false.
For a completed `analyze_function` dossier, use `inspect_analysis_view` with
`view: {kind: "native", facet: "value_flow_operations", offset: 0, limit: 32}`
and the exact retained Evidence ID to read selected facts without reanalysis.
Native facets also include procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and value-flow summaries. Pseudocode offsets and limits count UTF-16
code units; use the returned `next_offset` for continuation. Provider limitations
and unavailable facts remain explicit; the complete parent Evidence is retained.
To see which functions or Objective-C methods a Mach-O actually calls in one
run, use `observe_native_calls` with explicit breakpoints and a bounded
`duration_ms`/`max_events`. It launches a new process under LLDB, so the target
@@ -60,6 +69,15 @@ use inclusive ends and can contain gaps. Do not treat the enclosing span as code
For packed targets, retain the original and separately derived artifact identities;
decompiling an unpacking stub does not recover the unpacked program.
When reading Objective-C dispatch metadata, distinguish class implementation
methods from protocol requirements: class methods report null requirement
flags, while decoded protocol declarations retain required and optional facts.
Property attributes remain raw name/value tokens; use the property's
`atomicity` field for the decoded `N` marker or the default atomic behavior.
Null class/meta flags, ivar counts, atomicity, or read-only values mean the
selected provider did not establish that fact. Symbol names alone do not prove
that a class is a root class or has no ivars.
## Managed PE/CLI
Start with `inspect_managed_artifact`. REA's canonical managed inspection is
@@ -135,3 +153,15 @@ context. PSP/stack/device state remains unmodeled. See [DOS guide](https://githu
### Function annotations in Ghidra
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations.
## Offline PE resource inventory
Use `inspect_pe_resources` with an absolute `path`, or
`rea inspect-pe-resources ./selected.exe --json`, for portable PE32/PE32+
resource inspection without opening a native target. Preserve returned Evidence:
type/name/language IDs and UTF-16 names, original directory/data/payload ranges,
code pages, payload hashes and static icon-group references. Same-language icon
resolution is explicit; missing references and size mismatch remain visible.
Other payloads are opaque, and this operation does not decode images or simulate
Windows resource loading. Consult the budgets and supported tree profile in
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/binary-diagnostics.md).
+1 -1
View File
@@ -28,7 +28,7 @@ intentionally not included. -->
- Provider, bridge, target-format, or platform compatibility:
- Evidence, artifact, provenance, or reconstruction contract:
- Process execution, authorization, cleanup, or containment impact:
- Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `skill-src/` and never commit build outputs):
- Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs):
## Evidence and regression coverage
+25 -48
View File
@@ -8,7 +8,9 @@ on:
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# The latest main push verifies the full tree, including earlier changes.
# Publication uses its own release workflow and concurrency group.
cancel-in-progress: true
env:
HUSKY: "0"
@@ -47,15 +49,22 @@ jobs:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
if [[ "${GITHUB_EVENT_NAME}" != "pull_request" ]]; then
echo "required=true" >> "${GITHUB_OUTPUT}"
elif git diff --quiet "${BASE_SHA}" "${HEAD_SHA}" -- \
# Compare the PR's changes, excluding unrelated updates on its base.
elif git diff --quiet "${BASE_SHA}...${HEAD_SHA}" -- \
. \
':(exclude)docs/**' \
':(top,exclude,glob)README*.md' \
':(exclude)AGENTS.md' \
':(exclude)CONTRIBUTING.md'; then
echo "required=false" >> "${GITHUB_OUTPUT}"
else
diff_status=$?
# A failed comparison must fail classification, not report a scope.
if [[ "${diff_status}" -ne 1 ]]; then
exit "${diff_status}"
fi
echo "required=true" >> "${GITHUB_OUTPUT}"
fi
@@ -302,7 +311,7 @@ jobs:
- run: npm run verify:windows-native:artifact
- run: npm run verify:package
- name: Verify real Node Inspector discovery and observation
if: matrix.platform == 'darwin'
timeout-minutes: 10
run: npm run verify:inspector
apple-artifacts:
@@ -321,6 +330,8 @@ jobs:
- run: npm run verify:keyed-archive
- run: npm run verify:asset-catalog
- run: npm run verify:macos-bundle
- name: Legacy simulator platform verification
run: npm run verify:legacy-simulator
- name: Native installer and compiled NIB hierarchy regressions
run: npm run test:focused -- tests/boundary/filesystem/installScript.test.ts tests/boundary/filesystem/nibNativeHierarchy.test.ts tests/boundary/filesystem/interfaceBuilderBundle.test.ts
- name: Real binary metadata and Interface Builder integration
@@ -365,48 +376,6 @@ jobs:
if-no-files-found: error
retention-days: 30
javascript-runtime-observation:
name: JavaScript runtime observation (${{ matrix.os }})
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: ubuntu-24.04-arm
platform: linux
architecture: arm64
- os: windows-latest
platform: win32
architecture: x64
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- name: Verify native runtime identity
env:
EXPECTED_CI_PLATFORM: ${{ matrix.platform }}
EXPECTED_CI_ARCHITECTURE: ${{ matrix.architecture }}
run: >-
node -e "const assert = require('node:assert/strict');
assert.equal(process.platform, process.env.EXPECTED_CI_PLATFORM);
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
- run: npm ci
- name: Verify real Node Inspector discovery and observation
run: npm run verify:inspector
windows-curated:
name: Windows capability and package lane
needs: [changes, windows-native-build]
@@ -448,6 +417,7 @@ jobs:
tests/boundary/filesystem/binaryTarget.test.ts
tests/boundary/filesystem/safeOutputTree.test.ts
tests/boundary/providers/native/artifactProvider.archiveSafety.test.ts
tests/boundary/providers/native/artifactProvider.extractionCompleteness.test.ts
tests/boundary/filesystem/setupUnavailableProvider.test.ts
tests/boundary/filesystem/windowsNpxRegistration.test.ts
tests/boundary/filesystem/webScriptManifestPaths.test.ts
@@ -455,7 +425,6 @@ jobs:
tests/acceptance/webModuleCli.test.ts
tests/acceptance/webSourceLocationCli.test.ts
tests/boundary/cli/referenceSourceImportStatus.test.ts
src/cliReferenceSourceImportStatus.test.ts
tests/boundary/filesystem/asarInventoryFreshness.test.ts
tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
tests/conformance/providers/ghidra/windowsCapabilities.test.ts
@@ -463,6 +432,7 @@ jobs:
tests/boundary/providers/ghidra/ghidraTransport.test.ts
tests/boundary/providers/ghidra/ghidraTargetSnapshot.test.ts
tests/boundary/providers/ghidra/ghidraLauncher.test.ts
tests/boundary/providers/hopper/hopperClient.cleanupRetry.test.ts
src/windows/WindowsNativeLoader.test.ts
src/windows/WindowsOwnedProcess.test.ts
src/ghidra/GhidraLauncherEnvironment.test.ts
@@ -474,6 +444,12 @@ jobs:
tests/process-global/updateMaintenance.test.ts
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
- run: npm run verify:windows-native
- name: Verify real Node Inspector discovery and observation
timeout-minutes: 10
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
run: npm run verify:inspector
- run: npm run verify:package:windows
- name: Verify native directory identity on Node 24
run: >-
@@ -484,12 +460,13 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 22.19.0
- name: Verify native directory identity on Node 22
- name: Verify native path boundaries on Node 22
run: >-
npx vitest run --coverage.enabled=false
tests/boundary/filesystem/directoryArtifactReaderOpen.test.ts
tests/boundary/filesystem/javascriptPackagePrecedence.test.ts
tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts
tests/boundary/process/sourceMapUncHosts.test.ts
- uses: actions/upload-artifact@v4
if: always()
with:
+20
View File
@@ -64,6 +64,14 @@ jobs:
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --x86 | Tee-Object -FilePath windows-ghidra-x86-proof.log
- name: Verify native x64 DLL Windows Ghidra operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --dll | Tee-Object -FilePath windows-ghidra-dll-proof.log
- name: Verify native x86 DLL Windows Ghidra operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --x86 --dll | Tee-Object -FilePath windows-ghidra-x86-dll-proof.log
- name: Verify ordinary-user CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
@@ -72,6 +80,14 @@ jobs:
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --x86 | Tee-Object -FilePath windows-ghidra-x86-package-proof.log
- name: Verify ordinary-user x64 DLL CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --dll | Tee-Object -FilePath windows-ghidra-dll-package-proof.log
- name: Verify ordinary-user x86 DLL CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --x86 --dll | Tee-Object -FilePath windows-ghidra-x86-dll-package-proof.log
- uses: actions/upload-artifact@v4
if: always()
with:
@@ -81,4 +97,8 @@ jobs:
windows-ghidra-package-proof.log
windows-ghidra-x86-proof.log
windows-ghidra-x86-package-proof.log
windows-ghidra-dll-proof.log
windows-ghidra-x86-dll-proof.log
windows-ghidra-dll-package-proof.log
windows-ghidra-x86-dll-package-proof.log
retention-days: 30
@@ -56,9 +56,9 @@ jobs:
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/rea-wakaru"
curl --fail --location --retry 3 https://github.com/pionxzh/wakaru/releases/download/v1.13.0/wakaru-linux-x64.tar.gz -o "$RUNNER_TEMP/rea-wakaru/release.tar.gz"
curl --fail --location --retry 3 https://github.com/pionxzh/wakaru/releases/download/v1.14.0/wakaru-linux-x64.tar.gz -o "$RUNNER_TEMP/rea-wakaru/release.tar.gz"
tar -xzf "$RUNNER_TEMP/rea-wakaru/release.tar.gz" -C "$RUNNER_TEMP/rea-wakaru" wakaru
printf '%s %s\n' e8c7ca052974604197389f6ace7464e4dd24dce64e2730971521bd6606ec9c9e "$RUNNER_TEMP/rea-wakaru/wakaru" | sha256sum --check
printf '%s %s\n' 664fa06782a61eda7ed15885134b52525fd565dd77607e642062ceb6cd927c38 "$RUNNER_TEMP/rea-wakaru/wakaru" | sha256sum --check
- name: Install isolated fixture compilers
run: npm install --prefix "$RUNNER_TEMP/rea-fixture-compilers" --ignore-scripts --no-audit --no-fund esbuild@0.25.10 webpack@5.101.3
- run: npm run build:cached
+2 -6
View File
@@ -35,9 +35,5 @@ jobs:
sudo apt-get update
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
python3 -m pip install -r website/requirements.txt
- name: Prepare website assets
run: python3 scripts/prepare-website.py
- name: Check website links, metadata and publishing configuration
run: python3 scripts/verify-website.py
- name: Check sitemap discovery and metadata regressions
run: python3 scripts/test-website.py
- name: Check shared HTML, links, assets and contributor workflows
run: python3 scripts/website.py check
+2 -4
View File
@@ -59,10 +59,8 @@ jobs:
sudo apt-get update
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
python3 -m pip install -r website/requirements.txt
- name: Prepare website assets
run: python3 scripts/prepare-website.py
- name: Check website links, metadata and publishing configuration
run: python3 scripts/verify-website.py
- name: Check shared HTML, links, assets and contributor workflows
run: python3 scripts/website.py check
- name: Record the published commit
run: |
python3 - <<'PY'
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "6.2.0"
".": "6.3.0"
}
+25 -92
View File
@@ -1,116 +1,49 @@
# Repository Guidelines
## Product Direction
## Product and Authority
REA exposes reverse-engineering tools through a CLI and MCP server. Hopper, the bring-your-own Ghidra adapter, and the bring-your-own IDA MCP adapter are operation-capable deep binary-analysis providers. Ghidra is supported on Linux x64/arm64 and macOS x64/arm64 with matching native decompiler tools, and has an experimental Windows x64 P0 boundary for approved native x86 and x86-64 PE applications; on Linux and macOS it supplies inventory, function analysis, and atomic function annotation edits in an ephemeral database, without modifying executable bytes or controlling a GUI. Windows P0 has no mutation authority. IDA adapts upstream legacy attached GUI and modern headless database-supervisor profiles for live read-only analysis; initial real verification covers Windows, and an attached GUI database is never saved or closed. Keep provider-specific code out of the domain and application layers.
REA is a local-only reverse-engineering tool with shared CLI/MCP workflows. Distinguish observations, derivations, inferences, and unknowns; preserve Evidence provenance and session semantics through both adapters. Provider support and setup live in [README.md](README.md#choosing-a-deep-analysis-provider) and its linked guides.
Prioritize:
Ghidra uses ephemeral databases without modifying executable bytes or controlling a GUI; Windows Ghidra P0 has no mutation authority. IDA analysis is read-only; never save or close an attached GUI database.
- tool results that distinguish observations, inferences, and unknowns;
- equivalent behavior through the CLI and MCP;
- additive, idempotent configuration with backups;
- end-to-end tests for packaged artifacts and real Hopper/Ghidra claims.
Configuration changes must be additive and idempotent, with backups. Installers must not install or upgrade unrelated software, including Homebrew, Node.js, npm, Java, or Ghidra. Ghidra and IDA are bring-your-own. `rea setup` must show its planned changes and require approval before writing files or installing Hopper.
Installers must not install or upgrade Homebrew, Node.js, npm, Java, Ghidra, or other unrelated software. Ghidra is bring-your-own. `rea setup` must print its planned changes and require approval before writing files or installing Hopper.
Preserve caller-selected inputs and local evidence, including output, URLs, paths, digests, and metadata. Redact transport authentication credentials and explicitly marked sensitive values; do not infer secrecy from names or text patterns. Do not persist the ambient environment merely because a child inherits it.
REA is a local-only tool. Preserve caller-selected inputs, captured output, URLs, paths, digests, mismatch locations, and analysis metadata. Do not guess that local evidence is secret from environment-variable names, argument names, or text patterns. Redact transport authentication credentials and values the caller explicitly marks sensitive; do not persist the entire ambient environment merely because a child inherits it.
## Architecture and Cleanup
## Project Structure & Module Organization
Dependencies flow inward: domain semantics and contracts, provider adapters, shared application workflows, then CLI/MCP adapters. Keep engine protocols and provider-specific code out of domain/application layers. See [docs/architecture.mermaid](docs/architecture.mermaid) when changing composition.
REA is a layered ESM TypeScript application. Dependencies flow inward from pure domain logic through contracts, providers, application workflows, and CLI/MCP adapters. See [docs/architecture.mermaid](docs/architecture.mermaid) for the component map.
Give each interpretation and resource a clear owner. Preserve identity, omission, uncertainty, and source evidence across boundaries. Retain ownership of resources whose cleanup failed. Reuse `src/process/` supervision and identity primitives; a PID and executable path alone do not establish ownership after exit or reuse.
- `src/domain/` owns pure provider-neutral semantics; `src/contracts/` owns caller-visible schemas and the canonical tool inventory.
- `src/hopper/`, `src/ghidra/`, `src/ida/`, `src/browser/`, `src/inspector/`, `src/native/`, `src/artifacts/`, and `src/dotnet/` own provider-specific boundaries. Keep provider protocols out of domain and application code.
- `src/application/` composes shared CLI/MCP workflows, including Evidence provenance, unknowns, and eligible snapshot bindings; `src/server/` translates MCP requests; `src/cli.ts` and `src/main.ts` are the CLI and MCP entry points.
- `src/process/` owns shared process lifecycle primitives, not provider wire protocols. Reuse its supervision and identity primitives before adding provider-local lifecycle code; a PID and executable pathname alone do not establish ownership after exit or reuse. `bridge/` contains provider-side adapters.
- `tests/` contains unit, composition, boundary, acceptance, and conformance tests. `scripts/verify-*` and capability directories under `scripts/verify/` contain real-toolchain checks.
- `docs/public/product-catalog.json`, `docs/verification/managed-conformance-*.json`, and `skills/` are ignored build outputs. Update source contracts and authored instructions in `skill-src/`, then run `npm run docs:generate`; never commit derived catalog digests or portable conformance projections.
- `.cache/mcp-tool-catalog.json` is generated test metadata. Generate it with `npm run mcp-catalog:generate`; source checking and runtime builds do not consume it.
Assess brittleness in touched code during implementation, debugging, review, and maintenance. Fix the producing representation or ownership rule before adding downstream repairs. Normalize once at the owning boundary using format-aware parsers. Remove superseded representations, aliases, wrappers, and redundant tests after verifying affected consumers. Introduce abstractions only when they remove observed complexity.
## Build, Test, and Development Commands
Parse unknown boundary values and model expected failures with the tagged error algebra and `Result`. Preserve partial facts and meaningful failure reasons. Keep identity and lookup values separate from display formatting; preserve source values and explicit unknowns when normalization loses information. Absolute paths, file URLs, and HTTP paths have different semantics.
- `npm ci`: install the locked dependencies.
- `npm run build:cached`: compile the CLI/MCP runtime and bundle its authored skill. Test catalogs and documentation/conformance artifacts have separate tasks.
- `npm run test:local`: run changed source tests without building; pass exact source test paths to run them regardless of Git status.
- `npm run test:focused -- PATH...`: run exact test files, preparing runtime and generated artifacts required by the selected tests.
- `npm run check:changed`: run cached static checks and source tests affected since the branch merge base (default `origin/main`).
- `npm run check:fast`: run cached typecheck and lint checks.
- `npm run check:pr`: opt into the complete local deterministic gate and generated-document checks for broad changes; CI owns full coverage. Routine iterations need focused tests and relevant checks, not the whole gate each time.
- `npm run docs:check`: build and validate generated documents for the current checkout; `npm run docs:generate` regenerates them. CI retains ignored outputs as artifacts and does not push snapshot commits to feature branches.
- For provider-dependent changes, see [docs/testing.md](docs/testing.md) and run the matching real-provider verification.
- Keep each verification lane's prerequisites limited to the claim it checks. Use host-native fixtures for host/provider acceptance; put optional cross-target formats and their external toolchains in a separate lane. Preflight required commands and report the missing dependency and lane clearly.
Validate advertised JSON Schemas after SDK conversion against their declared dialect and actual clients. Bind handlers to named contracts with exact types; catalog ordering must never select an operation or schema.
See [docs/testing.md](docs/testing.md) for test scopes and verification lanes and [CONTRIBUTING.md](CONTRIBUTING.md) for contribution checks. Pre-commit formats and lints staged source; pre-push runs `npm run check:fast`.
## Development
## Configuration & Environment Variables
Use [.nvmrc](.nvmrc) and `package.json#packageManager` for the pinned toolchain. Cursor Cloud may place older Node.js first on `PATH`; environment setup installs the pinned toolchain under `/usr/local/bin`.
Configuration is parsed and validated by `src/config.ts` and `src/config/`. Keep user-facing setup and provider configuration in [README.md](README.md) and the relevant guide under `docs/`; do not maintain a second environment-variable catalogue here.
- `npm ci`: install locked dependencies.
- `npm run build:cached`: build the runtime and packaged skill.
- `npm run test:local -- PATH...`: source tests without building.
- `npm run test:focused -- PATH...`: exact tests with their required artifacts.
- `npm run check:fast`: cached typecheck/lint and the pre-push check.
- `npm run docs:check`: validate generated documentation.
## Coding Style & Naming Conventions
Use relevant checks for the change. The complete local gate, `npm run check:pr`, is optional for broad changes or CI diagnosis. See [CONTRIBUTING.md](CONTRIBUTING.md) for development, generated-file ownership, and release conventions.
Use ESM TypeScript, two-space indentation, and the committed Oxfmt configuration. Keep compiler strictness intact (`strict`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, `verbatimModuleSyntax`). Use `camelCase` for values/functions, `PascalCase` for classes/types, and `UPPER_SNAKE_CASE` for constants. Parse unknown values at every MCP, environment, and subprocess boundary. Avoid `any`, unchecked casts, non-null assertions, import-time I/O, and floating promises. Exported APIs require concise JSDoc. Model expected failures with the tagged error algebra and `Result`, not broad exception wrappers.
`docs/public/product-catalog.json`, `docs/verification/managed-conformance-*.json`, and `skills/` are ignored outputs. Edit source contracts and `.agents/skills/reverse-engineer-anything/`, then regenerate as needed. `.cache/mcp-tool-catalog.json` is test metadata; runtime builds and source checking do not consume it. Never commit binaries, provider project documents, credentials, `dist/`, `node_modules/`, or local planning artifacts.
Assess brittleness during implementation, debugging, review, and maintenance. Simplify duplicated rules, scattered defaults, caller-specific exceptions, and unclear invariants in touched code. Prefer standard format-aware parsers and existing shared helpers; normalize once at the owning boundary while preserving source evidence. Keep refactors focused on the task, and introduce abstractions only when they remove observed complexity. Verify preserved behavior and corrected edge cases through affected callers.
## Tool and Test Changes
## Boundary Contracts
For tool design, follow [docs/tool-design.md](docs/tool-design.md): start from the analyst question, reuse existing contracts, preserve caller choices, and return useful evidence inline. Limits must follow real format, protocol, authority, or resource constraints. Account for representation expansion before allocation; derive completeness from examined coverage.
Treat a boundary as a contract between the producer's actual representation and the consumer's required meaning. When implementing or auditing a boundary, trace the value through parsing, normalization, authorization, serialization, and the CLI/MCP result. Establish affected callers from their code paths; similar tool names or workflows do not prove that they share a schema or failure mode.
For test changes or provider claims, use [docs/testing.md](docs/testing.md). Prefer real public CLI/MCP workflows, then production-boundary integration, then producer goldens. Keep module tests for distinct semantics stronger workflows cannot reliably reproduce. Preserve malformed-input, cancellation, cleanup, permission, capacity, and target-identity coverage when pruning. Report unverified coverage explicitly; simulated providers do not establish real-provider behavior.
When changing boundary behavior, inspect adjacent input representations, failure paths, and affected callers, and correct the underlying assumption across those cases.
Keep portable evidence and scenario validation distinct from host-native execution checks. Absolute filesystem paths, file URLs, and HTTP paths have different semantics; do not substitute one platform's syntax for the domain concept. Interpret provider metadata according to its documented or observed producer behavior. Keep values used for identity, provenance, matching, and path resolution separate from display formatting. When normalization loses information, preserve the source value and an explicit unknown; display placeholders must not feed back into lookup or selection.
Preserve meaningful failure reasons through application and adapter layers. Malformed input is distinct from an unsupported target, unavailable provider, or host operating-system permission denial. Diagnostics should identify the failed constraint and the target or lifecycle request it applies to. Recovery advice must address that reason and point to an available workflow; generic catches must not erase actionable validation details. Preserve collected observations on execution failure independently of whether cleanup succeeds.
Preserve partial native facts. A shared schema must not require one provider's full metadata before another provider can report the facts it observes. Keep observed classifications and endpoints alongside explicit unknowns for unsupported flags; never invent missing flags or discard known facts to satisfy an all-or-nothing availability shape. Before claiming a native API lacks a capability, inspect the installed API and probe representative producer objects. Exercise the resulting partial representation through CLI, MCP, and composed results such as function dossiers.
Leave meaningful target, action, capture, and output choices to the agent. A selected operation already expresses intent; do not require approval booleans or repeated permission declarations. Trace each setting to its consumer: remove ignored options and single-value confirmations, derive built-in lifecycle behavior, and supply defaults for omitted optional metadata. Report actual effects and limitations where they help interpret results rather than asking callers to restate them.
Verify the representation consumed at the next boundary. Internal validator success does not establish JSON Schema validity or client compatibility: validate advertised input and output schemas against their declared dialect after SDK conversion, and keep generated contracts aligned. Use representative producer data and regressions that exercise the failed behavior. Platform and provider support claims require the corresponding real workflow; package startup, capability probes, and mock transport tests establish only their narrower claims. Report unverified coverage explicitly.
Bind tool handlers to named contracts, preserving their exact input and output types. Catalog ordering is presentation metadata; changing that order must not select a different schema or operation for an existing handler.
## Designing MCP Tools
Start from the analyst question and desired result, not a provider API. Before adding a tool, inspect the existing contract and its nearest alternative.
Let agents compose experiments with ordinary commands, scripts, and local fixture servers. REA tools should perform the requested inspection or capture and return evidence. A custom orchestration language, replay engine, or separate prepare/execute plan needs an observed requirement that those primitives cannot satisfy. A plan-only tool without an executor does not establish runtime behavior; expose the useful inspection directly.
- Prefer reusable, composable primitives: inspect one explicit object or
relationship and return evidence that can support different analyst
questions. Compose primitives into a workflow only for a recurring outcome
that benefits from joining evidence sources; keep one-application or
business-domain interpretations out of general tool contracts.
- Use **inspect/search** tools for facts about a target or candidate set; use **trace** tools for relationships; use **compare** tools for explicitly paired inputs.
- Add a **workflow** when observed agent use shows a repeated sequence that REA can compose without losing analyst control. Return useful results inline so callers can choose their next action.
- Use **observe/capture** only when runtime activity is required, and declare authority and lifecycle effects in the contract.
- Extend an existing tool when intent and result contract are unchanged. Add a tool for a distinct analyst outcome or materially different authority.
- Keep caller-facing names and results provider-neutral. Put engine-specific behavior in provider adapters and report each provider's exact coverage.
- Keep results complete by default. Add a limit only when it follows from a real format, protocol, authority, or resource-safety constraint; explain truncation and unsupported facets. Account for representation expansion and products of independently bounded dimensions before allocating or retaining output. Derive facet completeness from what was examined and exhausted, not an empty failure list. Keep observed, derived, inferred, and unknown results distinct.
- Include artifact identity, source locations, Evidence references, actionable errors, and relevant limitations when they affect conclusions. Return the evidence needed for the next analysis inline rather than requiring a resource or identifier lookup.
- Implement shared application workflows behind CLI and MCP adapters. Update canonical contracts and generated catalog together.
See [docs/tool-design.md](docs/tool-design.md) for the design checklist. When usability or tool selection changes, evaluate representative CLI/MCP tasks as well as schema and transport behavior.
## Testing Guidelines
Prefer full end-to-end workflows through the public CLI or MCP with real providers and no mocked dependencies, then integration across production boundaries, then goldens captured from real producers. Keep a focused module test only for a distinct failure or semantic case that stronger workflows cannot reliably reproduce. Delete redundant getter, serialization, enum, count, and snapshot assertions when a stronger consumer workflow already proves the claim. Test paths, compiled imports, and suites named E2E do not establish end-to-end coverage. See [docs/testing.md](docs/testing.md) for pruning and classification rules.
Treat advertised examples as executable contracts: derive them from representative producer data, exercise them through the advertised CLI or MCP workflow, and assert the behavior they claim to demonstrate. Share production projections where practical and declare omitted coverage explicitly.
Name tests `*.test.ts`. Use Vitest and production seams (`tests/fixtures/`) rather than module mocks. Domain tests assert pure behavior; adapter tests use fake launcher/socket seams; MCP tests connect with the client SDK version pinned in `package.json`. Preserve the canonical tool inventory defined by `TOOL_CONTRACTS` and verified through `CATALOG_IDENTITY` and generated product metadata. Cover malformed input, cancellation, lifecycle cleanup, and actual format, protocol, host-permission, and target-identity boundaries. Do not add tests that merely freeze arbitrary caps or prescribed call sequences. Real Hopper, Ghidra, browser, managed conformance, and any real managed-tool claims cannot be replaced by mocks; use the corresponding `verify:*` command.
Keep tool catalogs complete and self-describing; prefer capability- and session-scoped availability over schema truncation. Serialized bytes alone do not measure agent usability or model context cost.
## Cursor Cloud specific instructions
Development requires Node.js 24.18.0 and npm 11.16.0 (`.nvmrc` and `packageManager`). The Cloud Agent image places an older `node` on `PATH` ahead of a normal install. Environment setup installs the pinned toolchain under `/usr/local` and prepends `/usr/local/bin` for login shells. Confirm `node -v` is `v24.18.0` before installing dependencies.
`npm ci` installs locked dependencies. `npm run build:cached` produces the CLI and MCP server. `npm run check:fast` is the pre-push typecheck and lint. Hopper, Ghidra, and IDA are optional bring-your-own providers. JavaScript analysis and the deterministic Vitest suites do not need them. `rea doctor` reports those engines as missing until they are configured.
## Commit & Pull Request Guidelines
Use Conventional Commit subjects because Release Please derives changelogs from them. Release Please uses `always-bump-minor`: every release increments minor, including breaking changes. Examples: `feat: add historical source import`, `fix(process): stop timers after exit`, and `docs: update architecture`. Use `!` or a `BREAKING CHANGE:` footer for breaking changes. Pull request titles must follow the same format because squash merges use the title as the release commit. Pull requests should describe contract or behavior changes, list verification commands, link issues, and include sanitized MCP examples when schemas change. State whether real Hopper/Ghidra verification was performed. Never commit binaries, Hopper or Ghidra project documents, credentials, `dist/`, `node_modules/`, or local planning artifacts (e.g. `.codex/`).
Use Conventional Commit subjects and PR titles. Mark breaking changes with `!` or a `BREAKING CHANGE:` footer. Describe behavior changes, relevant validation, and real-provider verification scope.
<!-- BEGIN:turborepo-agent-rules -->
+168
View File
@@ -1,5 +1,173 @@
# Changelog
## [6.3.0](https://github.com/morluto/rea/compare/rea-agents-6.2.0...rea-agents-6.3.0) (2026-10-09)
### ⚠ BREAKING CHANGES
* **captures:** Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected. Preserve original captures and recapture with the current producer; update comparison consumers to include every dimension rather than synthesizing missing observations. See the [process capture guide](docs/process-capture.md) and [browser scenario contract](docs/browser-scenario-contract.md). ([3283a45](https://github.com/morluto/rea/commit/3283a45d09457c79e3adadb50a48620926d4bc5b))
* **browser:** JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
* **process:** Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
* **contracts:** Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
* **javascript:** Semantic graph facts now store evidence context IDs and locations. Graph and semantic trace results require an inline evidence_contexts table.
* **contracts:** source-map URLs now live in target observations selected by declared_url_sha256, and doctor skill identity no longer emits installed_catalog_digest. Use the documented observation join and identity.skill.state instead.
* **javascript:** remove the never-incremented truncated_scopes statistic from JavaScript application analysis results and schemas.
* **native:** Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
### Features
* **setup:** register OMP during setup ([#1301](https://github.com/morluto/rea/pull/1301)) ([8b4c359](https://github.com/morluto/rea/commit/8b4c3591358ee59297d8298ede1b63d08459d817))
* **javascript:** record Electron integrity mismatches ([7915ee5](https://github.com/morluto/rea/commit/7915ee51781878ed67e094259924b6e6f3093b3f))
### Bug Fixes
* **inspector:** retain observations after capture failures ([dea3498](https://github.com/morluto/rea/commit/dea3498b2b8d919606eefc4fd62f6ebcbbe5ed30))
* **artifacts:** bind ASAR interpretation to owned snapshots ([d79317c](https://github.com/morluto/rea/commit/d79317cda0bbe8240eb7e25b0a5de90dcffca5fa))
* **artifacts:** infer legacy Mach-O simulator platforms ([5aa2002](https://github.com/morluto/rea/commit/5aa200285ab066e48b37b716495936e6e2a963fd))
* **artifacts:** preserve archive facts and Unicode path identity ([5751f5c](https://github.com/morluto/rea/commit/5751f5caac86c770123ae739a4e4101a72b0989c))
* **artifacts:** reject incomplete inventoried extraction ([5e8fb53](https://github.com/morluto/rea/commit/5e8fb531e255a4a04fc053c54096f66d5c84cde3))
* **artifacts:** retain DMG ownership through uncertain attachment ([a27794c](https://github.com/morluto/rea/commit/a27794c246b3f11d7f92ae7f6d276718190ab731))
* **artifacts:** validate only active extraction entries ([cfb12e4](https://github.com/morluto/rea/commit/cfb12e47dc241f057be93a00892f7d7361d6119d))
* **browser:** follow only HTTP redirect statuses for source maps ([82bbe74](https://github.com/morluto/rea/commit/82bbe743336244d398e67512659ea6943d43a4a4))
* **browser:** preserve payload shapes and WebMCP declarations ([4951a89](https://github.com/morluto/rea/commit/4951a897c53bb6882300c5d7a9660a3f43e374f5))
* **browser:** release attached viewport overrides without resizing the external page ([f6cfbfc](https://github.com/morluto/rea/commit/f6cfbfcc554ff24173dd7ad5333e8e26ab9c962d))
* **browser:** retain attached scenario emulation until cleanup ([a0523b3](https://github.com/morluto/rea/commit/a0523b375eb3147f1d2d1e7eb10a2f4546f5d0fc))
* **browser:** retain malformed redirect diagnostics ([617cd84](https://github.com/morluto/rea/commit/617cd84d27d100e7cc3cd4b5721dea4a996c9775))
* **browser:** serialize attached scenarios through cleanup settlement ([cfce91d](https://github.com/morluto/rea/commit/cfce91d418fbcde4a9ef283a61549279751854e7))
* **ci:** scope verification and reuse native runners ([#1344](https://github.com/morluto/rea/issues/1344)) ([d5cb8ae](https://github.com/morluto/rea/commit/d5cb8aee063065a48233458e04771635167825c8))
* **cli:** avoid duplicate primary cleanup diagnostics ([37fcea7](https://github.com/morluto/rea/commit/37fcea78cecbeeadd869e9a3d77dd133ed264a0a))
* **cli:** classify JSON input permission denials ([08daf05](https://github.com/morluto/rea/commit/08daf056cc8e4d092f9592574d09d5182457b7bc))
* **cli:** classify oversized JSON inputs ([f7cf4c8](https://github.com/morluto/rea/commit/f7cf4c890d4b9c70b1f56e6c627b44a59e58fd73))
* **cli:** stream JSON inputs beyond the whole-document string limit ([#1360](https://github.com/morluto/rea/issues/1360)) ([6ce3288](https://github.com/morluto/rea/commit/6ce3288f3bd65a886e47905455ed5c9b661015e6)), closes [#1331](https://github.com/morluto/rea/issues/1331)
* **cli:** stream JSON results at the shared command boundary ([810107a](https://github.com/morluto/rea/commit/810107a2ad15cc52afd6662aec24d231d8c77225))
* **contracts:** advertise NUL with a portable hex escape ([3f59a84](https://github.com/morluto/rea/commit/3f59a84bd1039763bb349894542601ed78be2033)), closes [#1329](https://github.com/morluto/rea/issues/1329)
* **contracts:** require observed provider output metadata ([a4ba8ae](https://github.com/morluto/rea/commit/a4ba8aecd507637b6261026afc17f79516840d50))
* **electron:** preserve unrepresentable numeric option evidence ([41a228c](https://github.com/morluto/rea/commit/41a228c1b01a89127858b1706879ede08a81deaf))
* **evidence:** order canonical projections independently of locale ([614fb76](https://github.com/morluto/rea/commit/614fb7681ee9e4eba7219c1ee9e90d6a85d78095))
* **files:** reject nonregular capture and JSON inputs ([5f16124](https://github.com/morluto/rea/commit/5f16124a31fa4a82bd03037506809d6be959d768))
* **filesystem:** reject unstable artifact targets ([7829b1a](https://github.com/morluto/rea/commit/7829b1aeef8f43f186be2d2adbd6c67541306a7a))
* **ghidra:** reject a native decompiler built for another host ([#1280](https://github.com/morluto/rea/issues/1280)) ([3728c82](https://github.com/morluto/rea/commit/3728c8267b4fb6da78cbae42a2a6cbddff80ea84)), closes [#1192](https://github.com/morluto/rea/issues/1192)
* **ghidra:** retain process ownership after failed launch rollback ([07675f7](https://github.com/morluto/rea/commit/07675f78c66ce9e8706e808d417265e18ba9f3a5))
* **ghidra:** verify dense jump tables on an optimized fixture ([#1374](https://github.com/morluto/rea/issues/1374)) ([73a664b](https://github.com/morluto/rea/commit/73a664bc78ee618045a2733b8714821281f77403))
* **hopper:** allow restart after verified owned-provider shutdown ([1c12349](https://github.com/morluto/rea/commit/1c123493a21cc579ba7532c40e7ef30df45db3e8))
* **hopper:** probe interior navigation from multi-byte instructions ([#1285](https://github.com/morluto/rea/issues/1285)) ([bf934d5](https://github.com/morluto/rea/commit/bf934d5592e707ba5e7769043de3a430ed8d4923))
* **ida:** compare admitted document paths consistently ([890bb66](https://github.com/morluto/rea/commit/890bb66b35d5f9f8ee54ff0049bf7dc7b82b2480))
* **javascript:** avoid positive-zero evidence for signed zero ([9055bd6](https://github.com/morluto/rea/commit/9055bd695b75f72fb1b8a538d1485d30c0b0ee0b))
* **javascript:** decline source-map UNC references with an unusable host ([#1372](https://github.com/morluto/rea/issues/1372)) ([f504c2a](https://github.com/morluto/rea/commit/f504c2a351027f17ac353fba2d7cfc3505ee17d6))
* **javascript:** distinguish prefix-only builtins from packages ([2b4abbf](https://github.com/morluto/rea/commit/2b4abbf1ccb6dd6ad1248cf48e381df0842542c1))
* **javascript:** honor module-sync package exports ([#1361](https://github.com/morluto/rea/issues/1361)) ([d0e6069](https://github.com/morluto/rea/commit/d0e606930acb701790c286340226b1e3e7060b4f))
* **javascript:** parse declaration artifacts in ambient mode ([4896adc](https://github.com/morluto/rea/commit/4896adcd0f9316034e83129685ed3807ade6f3ea))
* **javascript:** preserve agreeing module provenance ([db171be](https://github.com/morluto/rea/commit/db171be6e570fd1261a30d711e4da2d17de85a93))
* **javascript:** preserve capture-time guards and ordering ([001851f](https://github.com/morluto/rea/commit/001851fde6f972e6ebd01fddccdff4c645a85f63))
* **javascript:** preserve semantic evidence through satisfies ([e995b19](https://github.com/morluto/rea/commit/e995b19f834ba78faa294f5959fd3ad8a97290ca))
* **javascript:** preserve uncertainty after references escape to calls ([#1292](https://github.com/morluto/rea/issues/1292)) ([355a292](https://github.com/morluto/rea/commit/355a292198bf58245c67ae315fdb4f77e62769cc))
* **javascript:** reject invalid package exports configurations ([7a4f268](https://github.com/morluto/rea/commit/7a4f2685d41b134507331c322f0f5da8e1f6c3f4))
* **javascript:** resolve exported callables through lexical bindings ([#1351](https://github.com/morluto/rea/issues/1351)) ([a9f5dad](https://github.com/morluto/rea/commit/a9f5dad5a8f196c88f6305d8d958b355cc0b52c2))
* **javascript:** resolve query-only HTML references to their document ([55a46f7](https://github.com/morluto/rea/commit/55a46f7c7176075c9edda4fe61ed995f2ceadf6a))
* **javascript:** retain array identity after length mutations ([4bcea1a](https://github.com/morluto/rea/commit/4bcea1aa76e3e7ca665197181739c5e27a62c40a))
* **javascript:** retain conditional mutation ordering uncertainty ([b8a8190](https://github.com/morluto/rea/commit/b8a8190b2f30e377eee2d69d1ba31ea454fa70b9))
* **javascript:** retain distinct module provenance path components ([2bd7de6](https://github.com/morluto/rea/commit/2bd7de6f8ca62fc1d48334cfa7fdced461b7b153))
* **javascript:** retain unresolved value frontiers in provenance queries ([3e19875](https://github.com/morluto/rea/commit/3e19875c7fa9c61cff655bbe6046ddc4ab558533))
* **javascript:** store source map URLs once ([ed8fcae](https://github.com/morluto/rea/commit/ed8fcae94b699b62b44162f880faa077a36c455d))
* **json:** preserve runtime limits across JSON file readers ([#1350](https://github.com/morluto/rea/issues/1350)) ([9c4a68b](https://github.com/morluto/rea/commit/9c4a68bc19a0f7d39557e3cc039f5877f6550f63))
* **managed:** bind graph facts to their source Evidence ([cc7b5af](https://github.com/morluto/rea/commit/cc7b5af0777fc68ebba10ec061244729ebf2357d))
* **mcp:** admit composed analysis through result bookkeeping ([e11f4d3](https://github.com/morluto/rea/commit/e11f4d371abaa8cb65ebf7b94fa216329fd78d88))
* **mcp:** advertise object roots for union input schemas ([#1373](https://github.com/morluto/rea/issues/1373)) ([39dabd0](https://github.com/morluto/rea/commit/39dabd0608ed9617d60f16ece05993089f24ff38))
* **mcp:** advertise primitive semantic literal seeds ([f62b449](https://github.com/morluto/rea/commit/f62b44971deee0e99df6fcf32758c8e5592400ed))
* **mcp:** preserve JavaScript workflow identity validation ([#1366](https://github.com/morluto/rea/issues/1366)) ([53ed942](https://github.com/morluto/rea/commit/53ed942a85f51ff9f0e4f01cbb53359df476071d)), closes [#1364](https://github.com/morluto/rea/issues/1364) [#1065](https://github.com/morluto/rea/issues/1065)
* **mcp:** retry failed shutdown resources and retain failure reasons ([e64678e](https://github.com/morluto/rea/commit/e64678e8f9768dd819d8f5f12cc844a6660ff2c5))
* **native:** distinguish symbol definitions from metadata ([70bad53](https://github.com/morluto/rea/commit/70bad53847b0e14489acee73d204ff645e1adfcd))
* **native:** preserve unknown Objective-C metadata ([b112d44](https://github.com/morluto/rea/commit/b112d44a3961939881779c81a57e7a3f9d1372f7))
* **native:** refuse to list architectures of non-Mach-O targets ([#1325](https://github.com/morluto/rea/issues/1325)) ([1b73b5a](https://github.com/morluto/rea/commit/1b73b5ab4bc75bd424e643de8e49f142ffa2b336))
* **native:** retain LLDB cleanup ownership through client close ([7ad353f](https://github.com/morluto/rea/commit/7ad353fa8b3f07e14face80336678d23cc7c6507))
* **process:** keep unobserved file contents unknown ([#1358](https://github.com/morluto/rea/issues/1358)) ([f91f279](https://github.com/morluto/rea/commit/f91f2798b4dc6adb61b3ffe28a24a5d55adbd6ff))
* **process:** retain per-file digest open failures ([415145d](https://github.com/morluto/rea/commit/415145d04f09a15cbfb7dda8ea9dc363a77f9bf0))
* **reference:** report malformed UTF-8 before import parsing ([f166a2a](https://github.com/morluto/rea/commit/f166a2ae15b072216173a51a8f5cad930a858366))
* report malformed application evidence as input errors ([218c131](https://github.com/morluto/rea/commit/218c13160ec0ed7116d6633fc76559ec39dae4d7))
* retain completed observations when later analysis steps fail ([35f121f](https://github.com/morluto/rea/commit/35f121f4acac821e848c485fb82a2c42f51f6ea1))
* **setup:** install the skill for Claude Code ([b4a1919](https://github.com/morluto/rea/commit/b4a19193fe3baf9075f8ac419517021ea0c71ea3))
* **setup:** recognize supported Nobara hosts ([f0dc233](https://github.com/morluto/rea/commit/f0dc233d64de4c215c453c346e516b7622713e95))
* **skill:** pin packaged commands to the shipping package version ([2793672](https://github.com/morluto/rea/commit/2793672ee2a575f97a8011c7fec5288098cdd5d1))
* **skill:** pin packaged commands to the shipping package version ([#1346](https://github.com/morluto/rea/issues/1346)) ([f39e71c](https://github.com/morluto/rea/commit/f39e71ce1897bb5c704b33a8b0049567f11e3a13))
* **snapshot:** preserve complete investigation revision histories ([#1354](https://github.com/morluto/rea/issues/1354)) ([1c0cc8a](https://github.com/morluto/rea/commit/1c0cc8a6753b5ac781b28ebb1832f3a6a1771a68))
* **targets:** cancel resolution before provider admission ([f3c4a33](https://github.com/morluto/rea/commit/f3c4a332f7bd198bd67f0187bc2a85c7b31bb960))
* **update:** preserve disabled client registrations ([abf5e24](https://github.com/morluto/rea/commit/abf5e243c4d2cae03404b6e1fb1ccc77be917b53))
### Performance Improvements
* **javascript:** index version relationships once per comparison ([#1347](https://github.com/morluto/rea/issues/1347)) ([b1e85ad](https://github.com/morluto/rea/commit/b1e85ad711743a594c572dbd5b0d5cb664e2a502))
* **javascript:** validate the version change graph once ([#1370](https://github.com/morluto/rea/issues/1370)) ([037709a](https://github.com/morluto/rea/commit/037709a52c0824f4d2bbee90d8e2642b2d88d364))
* **json:** encode streamed JSON iteratively ([#1322](https://github.com/morluto/rea/issues/1322)) ([56598be](https://github.com/morluto/rea/commit/56598beb4e82968a313deb9efdf4b98db5bd1f4f))
### Code Refactoring
* use canonical implementations and types directly ([765e809](https://github.com/morluto/rea/commit/765e809e366eff21b4b9c224f1a813ad64245ea3))
* **artifacts:** remove unused root classifier ([5291bca](https://github.com/morluto/rea/commit/5291bca108af781214572fac709f9808bb8aa4db))
* **artifacts:** test inventory changes at materialization boundary ([750fb65](https://github.com/morluto/rea/commit/750fb6565052e9eaad40b946b6a284d0730d14f8))
* **browser:** open scenario sessions without a factory wrapper ([d1983a4](https://github.com/morluto/rea/commit/d1983a45767bfcdc020652f48109a78a3f9fa590))
* **catalog:** import CLI metadata from its owner ([8c96baa](https://github.com/morluto/rea/commit/8c96baab80dc258d31ca1632d761fffb11dbaaae))
* consolidate boundary semantics and prune redundant tests ([392f1f3](https://github.com/morluto/rea/commit/392f1f310733f2c365da7bc57a1154cf10ec4ba0))
* **javascript:** normalize erased expression syntax once ([b628bba](https://github.com/morluto/rea/commit/b628bba1fa65fd3b51363bf4b745f0afc57e1dba))
* **javascript:** parse runtime evidence into one verified owner ([006b295](https://github.com/morluto/rea/commit/006b295f1de19fd5351832cf52d98a202a5cd5cd))
* **javascript:** remove obsolete scope truncation statistic ([449d570](https://github.com/morluto/rea/commit/449d57075eec71b2f064af8877c50cbbde30a283))
* **javascript:** share Babel child traversal ([0f10499](https://github.com/morluto/rea/commit/0f10499245ec2fab8823f116caf34450b3a7385b))
* **javascript:** share semantic evidence at fact construction ([e3bbb9a](https://github.com/morluto/rea/commit/e3bbb9ac453da8d15f3b32511180451613710616))
* **process:** remove duplicate observation and trace entry points ([070339a](https://github.com/morluto/rea/commit/070339af50a50a0f23e82db859e761c53277ee79))
* **providers:** use canonical artifact and managed identities ([87f0051](https://github.com/morluto/rea/commit/87f0051496aff1b05ab24d6b63f79884f4ca9b8f))
* **reference:** simplify malformed UTF-8 handling ([377df71](https://github.com/morluto/rea/commit/377df715ea5b2523cd6c1084fdc286eb8a056182))
* remove obsolete source exclusions and identity wrapper ([44c92f8](https://github.com/morluto/rea/commit/44c92f88c51841735741811a68cc89fde14efa80))
* remove single-use forwarding helpers ([4144e45](https://github.com/morluto/rea/commit/4144e454f385c372d29e301e6bb959092c606a6e))
### Documentation
* keep license sections text-only ([e10f1f0](https://github.com/morluto/rea/commit/e10f1f0901fa56fb4443837cf9528b31a12e140e))
* align translated README artwork and layout ([ccfbe87](https://github.com/morluto/rea/commit/ccfbe87e984e456e12c66d0d2fe6d5a559d09518))
* add README artwork and refine closing sections ([4b8e744](https://github.com/morluto/rea/commit/4b8e744d90579e353371649047215c4e4be7a5f6))
* add repository-local REA tool design skill ([7738c1f](https://github.com/morluto/rea/commit/7738c1f6a9ccf1ec9868ef832f154abe9ba5eebd))
* celebrate 40,000 GitHub stars 🎉 ([3edb217](https://github.com/morluto/rea/commit/3edb2172def0e0bd9076f23148f0c41cd2f341a3))
* celebrate 40,000 GitHub stars 🎉 ([5ecc98a](https://github.com/morluto/rea/commit/5ecc98a5eac4c10d33e9c418b9ffae61c68e3ef2))
* consolidate agent guidance around ownership and boundaries ([ba44222](https://github.com/morluto/rea/commit/ba4422296dc409d49836f25642555e00463bfe3b))
* **contracts:** explain canonical URL and skill metadata ownership ([e36afa1](https://github.com/morluto/rea/commit/e36afa112fd7b7ab5a925ca452de93b68f12a6ab))
* correct MCP error and capture import guidance ([077d6c4](https://github.com/morluto/rea/commit/077d6c407b3ea7443a7277ae0e5531b3927dd742))
* correct README setup and runtime guidance ([5b3715e](https://github.com/morluto/rea/commit/5b3715ef825a30150b02d3f1bb7d40dd89453018))
* explain CI scope and native runner reuse ([#1348](https://github.com/morluto/rea/issues/1348)) ([6c9161d](https://github.com/morluto/rea/commit/6c9161d61745e242643f224ce49e7468143a15f3))
* prune repeated contributor and tool design instructions ([5d79387](https://github.com/morluto/rea/commit/5d79387505ebae1ec8d800ee3ffd901920a9d8be))
* remove retired architecture and migration artifacts ([7a0c800](https://github.com/morluto/rea/commit/7a0c80085128e6329ca2e4f54f3539f3245c57d1))
### Tests
* share the client registration command to restore the jscpd gate ([#1317](https://github.com/morluto/rea/pull/1317)) ([5d16be2](https://github.com/morluto/rea/commit/5d16be2a7185db8b70a5fcbc5f5e1be63297f2c8))
* **mcp:** remove arbitrary schema inventory thresholds ([24673aa](https://github.com/morluto/rea/commit/24673aaae497ca4ef0902544c0cd69817f5424ed))
* **android:** allow provider readiness under load ([961c3c3](https://github.com/morluto/rea/commit/961c3c3de79ec44d608d011eb3fa3d6bd645cf6a))
* **artifacts:** verify extraction races with real filesystem changes ([1ac8389](https://github.com/morluto/rea/commit/1ac8389c5c1f75faf8d7f2f3faf2f24febad5fea))
* **browser:** avoid duplicating source-map listener setup ([9367dc1](https://github.com/morluto/rea/commit/9367dc13bd8d2732d36d5376b5de170c9f4af424))
* **browser:** report redirect status cases independently ([5a61562](https://github.com/morluto/rea/commit/5a61562dc200120c7b8020854085c17b8203e95d))
* **cli:** remove duplicate malformed JSON assertion ([5d32e42](https://github.com/morluto/rea/commit/5d32e4252941e93065cadd83b9f02aa6427544d8))
* exercise source test selection through Git and Vitest ([25711ad](https://github.com/morluto/rea/commit/25711ad2590af136dfb301839dddd6d30971ba76))
* **filesystem:** bound FIFO regressions at consumers ([0bfb6e0](https://github.com/morluto/rea/commit/0bfb6e00abae1e67a96e548d64954bb21861f621))
* **ghidra:** allow rollback tests to reach spawned process ([d761d73](https://github.com/morluto/rea/commit/d761d7358b45fe0724b182a206241fd605f338b0))
* **javascript:** share primitive expansion producer fixtures ([c867bcd](https://github.com/morluto/rea/commit/c867bcd0aadd63473865f9a328459e0db3c89565))
* **javascript:** share semantic graph test facts ([ac356c4](https://github.com/morluto/rea/commit/ac356c46ad6a17c8864bc5d350984786db62d2f5))
* **javascript:** verify distinct module origins through reconstruction ([96b2b24](https://github.com/morluto/rea/commit/96b2b245fdefc9c78f5dcf6ce054232b51f7c117))
* **json:** remove assertions covered by CLI output consumers ([a959a83](https://github.com/morluto/rea/commit/a959a8309db79fbee6477efd7ee541615e625627))
* **managed:** include shared dossier fixture in artifact inputs ([66a20a2](https://github.com/morluto/rea/commit/66a20a2597b5daebc0a292361aa62a78b7df6e7d))
* **native:** retain trace diagnostics when observed hits differ ([048b798](https://github.com/morluto/rea/commit/048b79878c70c594789909082499dc675472b63a))
* **package:** share validated native dossier fixtures ([ca90109](https://github.com/morluto/rea/commit/ca9010936a934a49fbc6cf69eb1d7fc2242b6da9))
* **process:** publish capture readiness atomically ([74be526](https://github.com/morluto/rea/commit/74be52611e66f680ef1919d521fc3c304bc2326e))
* **process:** report cleanup details on cancellation failures ([79d5b9a](https://github.com/morluto/rea/commit/79d5b9a826b9204c1ef59b0a5c5ec83e7a2f2bec))
* **process:** use owned CLI and workspace fixtures ([4940a86](https://github.com/morluto/rea/commit/4940a867e2e56cbb974bfa321008a8f35db47d52))
* share snapshot replay and managed graph fixtures ([d83cbd2](https://github.com/morluto/rea/commit/d83cbd2abf1bbf15beef990f5353457fdbaaeb8e))
### Continuous Integration
* enforce architecture guards with portable checkout paths ([ecc67ca](https://github.com/morluto/rea/commit/ecc67cab2d85cacda245890ffe84b80ac395d79e))
## [6.2.0](https://github.com/morluto/rea/compare/rea-agents-6.1.0...rea-agents-6.2.0) (2026-10-09)
+76 -114
View File
@@ -1,39 +1,30 @@
# Contributing to REA
REA welcomes focused bug fixes, documentation improvements, tests, and reverse-engineering workflow enhancements. Open an issue before a large contract or architecture change so its scope can be agreed before implementation.
REA welcomes focused bug fixes, documentation improvements, tests, and reverse-engineering workflows. For large contract or architecture changes, explain the intended scope and link the relevant issue or design discussion.
## Choosing a contribution
Small contributions are welcome when they solve a concrete problem, including
broken commands, misleading documentation, and missing regression coverage.
Explain the problem, keep the diff focused, and share how you checked the change.
Explain the concrete problem, keep related corrections together, and report
verification and unavailable coverage. Contributions should justify their review
and maintenance cost. Keep cosmetic polish with useful fixes; confusing or
incorrect user instructions warrant standalone corrections. Collect other
cosmetic-only suggestions in an issue rather than separate PRs.
Please avoid standalone cosmetic changes without a clear benefit, such as fixing
a typo in an internal comment, changing capitalization or punctuation in
already-clear prose, or reformatting unchanged code. Include related polish in a
useful fix when practical. For cosmetic-only suggestions, please open an issue
instead of a standalone PR so they can be collected and addressed together.
Corrections to confusing explanations or incorrect instructions are welcome.
Avoid speculative cleanup without a concrete problem to solve. Keep related
corrections in one PR.
Before requesting review, read the final diff and run the relevant checks. Be clear
about anything you couldn't test. You should be able to explain the changes you
submit.
We may decline changes when the benefit doesn't justify the review or maintenance
work.
For capability organization and provider composition, follow the incremental
[migration guide](docs/capability-migration.md). Run `npm run verify:test-discovery`
after adding or moving tests.
For capability organization and provider composition, use the
[architecture map](docs/architecture.mermaid). Production factories in
`src/composition/` construct fresh providers without starting engines or acquiring
targets; optional adapter failures must preserve successful peers. Run
`npm run verify:test-discovery` after adding or moving tests. Resolved import
boundaries are checked by `npm run verify:module-boundaries`, included in lint.
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
## Development setup
REA development requires Node.js 24.18.x and npm 11.16.x (pinned toolchain via `nvm use`; the supported runtime range is Node.js ^22.19 || ^24.11 || >=26, as the README badge states). Real-Hopper verification additionally requires either macOS 12+ or an officially supported Linux host (Ubuntu 24.04+, Fedora 41+, 64-bit Arch, or CachyOS) and an installed Hopper application. Linux demo verification uses its own private Xvfb display and does not require a desktop session. Run `nvm use` before installing dependencies.
Use the development toolchain pinned in `.nvmrc` and
`package.json#packageManager`. Run `nvm use` before installing dependencies;
installed-package runtime support is documented in
[installation](docs/installation.md#start-setup).
```bash
npm ci
@@ -48,7 +39,8 @@ catalogs, documentation projections, or managed verification evidence. Turbo
caches deterministic builds and static checks across Git worktrees. After a package, lockfile, or managed-skill version change, run
`npm run metadata:generate` before building.
Keep dependencies flowing inward through the existing domain, contracts, provider, application, server, and adapter layers. Parse unknown values at process and protocol boundaries, model expected failures with `Result`, and preserve the canonical tool inventory defined by `TOOL_CONTRACTS` unless a deliberate contract change updates every verifier, generated catalog artifact, and snapshot. Keep tool discovery complete and report capability- and session-scoped availability through `binary_session`.
Repository invariants live in [AGENTS.md](AGENTS.md). Keep provider-specific
protocols in adapters and shared CLI/MCP workflows in the application layer.
## Documentation website
@@ -74,112 +66,82 @@ The separate GitHub Pages host uses only the manual
## Development feedback and PR verification
For an ordinary edit, run the relevant regression and cached static checks:
Select checks for the behavior changed. For a source edit:
```bash
npm run test:focused -- src/config.test.ts
npm run check:fast
```
`test:local` selects dirty source tests without building; explicit source test
paths run even on a clean tree. `check:changed` adds source tests affected since
the branch merge base with `origin/main`. Use `npm run test:changed -- --base
REVISION` to choose another base. Changed-test selection follows the import
graph and is feedback, not complete correctness evidence. Inspect relevant
boundary and provider behavior explicitly; see [docs/testing.md](docs/testing.md).
`test:local` runs source tests without building. `check:changed` combines cached
static checks with source tests affected since the merge base with `origin/main`.
Import-graph selection can miss runtime registration, bridges, and generated data;
select relevant boundary tests explicitly. See [testing](docs/testing.md#developer-commands)
for commands, test placement, pruning, and real-provider prerequisites.
Before handing off a PR, run the relevant tests, `npm run check`, and
`npm run docs:check` when contracts or generated metadata change. Record which
checks ran. CI owns complete deterministic tests and aggregate coverage. Use
`npm run check:pr` for a deliberate full local gate on broad changes or when
investigating CI failures; it is not required after each edit, rebase, or push.
Packaging, setup, installation, or distribution changes also require
`npm run verify:package` and `npm pack --dry-run`. Provider behavior changes
require the matching real-provider `verify:*` lane.
Before requesting review, run relevant tests and `npm run check`; add
`npm run docs:check` when contracts or generated metadata change. Record the
checks and unavailable coverage. CI owns the full deterministic suite and
coverage. `npm run check:pr` is an optional full local gate for broad changes or
CI diagnosis. Packaging/setup/distribution changes additionally require
`npm run verify:package` and `npm pack --dry-run`; provider changes require the
matching real-provider lane. State which host/provider workflows ran.
`check:fast` runs cached source/test typecheck and lint without compiling or
running generators. `npm run test:prepare` prepares all artifacts consumed by
the complete suite; focused tests prepare only their runtime and declared
artifact dependencies. The test-only MCP catalog lives at
`.cache/mcp-tool-catalog.json` and can be regenerated independently with
`npm run mcp-catalog:generate`.
Pre-commit formats and lints staged files; pre-push runs `check:fast`.
Build and generation commands hold one SQLite exclusive transaction around
their whole Turbo graph, including cache restoration. The persistent database
in `.cache/rea-command-locks/` is a lock identity, not a stale-file marker;
the operating system releases ownership when the command supervisor exits.
On POSIX, that supervisor retains the transaction and process-group identity
through cancellation, including loss of its parent runner. Windows cancellation
waits for the command to complete. Do not remove the database while commands
are running.
### Generated files and command ownership
`check` adds formatting, dead-code, and package-metadata freshness checks.
Formatting uses Oxfmt and the committed `.oxfmtrc.json`; generated sources use
the same configuration. Pre-commit formats and lints staged files; pre-push runs
`check:fast`.
`docs:check` builds and validates generated metadata for the current checkout.
The product catalog (`docs/public/product-catalog.json`), portable managed
conformance projections (`docs/verification/managed-conformance-*.json`), and
packaged skill (`skills/`) are ignored generated outputs. `docs:generate`
prepares documentation and managed evidence; `evidence:generate` prepares only
the managed commitment and its runtime/skill dependencies. Edit skill
instructions and references in `skill-src/`; the skill task adds metadata to
the packaged copy without rewriting authored files. The generated manifest
commits to that exact packaged skill bundle. It is a portable projection of
the deterministic managed verifier, not a record of optional real-provider runs.
CI validates these outputs and retains them as artifacts instead of pushing
generated-only commits onto feature branches. Reviewed source metadata such as
`src/generatedPackageMetadata.ts` and `docs/error-contract.schema.json` remains
tracked and checked for freshness. Do not commit ignored generated outputs.
The build-generated product catalog contains documented facts and their provider
identity, rather than full runtime schema hashes. The managed skill contains
instructions and inventory metadata; doctor compares its installed files with
the canonical bundle. Schema-only fixes should not change these outputs or the
skill commitment in the conformance manifest. Runtime schema identity remains
available through doctor and `binary_session`.
Real-provider execution remains uncached; deterministic builds use Turbo.
`docs:generate` prepares documentation and portable managed evidence;
`evidence:generate` prepares only the managed commitment and its runtime/skill
dependencies. The ignored outputs are `docs/public/product-catalog.json`,
`docs/verification/managed-conformance-*.json`, and `skills/`. Edit authored
skill instructions in `.agents/skills/reverse-engineer-anything/`, where Skills
can discover the public bundle directly from a clean checkout. `verify:package`
installs that bundle with Skills 1.7.2 using default repository-root discovery
and checks every installed file, alongside the packaged setup checks.
CI validates generated outputs and retains them as artifacts; do not commit
them. Reviewed source metadata, including
`src/generatedPackageMetadata.ts` and `docs/error-contract.schema.json`, remains
tracked and checked for freshness.
Local `npm test` runs every deterministic Vitest project without coverage or
retries. CI runs four coverage shards and merges JUnit and timing reports.
CI cancels superseded PR runs and skips package, Windows, and full test lanes
for documentation-only PRs. Coverage thresholds remain in `vitest.config.ts`.
The packaged skill contains instructions and inventory metadata, not runtime
schema hashes. Its conformance commitment covers that exact bundle and portable
verification; it does not attest optional real-provider runs. Schema-only changes
should not alter that commitment. Doctor and `binary_session` expose runtime
schema identity.
Tests that need a temporary directory must use
`createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`. The
helper binds exact-path, awaited cleanup to the current Vitest case, including
failure and timeout completion. Run `npm run verify:test-temp-hygiene` to build
REA, execute the complete suite under a fresh `TMPDIR`, and reject any remaining
REA-owned temporary path. Never add a glob cleanup for shared `/tmp/rea-*`
content.
Build/generation commands hold a SQLite transaction around the entire Turbo
graph, including cache restoration. `.cache/rea-command-locks/` databases identify
locks, not stale files; never remove them while commands run. POSIX cancellation
retains process-group ownership until settlement; Windows waits for completion.
Real-provider execution is uncached.
Set `REA_LOG_LEVEL` to `trace`, `debug`, `info`, `warn`, `error`, `fatal`, or
`silent` to control structured JSON diagnostics. MCP mode defaults to `info` and
always writes logs to stderr so the stdio protocol remains intact. One-shot CLI
logging is opt-in and writes to stdout when a level is configured, preserving
machine-readable command output by default. Request arguments, bridge
authentication tokens, and environment data are redacted.
### Temporary files and diagnostics
Changes that claim real Hopper behavior must also be tested against the
source-owned, digest-bound conformance manifest. The verifier builds the
platform-native fixtures before starting Hopper:
Tests use `createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`
for exact-path, awaited cleanup, including failures and timeouts.
`npm run verify:test-temp-hygiene` runs the suite under a fresh `TMPDIR` and
rejects remaining REA-owned paths. Never glob-clean shared `/tmp/rea-*` content.
```bash
npm run verify:hopper
```
`REA_LOG_LEVEL` selects `trace`, `debug`, `info`, `warn`, `error`, `fatal`, or
`silent`. Logs go to stderr: MCP defaults to `info`, and one-shot CLI logging
is opt-in, so stdout carries only protocol messages and command results.
Request arguments, bridge tokens, and environment data are redacted from
diagnostic logs.
On a self-hosted Linux runner with the setup-installed Xvfb dependencies, use:
## Real Hopper changes
```bash
npm run verify:hopper:linux
```
Run `npm run verify:hopper` on a supported macOS host or
`npm run verify:hopper:linux` on the supported Linux demo runner. These build
native fixtures and verify the installed engine through CLI/MCP; package or
simulated-provider checks do not establish engine behavior. See
[real-toolchain verification](docs/testing.md#end-to-end-integration-and-golden-evidence)
for prerequisites and scope, and [Hopper setup](docs/installation.md#hopper)
for supported hosts and unattended startup.
Set `REA_HOPPER_CONFORMANCE_MANIFEST_PATH` only to verify another source-built
manifest. The normal commands use `build/conformance/manifest.json`; generated
fixtures and manifests remain ignored and must not be committed.
The macOS and Linux real-Hopper workflows remain separate so a successful mock or package test cannot be reported as platform-runtime proof. Pull requests changing setup, launch, bridge, or Hopper behavior must state which real workflows ran and why either workflow was unavailable.
Describe the behavior change and verification performed in the pull request. Never commit binaries, Hopper documents, credentials, `dist/`, `node_modules/`, or local planning artifacts.
Use the default `build/conformance/manifest.json` unless explicitly verifying
another source-built manifest with `REA_HOPPER_CONFORMANCE_MANIFEST_PATH`.
Generated fixtures and manifests remain ignored.
## Maintainer release checklist
+24 -23
View File
@@ -1,6 +1,6 @@
<div align="center">
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#what-you-can-analyze)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA launching its analysis bridge inside Hopper while inspecting a native binary" width="1200" />
<br />
<br /><br />
<table aria-label="REA community">
<tr>
@@ -52,7 +52,7 @@ See a feature in an app that you want in your own product? Ask your agent to inv
REA connects your agent to tools for inspecting native binaries, JavaScript and Electron apps, .NET assemblies, and websites. You can also use the same tools from your terminal. Analysis runs locally, and results include the evidence and limitations behind each conclusion.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper or Ghidra installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs neither engine.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper, Ghidra, or IDA installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs no native analysis engine.
> **[Visit the REA website](https://rea.tools/)** for setup instructions, illustrated guides, and real case studies.
@@ -151,13 +151,16 @@ Additional tools and host support depend on the target:
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://rea.tools/guides/native/) |
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier; [offline EVM guide](docs/evm-bytecode.md) |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | Static inspection; [managed-code guide](docs/managed-code-analysis.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
@@ -181,6 +184,8 @@ for features added since the latest npm release.
## Showcases
[![Illustrations of the DX-Ball sound-pan, Notion clipboard-bridge, and TH04 bullet-ring showcases](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruct a sound-pan calculation
Follow a sound call into its position-to-pan helper, inspect the instructions,
@@ -243,7 +248,7 @@ ask you to choose demo mode or activate your license. See
<details>
<summary><strong>What does installing the skill from skills.sh do?</strong></summary>
The skill supplies investigation instructions for your agent. Use `rea setup`
The skill supplies investigation instructions for your agent. Use `npx rea-agents setup`
to register REA's MCP server and install the matching instructions, then restart
your agent. See [skill-only installation](docs/installation.md#skill-only-installation).
@@ -303,23 +308,9 @@ For exact options, prerequisites and result contracts:
Report vulnerabilities through [SECURITY.md](SECURITY.md).
## Contributing
We'd love your help with REA! [Open an issue](https://github.com/morluto/rea/issues) to
report a bug or suggest a feature, or [send a pull request](https://github.com/morluto/rea/pulls)
to improve the code or docs.
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
[testing](docs/testing.md) for verification lanes, and the
[architecture map](docs/architecture.mermaid) for the project structure.
## Project links
[Website](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Security](SECURITY.md)
## Star history
🎉 **30,000 GitHub stars — thank you!**
🎉 **60,000 GitHub stars — thank you!**
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
@@ -337,6 +328,16 @@ REA provides tools for lawful reverse-engineering research, analysis, and recons
REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
## Contributing
We'd love your help with REA! [Open an issue](https://github.com/morluto/rea/issues) to
report a bug or suggest a feature, or [send a pull request](https://github.com/morluto/rea/pulls)
to improve the code or docs.
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
[testing](docs/testing.md) for verification lanes, and the
[architecture map](docs/architecture.mermaid) for the project structure.
## License
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: هندسة عكسية لأي شيء
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA يشغّل جسر التحليل داخل Hopper لفحص ملف ثنائي للشيفرة الأصلية" width="1200" />
<br />
<br /><br />
<table aria-label="مجتمع REA">
<tr>
@@ -135,13 +135,16 @@ npx rea-agents@latest setup
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](https://rea.tools/guides/native/) |
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](docs/binary-diagnostics.md) |
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](https://rea.tools/guides/javascript/) |
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](https://rea.tools/guides/browser/) |
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](docs/web-network-captures.md) |
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](docs/managed-code-analysis.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS؛ [دليل Android](docs/android-analysis.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](docs/android-analysis.md) |
| أجهزة Android | الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات | adb يوفّره المُستدعي (محاكي أو جهاز)؛ [دليل ADB](docs/adb-device-analysis.md) |
| مشاريع JEB | وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال | عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ [دليل JEB](docs/jeb-analysis.md) |
| موارد Android | البيان المفكوك الترميز وجداول السلاسل واللغات وحقائق الإصدار | مُشغّل Apktool يوفّره المُستدعي؛ [دليل الموارد](docs/apktool-resource-analysis.md) |
| البرامج الثابتة | المناطق، ونتائج الاستخراج، وما يُمرّر إلى تحليل الشيفرة الأصلية | Binwalk / Unblob على Linux؛ [دليل البرامج الثابتة](docs/firmware-analysis.md) |
| الحزم والموارد | قوائم الملفات، والبصمات، وملفات plist، وبنية حزم Apple، والموارد المستخرجة | [دليل تحليل الملفات وJavaScript](docs/javascript-artifact-reconstruction.md)، [تطبيقات Apple](docs/apple-application-analysis.md) |
| سلوك العمليات | مخرجات الطرفية، والتفاعلات، وملاحظات الخروج ونظام الملفات، ومقارنات التشغيل | Linux/macOS مع PTY أصلي؛ [تسجيل سلوك العمليات](docs/process-capture.md) |
@@ -154,6 +157,8 @@ npx rea-agents@latest setup
## دراسات الحالة
[![رسوم توضيحية لأمثلة توزيع الصوت في DX-Ball وجسر الحافظة في Notion وحلقة الطلقات في TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: إعادة بناء حساب توزيع الصوت بين القناتين
تتبّع استدعاء صوت إلى الدالة المساعدة التي تحوّل الموضع إلى توزيع بين القناتين، وافحص التعليمات، وحوّل الشيفرة شبه البرمجية غير المكتملة إلى C. تجتاز إعادة البناء 3,205 حالات اختبار على x86 الأصلي، وتعيد إنتاج جميع بايتات الدالة المترجمة البالغ عددها 63 بايتًا.
@@ -202,7 +207,7 @@ npx rea-agents@latest setup
<details>
<summary><strong>ماذا يفعل تثبيت المهارة من skills.sh؟</strong></summary>
توفّر المهارة تعليمات الاستقصاء لوكيلك. استخدم `rea setup` لتسجيل خادم MCP الخاص بـ REA وتثبيت التعليمات المطابقة، ثم أعد تشغيل وكيلك. راجع [تثبيت المهارة وحدها](docs/installation.md#skill-only-installation).
توفّر المهارة تعليمات الاستقصاء لوكيلك. استخدم `npx rea-agents setup` لتسجيل خادم MCP الخاص بـ REA وتثبيت التعليمات المطابقة، ثم أعد تشغيل وكيلك. راجع [تثبيت المهارة وحدها](docs/installation.md#skill-only-installation).
</details>
@@ -254,19 +259,9 @@ npx rea-agents@latest setup
أبلغ عن الثغرات وفق [SECURITY.md](SECURITY.md).
## المساهمة
نرحّب بمساعدتك في تطوير REA! [افتح issue](https://github.com/morluto/rea/issues) للإبلاغ عن خطأ أو اقتراح ميزة، أو [أرسل pull request](https://github.com/morluto/rea/pulls) لتحسين الشيفرة أو التوثيق.
راجع [CONTRIBUTING.md](CONTRIBUTING.md) لإعداد بيئة التطوير والفحوص، و[دليل الاختبار](docs/testing.md) لمسارات التحقق، و[خريطة البنية](docs/architecture.mermaid) لهيكل المشروع.
## روابط المشروع
[الموقع](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [الأمان](SECURITY.md)
## سجل النجوم
🎉 **30,000 نجمة على GitHub — شكرًا لكم!**
🎉 **50,000 نجمة على GitHub — شكرًا لكم!**
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
يوفّر REA أدوات لأبحاث الهندسة العكسية والتحليل وإعادة البناء المشروعة. أنت مسؤول عن الحصول على أي تفويض مطلوب والالتزام بالقوانين المعمول بها. لا يؤيد المشروع الاستخدام غير القانوني أو غير المصرّح به.
## المساهمة
نرحّب بمساعدتك في تطوير REA! [افتح issue](https://github.com/morluto/rea/issues) للإبلاغ عن خطأ أو اقتراح ميزة، أو [أرسل pull request](https://github.com/morluto/rea/pulls) لتحسين الشيفرة أو التوثيق.
راجع [CONTRIBUTING.md](CONTRIBUTING.md) لإعداد بيئة التطوير والفحوص، و[دليل الاختبار](docs/testing.md) لمسارات التحقق، و[خريطة البنية](docs/architecture.mermaid) لهيكل المشروع.
## الترخيص
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Alles reverse-engineeren
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA startet seine Analysebrücke in Hopper und untersucht eine native Binärdatei" width="1200" />
<br />
<br /><br />
<table aria-label="REA-Community">
<tr>
@@ -135,13 +135,16 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](https://rea.tools/guides/native/) |
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](docs/binary-diagnostics.md) |
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung unter Linux x64; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](https://rea.tools/guides/javascript/) |
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](https://rea.tools/guides/browser/) |
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](docs/web-network-captures.md) |
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](docs/managed-code-analysis.md) |
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS; [Android-Leitfaden](docs/android-analysis.md) |
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](docs/android-analysis.md) |
| Android-Geräte | Geräte, Pakete, Prozesse, Logs, Dumps, Bildschirmaufnahmen sowie APK- und Dateiübertragungen | Vom Aufrufer bereitgestelltes adb (Emulator oder Gerät); [ADB-Leitfaden](docs/adb-device-analysis.md) |
| JEB-Projekte | Engine-gestützte Projekteinheiten, Artefakt-Prüfsummen und Pseudokode von Typen/Methoden | Ein vom Aufrufer gestarteter JEB-Client mit MCP, ausgewählt über REA_JEB_MCP_URL; [JEB-Leitfaden](docs/jeb-analysis.md) |
| Android-Ressourcen | Dekodiertes Manifest, String-Tabellen, Sprachen und Versionsfakten | Vom Aufrufer bereitgestellter Apktool-Starter; [Ressourcen-Leitfaden](docs/apktool-resource-analysis.md) |
| Firmware | Bereiche, Extraktionsergebnisse und Übergaben an die native Analyse | Binwalk / Unblob unter Linux; [Firmware-Leitfaden](docs/firmware-analysis.md) |
| Pakete und Ressourcen | Dateiinventare, Hashwerte, plists, Aufbau von Apple-Bundles und extrahierte Ressourcen | [Artefakt- und JavaScript-Leitfaden](docs/javascript-artifact-reconstruction.md), [Apple-Anwendungen](docs/apple-application-analysis.md) |
| Prozessverhalten | Terminalausgabe, Interaktionen, Beobachtungen zu Prozessende und Dateisystem sowie Laufvergleiche | Linux/macOS mit nativer PTY; [Prozessaufzeichnung](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Native Formate und unterstützte Hostsysteme unterscheiden sich je nach Provider
## Fallstudien
[![Illustrationen der Fallstudien zu DX-Balls Klangbalance, Notions Zwischenablage-Brücke und TH04s Geschossring](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: Eine Stereo-Panning-Berechnung rekonstruieren
Verfolge einen Sound-Aufruf zur Hilfsfunktion, die Positionen in Panning-Werte umrechnet, untersuche die Anweisungen und überführe unvollständigen Pseudocode in C. Die Rekonstruktion besteht 3.205 Tests mit dem ursprünglichen x86-Code und reproduziert alle 63 Bytes der kompilierten Funktion.
@@ -200,7 +205,7 @@ REA startet Hopper, wenn eine Operation es benötigt. Unter macOS kann beim erst
<details>
<summary><strong>Was bewirkt die Installation des Skills über skills.sh?</strong></summary>
Der Skill stellt Untersuchungsanweisungen für deinen Agenten bereit. Verwende `rea setup`, um den MCP-Server von REA zu registrieren und passende Anweisungen zu installieren. Starte deinen Agenten anschließend neu. Siehe [Installation nur des Skills](docs/installation.md#skill-only-installation).
Der Skill stellt Untersuchungsanweisungen für deinen Agenten bereit. Verwende `npx rea-agents setup`, um den MCP-Server von REA zu registrieren und passende Anweisungen zu installieren. Starte deinen Agenten anschließend neu. Siehe [Installation nur des Skills](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ Beginne mit den [praxisnahen Anleitungen](https://rea.tools/guides/) auf der Web
Melde Sicherheitslücken gemäß [SECURITY.md](SECURITY.md).
## Mitwirken
Wir freuen uns über deine Hilfe bei REA! [Öffne ein Issue](https://github.com/morluto/rea/issues), um einen Fehler zu melden oder eine Funktion vorzuschlagen, oder [sende einen Pull Request](https://github.com/morluto/rea/pulls), um Code oder Dokumentation zu verbessern.
Die Entwicklungsumgebung und Prüfungen beschreibt [CONTRIBUTING.md](CONTRIBUTING.md), die Verifikationspfade der [Testleitfaden](docs/testing.md) und die Projektstruktur die [Architekturübersicht](docs/architecture.mermaid).
## Projektlinks
[Website](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Sicherheit](SECURITY.md)
## Sternverlauf
🎉 **30.000 GitHub-Sterne – vielen Dank!**
🎉 **50.000 GitHub-Sterne – vielen Dank!**
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
@@ -280,6 +275,12 @@ Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds
REA stellt Werkzeuge für rechtmäßige Reverse-Engineering-Forschung, Analyse und Rekonstruktion bereit. Du bist dafür verantwortlich, erforderliche Genehmigungen einzuholen und geltendes Recht einzuhalten. Das Projekt unterstützt keine rechtswidrige oder unbefugte Nutzung.
## Mitwirken
Wir freuen uns über deine Hilfe bei REA! [Öffne ein Issue](https://github.com/morluto/rea/issues), um einen Fehler zu melden oder eine Funktion vorzuschlagen, oder [sende einen Pull Request](https://github.com/morluto/rea/pulls), um Code oder Dokumentation zu verbessern.
Die Entwicklungsumgebung und Prüfungen beschreibt [CONTRIBUTING.md](CONTRIBUTING.md), die Verifikationspfade der [Testleitfaden](docs/testing.md) und die Projektstruktur die [Architekturübersicht](docs/architecture.mermaid).
## Lizenz
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Ingeniería inversa de cualquier cosa
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA inicia su puente de análisis dentro de Hopper mientras inspecciona un binario nativo" width="1200" />
<br />
<br /><br />
<table aria-label="Comunidad REA">
<tr>
@@ -135,13 +135,16 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](https://rea.tools/guides/native/) |
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](docs/binary-diagnostics.md) |
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal, en Linux x64; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama, en Linux x64; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](https://rea.tools/guides/javascript/) |
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](https://rea.tools/guides/browser/) |
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](docs/web-network-captures.md) |
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](docs/managed-code-analysis.md) |
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS; [guía de Android](docs/android-analysis.md) |
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, paquetes, procesos, registros, volcados, capturas de pantalla y transferencias de APK/archivos | adb suministrado por el autor de la llamada (emulador o dispositivo); [guía de ADB](docs/adb-device-analysis.md) |
| Proyectos JEB | Unidades de proyecto del motor, resúmenes de artefactos y pseudocódigo de tipos/métodos | Un cliente JEB iniciado por el autor de la llamada que sirve MCP, seleccionado con REA_JEB_MCP_URL; [guía de JEB](docs/jeb-analysis.md) |
| Recursos de Android | Manifiesto decodificado, tablas de cadenas, idiomas y datos de versión | Lanzador de Apktool suministrado por el autor de la llamada; [guía de recursos](docs/apktool-resource-analysis.md) |
| Firmware | Regiones, resultados de extracción y derivaciones al análisis nativo | Binwalk / Unblob en Linux; [guía de firmware](docs/firmware-analysis.md) |
| Paquetes y recursos | Inventarios de archivos, resúmenes criptográficos, plists, estructura de paquetes de Apple y recursos extraídos | [Guía de artefactos y JavaScript](docs/javascript-artifact-reconstruction.md), [aplicaciones de Apple](docs/apple-application-analysis.md) |
| Comportamiento de procesos | Salida de la terminal, interacciones, observaciones de salida y del sistema de archivos, y comparaciones entre ejecuciones | Linux/macOS con una PTY nativa; [captura de procesos](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Los formatos nativos y los sistemas anfitriones compatibles varían según el pr
## Casos prácticos
[![Ilustraciones de los casos de panoramización de sonido de DX-Ball, el puente del portapapeles de Notion y el anillo de proyectiles de TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruir un cálculo de panoramización de sonido
Sigue una llamada de sonido hasta la función auxiliar que convierte la posición en panoramización, inspecciona las instrucciones y transforma el pseudocódigo incompleto en C. La reconstrucción supera 3.205 casos con el x86 original y reproduce los 63 bytes de la función compilada.
@@ -200,7 +205,7 @@ REA inicia Hopper cuando una operación lo necesita. En macOS, puede aparecer un
<details>
<summary><strong>¿Qué hace la instalación de la skill desde skills.sh?</strong></summary>
La skill proporciona instrucciones de investigación a tu agente. Usa `rea setup` para registrar el servidor MCP de REA e instalar las instrucciones correspondientes; después reinicia tu agente. Consulta [instalación solo de la skill](docs/installation.md#skill-only-installation).
La skill proporciona instrucciones de investigación a tu agente. Usa `npx rea-agents setup` para registrar el servidor MCP de REA e instalar las instrucciones correspondientes; después reinicia tu agente. Consulta [instalación solo de la skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ Empieza con las [guías prácticas](https://rea.tools/guides/) del sitio web. Pa
Informa de vulnerabilidades siguiendo [SECURITY.md](SECURITY.md).
## Contribuir
¡Nos encantaría que ayudaras con REA! [Abre una issue](https://github.com/morluto/rea/issues) para comunicar un error o proponer una función, o [envía una pull request](https://github.com/morluto/rea/pulls) para mejorar el código o la documentación.
Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para preparar el entorno de desarrollo y las comprobaciones, la [guía de pruebas](docs/testing.md) para los procesos de verificación y el [mapa de arquitectura](docs/architecture.mermaid) para la estructura del proyecto.
## Enlaces del proyecto
[Sitio web](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Seguridad](SECURITY.md)
## Historial de estrellas
🎉 **30.000 estrellas en GitHub: ¡gracias!**
🎉 **50.000 estrellas en GitHub: ¡gracias!**
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
@@ -280,6 +275,12 @@ Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban co
REA proporciona herramientas para la investigación, el análisis y la reconstrucción mediante ingeniería inversa conforme a la ley. Eres responsable de obtener las autorizaciones necesarias y cumplir las leyes aplicables. El proyecto no respalda usos ilegales ni no autorizados.
## Contribuir
¡Nos encantaría que ayudaras con REA! [Abre una issue](https://github.com/morluto/rea/issues) para comunicar un error o proponer una función, o [envía una pull request](https://github.com/morluto/rea/pulls) para mejorar el código o la documentación.
Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para preparar el entorno de desarrollo y las comprobaciones, la [guía de pruebas](docs/testing.md) para los procesos de verificación y el [mapa de arquitectura](docs/architecture.mermaid) para la estructura del proyecto.
## Licencia
[MIT](LICENSE)
+30 -29
View File
@@ -1,6 +1,6 @@
<div align="center" dir="rtl">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی**
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی** · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: مهندسی معکوس هر چیزی
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="اجرای پل تحلیل REA در Hopper هنگام بررسی یک فایل باینری بومی" width="1200" />
<br />
<br /><br />
<table aria-label="انجمن REA"><tr><td align="center" width="360"><a href="https://discord.gg/GkcryMnJDM"><img src="docs/assets/discord.svg" height="42" alt="Discord" /><br /><strong>به انجمن مهندسی معکوس بپیوندید</strong></a><br /><sub>دیسکورد · پرسش و پاسخ · نمایش دستاوردها</sub></td></tr></table>
@@ -123,20 +123,23 @@ npx rea-agents@latest setup
REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه npm نیاز دارد. ابزارهای اضافی و پشتیبانی سیستم میزبان به نوع هدف بستگی دارند:
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| --------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS؛ [راهنمای اندروید](docs/android-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| --------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
| دستگاه‌های اندروید | دستگاه‌ها، بسته‌ها، فرایندها، لاگ‌ها، دامپ‌ها، اسکرین‌شات‌ها و انتقال APK/فایل | adb تأمین‌شده توسط فراخوان‌کننده (شبیه‌ساز یا دستگاه)؛ [راهنمای ADB](docs/adb-device-analysis.md) |
| پروژه‌های JEB | واحدهای پروژه از موتور، هش‌های مصنوع و شبه‌کدِ نوع/متد | یک کلاینت JEB که توسط فراخوان‌کننده اجرا شده و MCP ارائه می‌دهد و با REA_JEB_MCP_URL انتخاب می‌شود؛ [راهنمای JEB](docs/jeb-analysis.md) |
| منابع اندروید | مانیفست رمزگشایی‌شده، جداول رشته‌ها، زبان‌ها و اطلاعات نسخه | راه‌انداز Apktool تأمین‌شده توسط فراخوان‌کننده؛ [راهنمای منابع](docs/apktool-resource-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
بررسی ایستای JavaScript و .NET فایل‌های ارائه‌شده را بدون اجرای برنامه می‌خواند. ضبط زمان اجرا، هدف انتخاب‌شده را با مجوزهای کاربری شما اجرا می‌کند یا با آن تعامل دارد؛ آثار این عملیات در راهنمای مربوط به هر نوع ضبط توضیح داده شده‌اند.
@@ -146,6 +149,8 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه np
## نمونه‌های عملی
[![تصویرهایی از نمونه‌های پنینگ صدای DX-Ball، پل کلیپ‌بورد Notion و حلقهٔ گلوله‌های TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: بازسازی محاسبهٔ موقعیت استریوی صدا
یک فراخوانی صوتی را تا تابع کمکی تبدیل موقعیت به pan دنبال کنید، دستورالعمل‌ها را بررسی کنید و شبه‌کد ناقص را به C تبدیل کنید. بازسازی حاصل، هر ۳٬۲۰۵ مورد آزمایش x86 اصلی را با موفقیت پشت سر می‌گذارد و هر ۶۳ بایت تابع کامپایل‌شده را دقیقاً بازتولید می‌کند.
@@ -188,7 +193,7 @@ REA زمانی که عملیاتی به Hopper نیاز داشته باشد آن
<details><summary><strong>نصب skill از skills.sh چه کاری انجام می‌دهد؟</strong></summary>
این skill دستورالعمل‌های بررسی را برای ایجنت فراهم می‌کند. برای ثبت سرور MCP مربوط به REA و نصب دستورالعمل‌های متناظر، `rea setup` را اجرا کنید و سپس ایجنت را مجدداً راه‌اندازی کنید. [نصب مستقل skill](docs/installation.md#skill-only-installation) را ببینید.
این skill دستورالعمل‌های بررسی را برای ایجنت فراهم می‌کند. برای ثبت سرور MCP مربوط به REA و نصب دستورالعمل‌های متناظر، `npx rea-agents setup` را اجرا کنید و سپس ایجنت را مجدداً راه‌اندازی کنید. [نصب مستقل skill](docs/installation.md#skill-only-installation) را ببینید.
</details>
@@ -237,19 +242,9 @@ npx rea-agents@latest setup
آسیب‌پذیری‌ها را از طریق [SECURITY.md](SECURITY.md) گزارش کنید.
## مشارکت
از کمک شما به REA استقبال می‌کنیم! برای گزارش خطا یا پیشنهاد قابلیت، یک [issue باز کنید](https://github.com/morluto/rea/issues) یا برای بهبود کد و مستندات [pull request بفرستید](https://github.com/morluto/rea/pulls).
برای راه‌اندازی محیط توسعه و بررسی‌ها، [CONTRIBUTING.md](CONTRIBUTING.md)، برای مراحل اعتبارسنجی [آزمایش‌ها](docs/testing.md) و برای ساختار پروژه [نقشهٔ معماری](docs/architecture.mermaid) را ببینید.
## لینک‌های پروژه
[وب‌سایت](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [امنیت](SECURITY.md)
## تاریخچهٔ ستاره‌ها
🎉 **۳۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
🎉 **۵۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، قابلیت‌های جدید پیشنهاد می‌کنند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
@@ -259,6 +254,12 @@ npx rea-agents@latest setup
REA ابزارهایی برای پژوهش، تحلیل و بازسازی قانونی در حوزهٔ مهندسی معکوس فراهم می‌کند. مسئولیت دریافت مجوزهای لازم و رعایت قوانین مربوط بر عهدهٔ شماست. این پروژه استفادهٔ غیرقانونی یا بدون مجوز را تأیید نمی‌کند.
## مشارکت
از کمک شما به REA استقبال می‌کنیم! برای گزارش خطا یا پیشنهاد قابلیت، یک [issue باز کنید](https://github.com/morluto/rea/issues) یا برای بهبود کد و مستندات [pull request بفرستید](https://github.com/morluto/rea/pulls).
برای راه‌اندازی محیط توسعه و بررسی‌ها، [CONTRIBUTING.md](CONTRIBUTING.md)، برای مراحل اعتبارسنجی [آزمایش‌ها](docs/testing.md) و برای ساختار پروژه [نقشهٔ معماری](docs/architecture.mermaid) را ببینید.
## مجوز
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Français** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Français** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA : rétro-ingénierie de tout
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA lance son pont d'analyse dans Hopper pendant l'inspection d'un binaire natif" width="1200" />
<br />
<br /><br />
<table aria-label="REA community">
<tr>
@@ -136,13 +136,16 @@ REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](https://rea.tools/guides/native/) |
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](docs/binary-diagnostics.md) |
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal ; [guide EVM hors ligne](docs/evm-bytecode.md) |
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur ; GDB/pwndbg en option ; [crashs enregistrés](docs/recorded-crashes.md) |
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal sous Linux x64 ; [guide EVM hors ligne](docs/evm-bytecode.md) |
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur sous Linux x64 ; GDB/pwndbg en option ; [crashs enregistrés](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](https://rea.tools/guides/javascript/) |
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](https://rea.tools/guides/browser/) |
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](docs/web-network-captures.md) |
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](docs/managed-code-analysis.md) |
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS ; [guide Android](docs/android-analysis.md) |
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](docs/android-analysis.md) |
| Appareils Android | Appareils, paquets, processus, journaux, dumps, captures d'écran et transferts d'APK/fichiers | adb fourni par l'appelant (émulateur ou appareil) ; [guide ADB](docs/adb-device-analysis.md) |
| Projets JEB | Unités de projet fournies par le moteur, condensés d'artefacts et pseudo-code de types/méthodes | Un client JEB démarré par l'appelant servant MCP, sélectionné via REA_JEB_MCP_URL ; [guide JEB](docs/jeb-analysis.md) |
| Ressources Android | Manifeste décodé, tables de chaînes, langues et faits de version | Lanceur Apktool fourni par l'appelant ; [guide des ressources](docs/apktool-resource-analysis.md) |
| Firmware | Régions, résultats d'extraction et passage de relais vers l'analyse native | Binwalk / Unblob sous Linux ; [guide firmware](docs/firmware-analysis.md) |
| Paquets et ressources | Inventaires de fichiers, empreintes, plists, anatomie des bundles Apple et ressources extraites | [Guide artefacts et JavaScript](docs/javascript-artifact-reconstruction.md), [applications Apple](docs/apple-application-analysis.md) |
| Comportement des processus | Sortie du terminal, interactions, code de sortie, observations du système de fichiers et comparaisons | Linux/macOS avec un PTY natif ; [capture de processus](docs/process-capture.md) |
@@ -155,6 +158,8 @@ Les formats natifs et les hôtes pris en charge varient selon le fournisseur. Co
## Études de cas
[![Illustrations des études sur la spatialisation sonore de DX-Ball, le pont du presse-papiers de Notion et le cercle de projectiles de TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball : reconstruire un calcul de panoramique sonore
Suivez un appel sonore jusqu'à la fonction qui convertit une position en panoramique, inspectez ses instructions et transformez un pseudo-code incomplet en C. La reconstruction réussit 3 205 cas issus du x86 d'origine et reproduit à l'identique les 63 octets de la fonction compilée.
@@ -201,7 +206,7 @@ REA lance Hopper lorsqu'une opération en a besoin. Sous macOS, une boîte de di
<details>
<summary><strong>Que fait l'installation du skill depuis skills.sh ?</strong></summary>
Le skill fournit des instructions d'investigation à votre agent. Utilisez `rea setup` pour enregistrer le serveur MCP de REA et installer les instructions correspondantes, puis redémarrez votre agent. Consultez [l'installation du skill seul](docs/installation.md#skill-only-installation).
Le skill fournit des instructions d'investigation à votre agent. Utilisez `npx rea-agents setup` pour enregistrer le serveur MCP de REA et installer les instructions correspondantes, puis redémarrez votre agent. Consultez [l'installation du skill seul](docs/installation.md#skill-only-installation).
</details>
@@ -253,19 +258,9 @@ Commencez par les [guides pas à pas](https://rea.tools/guides/) du site web. Po
Signalez les vulnérabilités via [SECURITY.md](SECURITY.md).
## Contribuer
Votre aide sur REA est la bienvenue ! [Ouvrez une issue](https://github.com/morluto/rea/issues) pour signaler un bug ou proposer une fonctionnalité, ou [envoyez une pull request](https://github.com/morluto/rea/pulls) pour améliorer le code ou la documentation.
Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développement et les vérifications, la page [tests](docs/testing.md) pour les filières de vérification, et la [carte de l'architecture](docs/architecture.mermaid) pour la structure du projet.
## Liens du projet
[Site web](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Sécurité](SECURITY.md)
## Historique des étoiles
🎉 **30 000 étoiles GitHub — merci !**
🎉 **50 000 étoiles GitHub — merci !**
Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent des fonctionnalités, testent les builds et contribuent des correctifs.
@@ -281,6 +276,12 @@ Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent d
REA fournit des outils destinés à la recherche, à l'analyse et à la reconstruction légales en rétro-ingénierie. Il vous appartient d'obtenir toute autorisation nécessaire et de respecter les lois applicables. Le projet n'encourage aucune utilisation illégale ou non autorisée.
## Contribuer
Votre aide sur REA est la bienvenue ! [Ouvrez une issue](https://github.com/morluto/rea/issues) pour signaler un bug ou proposer une fonctionnalité, ou [envoyez une pull request](https://github.com/morluto/rea/pulls) pour améliorer le code ou la documentation.
Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développement et les vérifications, la page [tests](docs/testing.md) pour les filières de vérification, et la [carte de l'architecture](docs/architecture.mermaid) pour la structure du projet.
## Licence
[MIT](LICENSE)
+310
View File
@@ -0,0 +1,310 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · **Bahasa Indonesia** · [Italiano](README_it.md)
# REA: Rekayasa Balik Apa Pun
### Satu MCP untuk rekayasa balik pada berbagai biner, aplikasi, dan perilaku saat runtime.
**Melihat fitur yang Anda sukai. Pahami cara kerjanya hingga ke tingkat biner.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[Situs Web](https://rea.tools/) · [Panduan](https://rea.tools/guides/) · [Contoh Penggunaan](https://rea.tools/showcase/)**
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [FAQ](#faq) · [Dokumentasi](#dokumentasi)
<code>npx rea-agents setup</code>
<br />
<img src="docs/assets/rea-hopper-analysis.png" alt="REA menjalankan jembatan analisisnya di dalam Hopper saat memeriksa biner native" width="1200" />
<br /><br />
<table aria-label="Komunitas REA">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="docs/assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Bergabunglah dengan Komunitas Rekayasa Balik</strong>
</a><br />
<sub>Discord · Tanya Jawab · Berbagi Hasil</sub>
</td>
</tr>
</table>
<br />
</div>
---
Melihat fitur dalam suatu aplikasi yang ingin Anda hadirkan di produk sendiri? Minta agen Anda menyelidikinya menggunakan REA. REA dapat memeriksa aplikasi tanpa kode sumbernya, menjelaskan cara kerja fitur tersebut, menunjukkan bukti, dan membangun versi untuk proyek Anda.
REA menghubungkan agen Anda dengan berbagai alat untuk memeriksa biner native, aplikasi JavaScript dan Electron, assembly .NET, serta situs web. Anda juga dapat menggunakan alat yang sama dari terminal. Analisis dijalankan secara lokal, dan hasilnya mencakup bukti serta keterbatasan yang mendasari setiap kesimpulan.
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, atau IDA yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
> **[Kunjungi situs web REA](https://rea.tools/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
## Mulai Cepat
### Siapkan agen Anda
Dengan Node.js dan npm yang telah terpasang, jalankan:
```bash
npx rea-agents setup
```
Pilih agen yang ingin digunakan, tinjau perubahan yang diusulkan, lalu setujui perubahan tersebut. Proses penyiapan menambahkan server MCP REA dan instruksi alur kerja yang sesuai, serta membuat cadangan konfigurasi yang sudah ada. Setelah itu, mulai ulang agen Anda.
Penyiapan mendukung Claude Code, Codex, Cursor, Gemini CLI, Grok Build, dan [agen lainnya](docs/installation.md#supported-agents). Lihat [instalasi dan penyiapan](docs/installation.md) untuk konfigurasi penyedia dan pendaftaran MCP secara manual.
### Minta agen Anda
```text
Pahami cara kerja pencarian di aplikasi Notes, tunjukkan buktinya, dan buat fitur serupa untuk proyek saya.
```
Ganti Notes dengan aplikasi target dan fitur yang ingin Anda pahami.
### Gunakan terminal
Periksa direktori aplikasi JavaScript/Electron yang telah diekstrak atau berkas ASAR:
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
```
Hasilnya mencakup modul, impor, batas antarkomponen Electron, dan bukti yang mendasarinya. Ganti jalur tersebut dengan lokasi target Anda, misalnya `"D:/apps/example"` di Windows.
Untuk memasang perintah `rea` agar dapat digunakan secara rutin:
```bash
npm install --global rea-agents
rea --help
```
Untuk analisis native, konfigurasikan penyedia terlebih dahulu. Lihat [Panduan CLI dan Bukti](docs/cli.md) untuk perintah native, pemilihan penyedia, snapshot, dan pembuatan skrip.
### Perbarui REA
REA berkembang dengan cepat, dan rilis baru sering menyertakan perbaikan bug. Pastikan instalasi Anda selalu diperbarui.
Untuk CLI yang dipasang melalui npm:
```bash
rea update
```
Untuk memperbarui pendaftaran agen dan skill Anda, jalankan perintah penyiapan yang ditampilkan oleh proses pembaruan.
Jika Anda menggunakan `npx`, perbarui penyiapan agen dengan:
```bash
npx rea-agents@latest setup
```
Tinjau perubahan penyiapan dan mulai ulang agen Anda. Untuk menjalankan perintah CLI sekali pakai, gunakan `npx rea-agents@latest` diikuti dengan perintah yang diinginkan.
## Cara Kerja REA
Agen Anda memanggil REA melalui MCP untuk memeriksa target dan menelusuri kode yang relevan. REA mengembalikan temuan beserta bukti pendukungnya. Agen kemudian menggunakan temuan tersebut untuk mengajukan pertanyaan lanjutan, menjelaskan perilaku, atau menulis dan menguji implementasi.
Perintah CLI menggunakan alur kerja yang sama.
![Alur investigasi REA: agen Anda menanyakan sesuatu tentang target lokal, REA memeriksa dan menelusurinya menggunakan alat analisis, lalu agen menggunakan kode, referensi, dan hal-hal yang belum diketahui dari hasil tersebut untuk menjelaskan, mengimplementasikan, dan menguji.](website/public/assets/figures/rea-investigation-flow.svg)
[Buka ilustrasi dalam ukuran penuh](website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## Hal yang Dapat Anda Analisis
REA memerlukan Node.js 22.x (>=22.19), 24.x (>=24.11), atau 26+, beserta npm.
Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
| Target | Hasil yang diberikan REA | Persyaratan dan panduan |
| -------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](https://rea.tools/guides/native/) |
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](docs/binary-diagnostics.md) |
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](docs/evm-bytecode.md) |
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil; GDB/pwndbg opsional; [crash yang direkam](docs/recorded-crashes.md) |
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](https://rea.tools/guides/javascript/) |
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](https://rea.tools/guides/browser/) |
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](docs/web-network-captures.md) |
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](docs/managed-code-analysis.md) |
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](docs/android-analysis.md) |
| Perangkat Android | Perangkat, paket, proses, log, dump, tangkapan layar, serta transfer APK/berkas | adb buatan pemanggil (emulator atau perangkat); [panduan ADB](docs/adb-device-analysis.md) |
| Proyek JEB | Unit proyek bertenaga mesin, hash artefak, dan pseudokode tipe/metode | Klien JEB yang dijalankan pemanggil dan menyajikan MCP, dipilih dengan REA_JEB_MCP_URL; [panduan JEB](docs/jeb-analysis.md) |
| Resource Android | Manifest terdekode, tabel string, lokal, dan fakta versi | Peluncur Apktool buatan pemanggil; [panduan resource](docs/apktool-resource-analysis.md) |
| Firmware | Wilayah, hasil ekstraksi, dan pengalihan ke analisis native | Binwalk / Unblob di Linux; [panduan firmware](docs/firmware-analysis.md) |
| Paket dan sumber daya | Inventaris berkas, digest, plist, struktur paket Apple, dan sumber daya yang diekstrak | [Panduan artefak dan JavaScript](docs/javascript-artifact-reconstruction.md), [aplikasi Apple](docs/apple-application-analysis.md) |
| Perilaku proses | Keluaran terminal, interaksi, pengamatan proses keluar dan sistem berkas, serta perbandingan eksekusi | Linux/macOS dengan PTY native; [perekaman proses](docs/process-capture.md) |
Pemeriksaan JavaScript dan .NET statis membaca berkas yang disediakan tanpa menjalankan aplikasinya. Perekaman runtime menjalankan atau berinteraksi dengan target yang dipilih menggunakan izin pengguna Anda. Setiap panduan runtime menjelaskan dampaknya.
<a id="choosing-a-deep-analysis-provider"></a>
Format native dan dukungan sistem host berbeda-beda menurut penyedia. Lihat [penyiapan Hopper dan Ghidra](docs/installation.md#hopper), [panduan IDA](docs/ida-provider.md), dan [dukungan eksperimental Ghidra di Windows](docs/windows-ghidra-p0.md).
Ghidra juga mendukung [analisis DOS 16-bit](docs/ghidra-dos.md).
Untuk biner berukuran besar, tingkatkan batas waktu startup menggunakan `REA_GHIDRA_STARTUP_TIMEOUT_MS`.
Untuk memilih penyedia, lihat [panduan CLI](docs/cli.md#choose-a-provider).
Periksa [ketersediaan rilis](docs/installation.md#released-package-and-main) untuk mengetahui fitur yang ditambahkan setelah rilis npm terbaru.
## Contoh Penggunaan
[![Ilustrasi contoh penggunaan DX-Ball sound-pan, Notion clipboard-bridge, dan TH04 bullet-ring](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: merekonstruksi perhitungan sound-pan
Ikuti pemanggilan suara hingga ke fungsi pembantu yang mengubah posisi menjadi nilai pan, periksa instruksinya, lalu ubah pseudocode yang belum lengkap menjadi C. Hasil rekonstruksi tersebut lolos pada 3.205 kasus x86 asli dan mereproduksi seluruh 63 byte fungsi hasil kompilasi.
[Baca studi kasus](https://rea.tools/showcase/dx-ball/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/dx-ball)
### Notion: menelusuri jembatan clipboard Electron
Temukan API clipboard pada renderer, telusuri jalurnya melalui preload dan IPC hingga ke proses utama, lalu periksa format clipboard kaya.
[Baca studi kasus](https://rea.tools/showcase/notion/)
### TH04: memulihkan perhitungan bullet-ring DOS
Periksa instruksi 16-bit dari gim PC-98 asli, pulihkan perhitungan sudut tetap dan sudut yang diarahkan, lalu bandingkan C++ hasil rekonstruksi dengan keluaran historis kompiler.
[Baca studi kasus](https://rea.tools/showcase/th04/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/th04)
Jika Anda telah menggunakan REA untuk menganalisis sesuatu yang menarik, kami ingin melihat hasilnya. Bagikan kasus Anda melalui [issue](https://github.com/morluto/rea/issues) atau [pull request](https://github.com/morluto/rea/pulls), sertakan target, pertanyaan Anda, bagaimana REA membantu, dan apa yang Anda temukan.
## FAQ
<details>
<summary><strong>Agen apa saja yang dapat menggunakan REA?</strong></summary>
Agen apa pun yang mendukung server MCP lokal dapat menggunakan REA. Proses penyiapan mengonfigurasi [agen yang didukung](docs/installation.md#supported-agents). Klien lain dapat menggunakan [pendaftaran MCP manual](docs/installation.md#mcp-registry).
</details>
<details>
<summary><strong>Apakah saya memerlukan Hopper, Ghidra, atau IDA?</strong></summary>
Analisis native mendalam menggunakan salah satu dari ketiganya. Pemeriksaan JavaScript dan .NET statis dapat dilakukan tanpa mesin analisis native.
Proses penyiapan dapat memasang Hopper setelah memperoleh persetujuan. Ghidra dan IDA menggunakan instalasi yang sudah tersedia. Lihat [penyiapan penyedia](docs/installation.md#hopper).
</details>
<details>
<summary><strong>Apakah saya harus menjalankan Hopper terlebih dahulu?</strong></summary>
REA akan menjalankan Hopper saat suatu operasi membutuhkannya. Di macOS, dialog saat pertama kali dijalankan mungkin meminta Anda memilih mode demo atau mengaktifkan lisensi.
Lihat [startup dan pemecahan masalah Hopper](docs/installation.md#launcher-paths-and-troubleshooting).
</details>
<details>
<summary><strong>Apa fungsi memasang skill dari skills.sh?</strong></summary>
Skill tersebut menyediakan instruksi investigasi untuk agen Anda. Gunakan `npx rea-agents setup` untuk mendaftarkan server MCP REA dan memasang instruksi yang sesuai, lalu mulai ulang agen Anda.
Lihat [instalasi khusus skill](docs/installation.md#skill-only-installation).
</details>
<details>
<summary><strong>Kode seperti apa yang dihasilkan REA?</strong></summary>
Analisis native menghasilkan pseudocode dan assembly. Analisis JavaScript/Electron memulihkan modul dan hubungan antarmodulnya. Agen Anda menggunakan temuan tersebut untuk menulis dan menguji implementasi. [Contoh penggunaan](#contoh-penggunaan) menyediakan contoh yang telah dikerjakan.
</details>
<details>
<summary><strong>Apakah REA mengunggah aplikasi saya?</strong></summary>
REA menganalisis target secara lokal. Agen Anda menerima hasil alat, sedangkan penyedia model yang digunakannya memiliki kebijakan datanya sendiri.
</details>
<details>
<summary><strong>Apa yang harus saya lakukan jika menemukan bug?</strong></summary>
Perbarui terlebih dahulu. Rilis terbaru mungkin sudah memperbaiki masalah tersebut.
Untuk CLI yang dipasang melalui npm:
```bash
rea update
```
Untuk penyiapan agen melalui `npx`:
```bash
npx rea-agents@latest setup
```
Jika Anda menggunakan agen, selesaikan [pembaruan penyiapan](#perbarui-rea) dan mulai ulang agen tersebut.
Coba kembali tugas yang sama. Jika masalah masih terjadi, [buat issue](https://github.com/morluto/rea/issues) dengan menyertakan versi REA, jenis target, langkah-langkah untuk mereproduksi masalah, dan keluaran kesalahan.
</details>
## Dokumentasi
Mulailah dengan [panduan praktik di situs web](https://rea.tools/guides/).
Untuk mengetahui opsi, prasyarat, dan kontrak hasil secara tepat:
- [Instalasi dan penyiapan](docs/installation.md): pendaftaran agen, konfigurasi penyedia, pembaruan, dan penghapusan instalasi.
- [Kesiapan dan pemecahan masalah](docs/installation.md#check-readiness-for-your-task): mendiagnosis satu agen atau mesin analisis.
- [CLI dan Bukti](docs/cli.md): perintah, pemilihan penyedia, snapshot, impor/ekspor, dan status keluar.
- [Kontrak MCP](docs/mcp-contracts.md) dan [prompt agen](docs/mcp-prompts.md): hasil alat, sesi, dan investigasi terpandu.
- [Katalog alat](docs/mcp-contracts.md#generated-catalog): inventaris alat, penyedia, dan perintah CLI yang dibuat secara otomatis.
- [Peta jalan](docs/roadmap.md): pekerjaan yang direncanakan dan pelacak kemampuan.
Laporkan kerentanan melalui [SECURITY.md](SECURITY.md).
## Riwayat Bintang
🎉 **50.000 bintang GitHub, terima kasih!**
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="Riwayat bintang GitHub REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Penafian
REA menyediakan alat untuk penelitian, analisis, dan rekonstruksi rekayasa balik yang sah. Anda bertanggung jawab untuk memperoleh otorisasi yang diperlukan dan mematuhi hukum yang berlaku. Proyek ini tidak mendukung penggunaan ilegal atau tanpa izin.
REA adalah proyek perangkat lunak sumber terbuka. Kami tidak menerbitkan atau mendukung mata uang kripto maupun token apa pun. Token yang menggunakan nama REA tidak berafiliasi dengan proyek ini.
## Kontribusi
Kami sangat menghargai bantuan Anda untuk REA! [Buat issue](https://github.com/morluto/rea/issues) untuk melaporkan bug atau menyarankan fitur, atau [kirim pull request](https://github.com/morluto/rea/pulls) untuk meningkatkan kode atau dokumentasi.
Lihat [CONTRIBUTING.md](CONTRIBUTING.md) untuk penyiapan pengembangan dan pemeriksaan, [pengujian](docs/testing.md) untuk tahapan verifikasi, serta [peta arsitektur](docs/architecture.mermaid) untuk struktur proyek.
## Lisensi
[MIT](LICENSE)
+289
View File
@@ -0,0 +1,289 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · **Italiano**
# REA: Reverse Engineer Anything
### Un unico MCP per l'ingegneria inversa su binari, applicazioni e comportamento a runtime.
**Vedi una funzionalità che ti piace. Capisci come funziona, fino al livello binario.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#cosa-puoi-analizzare)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[Sito web](https://rea.tools/) · [Guide](https://rea.tools/guides/) · [Showcase](https://rea.tools/showcase/)**
[Quick start](#quick-start) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [FAQ](#faq) · [Documentazione](#documentazione)
<code>npx rea-agents setup</code>
<br />
<img src="docs/assets/rea-hopper-analysis.png" alt="REA che avvia il suo bridge di analisi dentro Hopper mentre ispeziona un binario nativo" width="1200" />
<br /><br />
<table aria-label="Community REA">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="docs/assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Unisciti alla community di ingegneria inversa</strong>
</a><br />
<sub>Discord · Domande e risposte · Show and Tell</sub>
</td>
</tr>
</table>
<br />
</div>
---
Hai visto una funzionalità in un'app che vorresti nel tuo prodotto? Chiedi al tuo agente di analizzarla con REA. Può ispezionare l'app senza il suo codice sorgente, spiegare come funziona la funzionalità, mostrare le prove e realizzare una versione per il tuo progetto.
REA collega il tuo agente a strumenti per ispezionare binari nativi, app JavaScript ed Electron, assembly .NET e siti web. Puoi usare gli stessi strumenti anche dal terminale. L'analisi viene eseguita localmente e i risultati includono le prove e i limiti dietro ogni conclusione.
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra o IDA; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
> **[Visita il sito web di REA](https://rea.tools/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
## Quick start
### Configura il tuo agente
Con Node.js e npm installati, esegui:
```bash
npx rea-agents setup
```
Scegli i tuoi agenti, rivedi le modifiche proposte e approvale. La configurazione aggiunge il server MCP di REA e le istruzioni di workflow corrispondenti, con backup della configurazione esistente. Riavvia quindi il tuo agente.
La configurazione supporta Claude Code, Codex, Cursor, Gemini CLI, Grok Build e [altri agenti](docs/installation.md#supported-agents). Vedi [installazione e configurazione](docs/installation.md) per la configurazione dei provider e la registrazione manuale MCP.
### Chiedi al tuo agente
```text
Spiega come funziona la ricerca nell'app Note, mostrami le prove e realizza
una funzionalità simile per il mio progetto.
```
Sostituisci Note con la tua app di destinazione e la funzionalità che vuoi capire.
### Usa il terminale
Ispeziona una directory di app JavaScript/Electron estratta o un ASAR:
```bash
npx -y rea-agents@latest analyze-javascript-application /percorso/assoluto/verso/app --json
```
Il risultato include moduli, import, confini Electron e le relative prove. Sostituisci il percorso con il tuo bersaglio, ad esempio `"D:/apps/example"` su Windows.
Per installare il comando `rea` per un uso regolare:
```bash
npm install --global rea-agents
rea --help
```
Per l'analisi nativa, configura prima un provider. Vedi la [guida CLI ed Evidence](docs/cli.md) per i comandi nativi, la selezione del provider, gli snapshot e lo scripting.
### Aggiorna REA
REA cambia rapidamente e le nuove versioni includono correzioni di bug frequenti. Tieni aggiornata la tua installazione.
Per una CLI installata via npm:
```bash
rea update
```
Per aggiornare le registrazioni del tuo agente e lo skill, esegui il comando di configurazione mostrato dall'aggiornamento.
Se usi `npx`, aggiorna la configurazione del tuo agente con:
```bash
npx rea-agents@latest setup
```
Rivedi le modifiche di configurazione e riavvia il tuo agente. Per comandi CLI singoli, usa `npx rea-agents@latest` seguito dal comando.
## Come funziona REA
Il tuo agente chiama REA tramite MCP per ispezionare il bersaglio e tracciare il codice rilevante. REA restituisce i risultati con le relative prove. L'agente li usa per fare domande di approfondimento, spiegare il comportamento o scrivere e testare un'implementazione. Anche i comandi CLI usano gli stessi workflow.
![Flusso di indagine REA: il tuo agente pone domande su un bersaglio locale, REA lo ispeziona e ne traccia il codice usando strumenti di analisi, e l'agente usa il codice, i riferimenti e gli elementi sconosciuti restituiti per spiegare, implementare e testare.](website/public/assets/figures/rea-investigation-flow.svg)
[Apri la figura a dimensione intera](website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## Cosa puoi analizzare
REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strumenti aggiuntivi e supporto host dipendono dal bersaglio:
| Obiettivo | Cosa restituisce REA | Requisiti e guida |
| ---------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](https://rea.tools/guides/native/) |
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](docs/binary-diagnostics.md) |
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](docs/evm-bytecode.md) |
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante; GDB/pwndbg opzionale; [crash registrati](docs/recorded-crashes.md) |
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](https://rea.tools/guides/javascript/) |
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](https://rea.tools/guides/browser/) |
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](docs/web-network-captures.md) |
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](docs/managed-code-analysis.md) |
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](docs/android-analysis.md) |
| Dispositivi Android | Dispositivi, pacchetti, processi, log, dump, screenshot e trasferimenti APK/file | adb fornito dal chiamante (emulatore o hardware); [guida ADB](docs/adb-device-analysis.md) |
| Progetti JEB | Unità di progetto dal motore, digest degli artifact e pseudocodice di tipi/metodi | Client JEB avviato dal chiamante via MCP, selezionato con REA_JEB_MCP_URL; [guida JEB](docs/jeb-analysis.md) |
| Risorse Android | Manifest decodificato, tabelle stringhe, lingue e dati di versione | Launcher Apktool fornito dal chiamante; [guida alle risorse](docs/apktool-resource-analysis.md) |
| Firmware | Regioni, risultati di estrazione e passaggi all'analisi nativa | Binwalk / Unblob su Linux; [guida firmware](docs/firmware-analysis.md) |
| Pacchetti e risorse | Inventari file, digest, plist, anatomia dei bundle Apple e risorse estratte | [Guida artifact e JavaScript](docs/javascript-artifact-reconstruction.md), [Applicazioni Apple](docs/apple-application-analysis.md) |
| Comportamento dei processi | Output del terminale, interazioni, osservazioni su uscita e filesystem ed confronti di esecuzione | Linux/macOS con un PTY nativo; [cattura dei processi](docs/process-capture.md) |
L'ispezione statica di JavaScript e .NET legge i file forniti senza eseguire l'applicazione. La cattura a runtime esegue o interagisce con il bersaglio selezionato usando i tuoi permessi utente; ogni guida runtime descrive i suoi effetti.
<a id="choosing-a-deep-analysis-provider"></a>
I formati nativi e il supporto host variano in base al provider. Vedi la [configurazione di Hopper e Ghidra](docs/installation.md#hopper), la [guida IDA](docs/ida-provider.md) e il [supporto sperimentale Windows Ghidra](docs/windows-ghidra-p0.md). Ghidra supporta anche l'[analisi DOS a 16 bit](docs/ghidra-dos.md). Per binari di grandi dimensioni, aumenta il timeout di avvio con `REA_GHIDRA_STARTUP_TIMEOUT_MS`. Per la selezione del provider, vedi la [guida CLI](docs/cli.md#choose-a-provider). Controlla la [disponibilità delle release](docs/installation.md#released-package-and-main) per le funzionalità aggiunte dall'ultima release npm.
## Showcase
[![Illustrazioni degli showcase del sound-pan di DX-Ball, del clipboard-bridge di Notion e dell'anello di proiettili di TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: ricostruisci un calcolo sound-pan
Segui una chiamata sonora fino al suo helper posizione-to-pan, ispeziona le istruzioni e trasforma il pseudocodice incompleto in C. La ricostruzione supera 3.205 casi x86 originali e riproduce tutti i 63 byte di funzione compilati.
[Leggi il case study](https://rea.tools/showcase/dx-ball/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/dx-ball)
### Notion: traccia il clipboard bridge di Electron
Trova l'API clipboard del renderer, seguila attraverso preload e IPC fino al processo principale e ispeziona il formato rich clipboard.
[Leggi il case study](https://rea.tools/showcase/notion/)
### TH04: recupera un calcolo dell'anello di proiettili DOS
Ispeziona le istruzioni a 16 bit del gioco PC-98 originale, recupera i calcoli dell'angolo fisso e mirato e confronta il C++ ricostruito con l'output del compilatore storico.
[Leggi il case study](https://rea.tools/showcase/th04/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/th04)
Se hai usato REA su qualcosa di interessante, ci piacerebbe vederlo. Condividi il tuo caso in una [issue](https://github.com/morluto/rea/issues) o in una [pull request](https://github.com/morluto/rea/pulls), includendo il bersaglio, la tua domanda, come REA ti ha aiutato e cosa hai scoperto.
## FAQ
<details>
<summary><strong>Quali agenti possono usare REA?</strong></summary>
Qualsiasi agente che supporti server MCP locali. La configurazione configura gli [agenti supportati](docs/installation.md#supported-agents); altri client possono usare la [registrazione MCP manuale](docs/installation.md#mcp-registry).
</details>
<details>
<summary><strong>Ho bisogno di Hopper, Ghidra o IDA?</strong></summary>
L'analisi nativa profonda ne usa uno. L'ispezione statica di JavaScript e .NET funziona senza un motore di analisi nativo. La configurazione può installare Hopper previa approvazione; Ghidra e IDA usano le tue installazioni esistenti. Vedi [configurazione provider](docs/installation.md#hopper).
</details>
<details>
<summary><strong>Devo avviare Hopper per primo?</strong></summary>
REA avvia Hopper quando un'operazione ne ha bisogno. Su macOS, una finestra di dialogo al primo avvio potrebbe chiederti di scegliere la modalità demo o di attivare la licenza. Vedi [avvio di Hopper e risoluzione dei problemi](docs/installation.md#launcher-paths-and-troubleshooting).
</details>
<details>
<summary><strong>Cosa fa l'installazione dello skill da skills.sh?</strong></summary>
Lo skill fornisce istruzioni di indagine per il tuo agente. Usa `npx rea-agents setup` per registrare il server MCP di REA e installare le istruzioni corrispondenti, quindi riavvia il tuo agente. Vedi [installazione solo skill](docs/installation.md#skill-only-installation).
</details>
<details>
<summary><strong>Quale codice restituisce REA?</strong></summary>
L'analisi nativa restituisce pseudocodice e assembly. L'analisi JavaScript/Electron recupera moduli e le loro relazioni. Il tuo agente usa questi risultati per scrivere e testare un'implementazione; gli [showcase](#showcase) offrono esempi concreti.
</details>
<details>
<summary><strong>REA carica la mia app da qualche parte?</strong></summary>
REA analizza i bersagli localmente. Il tuo agente riceve i risultati degli strumenti e il suo provider di modello ha la propria politica sui dati.
</details>
<details>
<summary><strong>Cosa devo fare se trovo un bug?</strong></summary>
Aggiorna prima; una release recente potrebbe averlo già risolto.
Per una CLI installata via npm:
```bash
rea update
```
Per la configurazione dell'agente tramite `npx`:
```bash
npx rea-agents@latest setup
```
Se stai usando un agente, completa l'[aggiornamento della configurazione](#aggiorna-rea) e riavvialo. Riprova lo stesso task. Se il problema persiste, [apri un issue](https://github.com/morluto/rea/issues) con la tua versione di REA, il tipo di bersaglio, i passaggi per riprodurlo e l'output di errore.
</details>
## Documentazione
Inizia dalle [guide pratiche](https://rea.tools/guides/) del sito web. Per opzioni esatte, prerequisiti e contratti dei risultati:
- [Installazione e configurazione](docs/installation.md): registrazione agente, configurazione provider, aggiornamenti e disinstallazione.
- [Pronto all'uso e risoluzione dei problemi](docs/installation.md#check-readiness-for-your-task): diagnostica un agente o un motore di analisi.
- [CLI ed Evidence](docs/cli.md): comandi, selezione provider, snapshot, import/export e stati di uscita.
- [Contratti MCP](docs/mcp-contracts.md) e [prompt agente](docs/mcp-prompts.md): risultati degli strumenti, sessioni e indagini guidate.
- [Catalogo strumenti](docs/mcp-contracts.md#generated-catalog): inventario generato di strumenti, provider e comandi CLI.
- [Roadmap](docs/roadmap.md): lavoro pianificato e tracker delle capacità.
Segnala vulnerabilità tramite [SECURITY.md](SECURITY.md).
## Cronologia delle stelle
🎉 **50.000 stelle su GitHub — grazie!**
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="Cronologia stelle GitHub di REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Disclaimer
REA fornisce strumenti per la ricerca, l'analisi e la ricostruzione di ingegneria inversa lecita. Sei responsabile di ottenere le eventuali autorizzazioni richieste e di rispettare le leggi applicabili. Il progetto non approva l'uso illegale o non autorizzato.
REA è un progetto software open-source. Non abbiamo emesso né approvato alcuna criptovaluta o token. I token che usano il nome REA non sono affiliati al progetto.
## Contributing
Apprezzeremmo il tuo aiuto con REA! [Apri un issue](https://github.com/morluto/rea/issues) per segnalare un bug o suggerire una funzionalità, oppure [invia una pull request](https://github.com/morluto/rea/pulls) per migliorare il codice o la documentazione.
Vedi [CONTRIBUTING.md](CONTRIBUTING.md) per la configurazione di sviluppo e i controlli, [testing](docs/testing.md) per le lane di verifica e la [mappa dell'architettura](docs/architecture.mermaid) per la struttura del progetto.
## License
[MIT](LICENSE)
+30 -29
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:あらゆるものをリバースエンジニアリング
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA が Hopper 内で分析ブリッジを起動し、ネイティブバイナリを調べる様子" width="1200" />
<br />
<br /><br />
<table aria-label="REA コミュニティ">
<tr>
@@ -131,20 +131,23 @@ npx rea-agents@latest setup
REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm が必要です。追加のツールや対応ホストは、対象によって異なります。
| 対象 | REA が返すもの | 要件とガイド |
| -------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/guides/native/) |
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | ローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | 利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/guides/javascript/) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/guides/browser/) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
| ファームウェア | 領域、抽出結果、ネイティブ分析への引き継ぎ | Linux 上の Binwalk / Unblob;[ファームウェアガイド](docs/firmware-analysis.md) |
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
| 対象 | REA が返すもの | 要件とガイド |
| -------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/guides/native/) |
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/guides/javascript/) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/guides/browser/) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
| Android デバイス | デバイス、パッケージ、プロセス、ログ、ダンプ、スクリーンキャプチャ、APK/ファイル転送 | 呼び出し側が用意した adb(エミュレーターまたは実機);[ADB ガイド](docs/adb-device-analysis.md) |
| JEBプロジェクト | エンジンによるプロジェクトユニット、アーティファクトのダイジェスト、型/メソッドの擬似コード | 呼び出し側が起動し MCP を提供する JEB クライアント(REA_JEB_MCP_URL で選択);[JEB ガイド](docs/jeb-analysis.md) |
| Android リソース | デコードされたマニフェスト、文字列テーブル、ロケール、バージョン情報 | 呼び出し側が用意した Apktool ランチャー;[リソースガイド](docs/apktool-resource-analysis.md) |
| ファームウェア | 領域、抽出結果、ネイティブ分析への引き継ぎ | Linux 上の Binwalk / Unblob;[ファームウェアガイド](docs/firmware-analysis.md) |
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
静的な JavaScript と .NET の検査は、指定されたファイルを読み取り、アプリケーションを実行しません。実行時キャプチャは、あなたのユーザー権限で対象を実行したり、対象とやり取りしたりします。それぞれの実行時ガイドに、どのような操作が行われるかを記載しています。
@@ -154,6 +157,8 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
## 事例
[![DX-Ball の音声パン、Notion のクリップボードブリッジ、TH04 の弾幕リングの事例を表すイラスト](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:音声のパン計算を再構築する
音声の呼び出しから位置をパンに変換する補助関数をたどり、命令を調べ、不完全な疑似コードを C に書き直します。再構築した実装は、元の x86 に対する 3,205 ケースの検証を通過し、コンパイル後の関数の全 63 バイトを再現しています。
@@ -202,7 +207,7 @@ REA は必要な操作の際に Hopper を起動します。macOS では、初
<details>
<summary><strong>skills.sh からスキルをインストールすると何ができますか?</strong></summary>
スキルはエージェントに調査の手順を提供します。`rea setup` で REA の MCP サーバーを登録し、対応する手順をインストールしてから、エージェントを再起動してください。[スキルのみのインストール](docs/installation.md#skill-only-installation)を参照してください。
スキルはエージェントに調査の手順を提供します。`npx rea-agents setup` で REA の MCP サーバーを登録し、対応する手順をインストールしてから、エージェントを再起動してください。[スキルのみのインストール](docs/installation.md#skill-only-installation)を参照してください。
</details>
@@ -254,19 +259,9 @@ npx rea-agents@latest setup
脆弱性の報告は [SECURITY.md](SECURITY.md) に従ってください。
## 貢献する
REA への貢献を歓迎します![issue を作成](https://github.com/morluto/rea/issues)してバグや機能の提案を報告したり、[pull request を送信](https://github.com/morluto/rea/pulls)してコードやドキュメントを改善したりできます。
開発環境とチェックは [CONTRIBUTING.md](CONTRIBUTING.md)、検証レーンは[テストガイド](docs/testing.md)、プロジェクト構造は[アーキテクチャ図](docs/architecture.mermaid)を参照してください。
## プロジェクトリンク
[ウェブサイト](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [セキュリティ](SECURITY.md)
## スター履歴
🎉 **GitHub スター 30,000 件、ありがとうございます!**
🎉 **GitHub スター 50,000 件、ありがとうございます!**
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
@@ -282,6 +277,12 @@ REA の利用、バグ報告、機能の要望、ビルドのテスト、修正
REA は、合法的なリバースエンジニアリングの研究、分析、再構築のためのツールを提供します。必要な許可を得て、適用される法律に従う責任は利用者にあります。このプロジェクトは違法または無許可の利用を支持しません。
## 貢献する
REA への貢献を歓迎します![issue を作成](https://github.com/morluto/rea/issues)してバグや機能の提案を報告したり、[pull request を送信](https://github.com/morluto/rea/pulls)してコードやドキュメントを改善したりできます。
開発環境とチェックは [CONTRIBUTING.md](CONTRIBUTING.md)、検証レーンは[テストガイド](docs/testing.md)、プロジェクト構造は[アーキテクチャ図](docs/architecture.mermaid)を参照してください。
## ライセンス
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: 무엇이든 리버스 엔지니어링
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA가 Hopper 안에서 분석 브리지를 실행해 네이티브 바이너리를 검사하는 모습" width="1200" />
<br />
<br /><br />
<table aria-label="REA 커뮤니티">
<tr>
@@ -135,13 +135,16 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
| --------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](https://rea.tools/guides/native/) |
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](docs/binary-diagnostics.md) |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; [애플리케이션 분석](https://rea.tools/guides/javascript/) |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](https://rea.tools/guides/browser/) |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](docs/web-network-captures.md) |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; [관리 코드 가이드](docs/managed-code-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); [ADB 가이드](docs/adb-device-analysis.md) |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); [JEB 가이드](docs/jeb-analysis.md) |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; [리소스 가이드](docs/apktool-resource-analysis.md) |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; [펌웨어 가이드](docs/firmware-analysis.md) |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](docs/javascript-artifact-reconstruction.md), [Apple 애플리케이션](docs/apple-application-analysis.md) |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
## 사례
[![DX-Ball 사운드 패닝, Notion 클립보드 브리지, TH04 탄환 고리 사례를 보여 주는 그림](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: 사운드 패닝 계산 재구현
사운드 호출에서 위치를 패닝 값으로 변환하는 보조 함수까지 추적하고, 명령을 검사하여 불완전한 의사 코드를 C로 옮깁니다. 재구현한 코드는 원본 x86에 대한 3,205개 테스트 케이스를 통과했으며, 컴파일된 함수의 63바이트 전체를 재현합니다.
@@ -202,7 +207,7 @@ REA는 작업에 필요할 때 Hopper를 실행합니다. macOS에서는 처음
<details>
<summary><strong>skills.sh에서 설치하는 스킬은 어떤 역할을 하나요?</strong></summary>
스킬은 에이전트에게 조사 지침을 제공합니다. `rea setup`으로 REA의 MCP 서버를 등록하고 버전에 맞는 지침을 설치한 뒤 에이전트를 다시 시작하세요. [스킬만 설치하기](docs/installation.md#skill-only-installation)를 참고하세요.
스킬은 에이전트에게 조사 지침을 제공합니다. `npx rea-agents setup`으로 REA의 MCP 서버를 등록하고 버전에 맞는 지침을 설치한 뒤 에이전트를 다시 시작하세요. [스킬만 설치하기](docs/installation.md#skill-only-installation)를 참고하세요.
</details>
@@ -254,19 +259,9 @@ npx rea-agents@latest setup
취약점은 [SECURITY.md](SECURITY.md)에 따라 보고하세요.
## 기여
REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/rea/issues)해 버그나 기능을 제안하거나, [pull request를 보내](https://github.com/morluto/rea/pulls) 코드와 문서를 개선할 수 있습니다.
개발 환경과 검사 항목은 [CONTRIBUTING.md](CONTRIBUTING.md), 검증 절차는 [테스트 가이드](docs/testing.md), 프로젝트 구조는 [아키텍처 지도](docs/architecture.mermaid)를 참고하세요.
## 프로젝트 링크
[웹사이트](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [보안](SECURITY.md)
## 스타 기록
🎉 **GitHub 스타 30,000개, 감사합니다!**
🎉 **GitHub 스타 50,000개, 감사합니다!**
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
@@ -282,6 +277,12 @@ REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를
REA는 합법적인 리버스 엔지니어링 연구, 분석, 재구성을 위한 도구를 제공합니다. 필요한 권한을 얻고 관련 법률을 준수할 책임은 사용자에게 있습니다. 이 프로젝트는 불법적이거나 허가받지 않은 사용을 지지하지 않습니다.
## 기여
REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/rea/issues)해 버그나 기능을 제안하거나, [pull request를 보내](https://github.com/morluto/rea/pulls) 코드와 문서를 개선할 수 있습니다.
개발 환경과 검사 항목은 [CONTRIBUTING.md](CONTRIBUTING.md), 검증 절차는 [테스트 가이드](docs/testing.md), 프로젝트 구조는 [아키텍처 지도](docs/architecture.mermaid)를 참고하세요.
## 라이선스
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA uruchamia most analityczny w Hopperze podczas analizy natywnego pliku binarnego" width="1200" />
<br />
<br /><br />
<table aria-label="Społeczność REA">
<tr>
@@ -135,13 +135,16 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](https://rea.tools/guides/native/) |
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](docs/binary-diagnostics.md) |
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym; [przewodnik EVM offline](docs/evm-bytecode.md) |
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym w systemie Linux x64; [przewodnik EVM offline](docs/evm-bytecode.md) |
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika w systemie Linux x64; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](https://rea.tools/guides/javascript/) |
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](https://rea.tools/guides/browser/) |
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](docs/web-network-captures.md) |
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](docs/managed-code-analysis.md) |
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemie Linux/macOS; [przewodnik Androida](docs/android-analysis.md) |
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](docs/android-analysis.md) |
| Urządzenia z Androidem | Urządzenia, pakiety, procesy, logi, zrzuty, zrzuty ekranu oraz transfery APK/plików | adb dostarczony przez wywołującego (emulator lub urządzenie); [przewodnik ADB](docs/adb-device-analysis.md) |
| Projekty JEB | Jednostki projektu obsługiwane przez silnik, skróty artefaktów i pseudokod typów/metod | Uruchomiony przez wywołującego klient JEB udostępniający MCP, wybrany przez REA_JEB_MCP_URL; [przewodnik JEB](docs/jeb-analysis.md) |
| Zasoby Androida | Zdekodowany manifest, tablice ciągów, języki i informacje o wersji | Należący do wywołującego launcher Apktool; [przewodnik zasobów](docs/apktool-resource-analysis.md) |
| Oprogramowanie układowe | Regiony, wyniki wyodrębniania i przekazanie do analizy kodu natywnego | Binwalk / Unblob w systemie Linux; [przewodnik oprogramowania układowego](docs/firmware-analysis.md) |
| Pakiety i zasoby | Spisy plików, skróty, pliki plist, struktura pakietów Apple i wyodrębnione zasoby | [Przewodnik artefaktów i JavaScript](docs/javascript-artifact-reconstruction.md), [aplikacje Apple](docs/apple-application-analysis.md) |
| Zachowanie procesów | Wyjście terminala, interakcje, obserwacje zakończenia i systemu plików oraz porównania uruchomień | Linux/macOS z natywnym PTY; [przechwytywanie procesów](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Obsługiwane formaty natywne i platformy zależą od dostawcy analizy. Zobacz [k
## Przykłady zastosowań
[![Ilustracje studiów przypadku panoramowania dźwięku w DX-Ball, mostka schowka w Notion i pierścienia pocisków w TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: odtworzenie obliczania panoramy dźwięku
Prześledź wywołanie dźwięku do funkcji pomocniczej przeliczającej pozycję na panoramę, sprawdź instrukcje i przekształć niepełny pseudokod w C. Odtworzona implementacja przechodzi 3 205 przypadków dla oryginalnego x86 i odtwarza wszystkie 63 bajty skompilowanej funkcji.
@@ -200,7 +205,7 @@ REA uruchamia Hoppera, gdy wymaga tego operacja. W systemie macOS przy pierwszym
<details>
<summary><strong>Co daje zainstalowanie umiejętności z skills.sh?</strong></summary>
Umiejętność dostarcza agentowi instrukcje prowadzenia analizy. Użyj `rea setup`, aby zarejestrować serwer MCP REA i zainstalować pasujące instrukcje, a następnie uruchom agenta ponownie. Zobacz [instalację samej umiejętności](docs/installation.md#skill-only-installation).
Umiejętność dostarcza agentowi instrukcje prowadzenia analizy. Użyj `npx rea-agents setup`, aby zarejestrować serwer MCP REA i zainstalować pasujące instrukcje, a następnie uruchom agenta ponownie. Zobacz [instalację samej umiejętności](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ Zacznij od [przewodników z przykładami](https://rea.tools/guides/) na stronie
Zgłaszaj podatności zgodnie z [SECURITY.md](SECURITY.md).
## Współtworzenie
Chętnie przyjmiemy Twoją pomoc w rozwoju REA! [Otwórz zgłoszenie](https://github.com/morluto/rea/issues), aby poinformować o błędzie lub zaproponować funkcję, albo [wyślij pull request](https://github.com/morluto/rea/pulls) z ulepszeniami kodu lub dokumentacji.
Zobacz [CONTRIBUTING.md](CONTRIBUTING.md), aby poznać konfigurację środowiska programistycznego i kontrole, [testowanie](docs/testing.md), aby poznać ścieżki weryfikacji, oraz [mapę architektury](docs/architecture.mermaid), aby poznać strukturę projektu.
## Linki projektu
[Strona internetowa](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Zgłoszenia](https://github.com/morluto/rea/issues) · [Bezpieczeństwo](SECURITY.md)
## Historia gwiazdek
🎉 **30 000 gwiazdek na GitHubie — dziękujemy!**
🎉 **50 000 gwiazdek na GitHubie — dziękujemy!**
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
@@ -280,6 +275,12 @@ Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują no
REA dostarcza narzędzia do zgodnych z prawem badań z zakresu inżynierii wstecznej, analizy i odtwarzania. Odpowiadasz za uzyskanie wymaganych zezwoleń i przestrzeganie obowiązującego prawa. Projekt nie popiera działań nielegalnych ani nieautoryzowanych.
## Współtworzenie
Chętnie przyjmiemy Twoją pomoc w rozwoju REA! [Otwórz zgłoszenie](https://github.com/morluto/rea/issues), aby poinformować o błędzie lub zaproponować funkcję, albo [wyślij pull request](https://github.com/morluto/rea/pulls) z ulepszeniami kodu lub dokumentacji.
Zobacz [CONTRIBUTING.md](CONTRIBUTING.md), aby poznać konfigurację środowiska programistycznego i kontrole, [testowanie](docs/testing.md), aby poznać ścieżki weryfikacji, oraz [mapę architektury](docs/architecture.mermaid), aby poznać strukturę projektu.
## Licencja
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Faça engenharia reversa de qualquer coisa
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA inicia sua ponte de análise dentro do Hopper enquanto inspeciona um binário nativo" width="1200" />
<br />
<br /><br />
<table aria-label="Comunidade REA">
<tr>
@@ -135,13 +135,16 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](https://rea.tools/guides/native/) |
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](docs/binary-diagnostics.md) |
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal; [guia de EVM sem execução](docs/evm-bytecode.md) |
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal no Linux x64; [guia de EVM sem execução](docs/evm-bytecode.md) |
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador no Linux x64; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](https://rea.tools/guides/javascript/) |
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](https://rea.tools/guides/browser/) |
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](docs/web-network-captures.md) |
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](docs/managed-code-analysis.md) |
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS; [guia de Android](docs/android-analysis.md) |
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, pacotes, processos, logs, despejos, capturas de tela e transferências de APK/arquivos | adb fornecido pelo chamador (emulador ou aparelho); [guia de ADB](docs/adb-device-analysis.md) |
| Projetos JEB | Unidades de projeto do motor, hashes de artefatos e pseudocódigo de tipos/métodos | Um cliente JEB iniciado pelo chamador servindo MCP, selecionado com REA_JEB_MCP_URL; [guia de JEB](docs/jeb-analysis.md) |
| Recursos do Android | Manifesto decodificado, tabelas de strings, idiomas e fatos de versão | Lançador do Apktool fornecido pelo chamador; [guia de recursos](docs/apktool-resource-analysis.md) |
| Firmware | Regiões, resultados de extração e encaminhamentos à análise nativa | Binwalk / Unblob no Linux; [guia de firmware](docs/firmware-analysis.md) |
| Pacotes e recursos | Inventários de arquivos, digests, plists, estrutura de bundles Apple e recursos extraídos | [Guia de artefatos e JavaScript](docs/javascript-artifact-reconstruction.md), [aplicativos Apple](docs/apple-application-analysis.md) |
| Comportamento de processos | Saída do terminal, interações, observações de encerramento e do sistema de arquivos, e comparações entre execuções | Linux/macOS com PTY nativo; [captura de processos](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Os formatos nativos e os sistemas anfitriões compatíveis variam por provedor.
## Casos de uso
[![Ilustrações dos estudos de panoramização de áudio do DX-Ball, da ponte da área de transferência do Notion e do anel de projéteis do TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruir um cálculo de panorâmica de áudio
Siga uma chamada de áudio até a função auxiliar que converte posição em panorâmica, inspecione as instruções e transforme pseudocódigo incompleto em C. A reconstrução passa em 3.205 casos com o x86 original e reproduz todos os 63 bytes da função compilada.
@@ -200,7 +205,7 @@ O REA inicia o Hopper quando uma operação precisa dele. No macOS, um diálogo
<details>
<summary><strong>O que faz a instalação da skill pelo skills.sh?</strong></summary>
A skill fornece instruções de investigação ao seu agente. Use `rea setup` para registrar o servidor MCP do REA e instalar as instruções correspondentes, depois reinicie seu agente. Consulte [instalação apenas da skill](docs/installation.md#skill-only-installation).
A skill fornece instruções de investigação ao seu agente. Use `npx rea-agents setup` para registrar o servidor MCP do REA e instalar as instruções correspondentes, depois reinicie seu agente. Consulte [instalação apenas da skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ Comece pelos [guias práticos](https://rea.tools/guides/) do site. Para opções
Relate vulnerabilidades conforme [SECURITY.md](SECURITY.md).
## Contribuir
Sua ajuda com o REA é bem-vinda! [Abra uma issue](https://github.com/morluto/rea/issues) para relatar um bug ou sugerir uma funcionalidade, ou [envie um pull request](https://github.com/morluto/rea/pulls) para melhorar o código ou a documentação.
Consulte [CONTRIBUTING.md](CONTRIBUTING.md) para configurar o ambiente de desenvolvimento e as verificações, o [guia de testes](docs/testing.md) para os fluxos de verificação e o [mapa da arquitetura](docs/architecture.mermaid) para a estrutura do projeto.
## Links do projeto
[Site](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Segurança](SECURITY.md)
## Histórico de estrelas
🎉 **30.000 estrelas no GitHub — muito obrigado!**
🎉 **50.000 estrelas no GitHub — muito obrigado!**
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
@@ -280,6 +275,12 @@ Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam b
O REA fornece ferramentas para pesquisa, análise e reconstrução por engenharia reversa dentro da lei. Você é responsável por obter as autorizações necessárias e cumprir as leis aplicáveis. O projeto não apoia usos ilegais ou não autorizados.
## Contribuir
Sua ajuda com o REA é bem-vinda! [Abra uma issue](https://github.com/morluto/rea/issues) para relatar um bug ou sugerir uma funcionalidade, ou [envie um pull request](https://github.com/morluto/rea/pulls) para melhorar o código ou a documentação.
Consulte [CONTRIBUTING.md](CONTRIBUTING.md) para configurar o ambiente de desenvolvimento e as verificações, o [guia de testes](docs/testing.md) para os fluxos de verificação e o [mapa da arquitetura](docs/architecture.mermaid) para a estrutura do projeto.
## Licença
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Реверс-инжиниринг чего угодно
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA запускает мост анализа внутри Hopper при исследовании нативного бинарного файла" width="1200" />
<br />
<br /><br />
<table aria-label="Сообщество REA">
<tr>
@@ -135,13 +135,16 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/guides/native/) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/guides/javascript/) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/guides/browser/) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS; [руководство по Android](docs/android-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](docs/adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](docs/jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](docs/apktool-resource-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](docs/firmware-analysis.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](docs/javascript-artifact-reconstruction.md), [приложения Apple](docs/apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
## Примеры
[![Иллюстрации примеров панорамирования звука в DX-Ball, моста буфера обмена Notion и кольца пуль в TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: восстановление расчёта звуковой панорамы
Проследите звуковой вызов до функции, преобразующей координату в значение панорамы, изучите инструкции и превратите неполный псевдокод в C. Восстановленная реализация проходит 3 205 тестов с исходным x86-кодом и воспроизводит все 63 байта скомпилированной функции.
@@ -200,7 +205,7 @@ REA запускает Hopper, когда он нужен для операци
<details>
<summary><strong>Что даёт установка skill с skills.sh?</strong></summary>
Skill предоставляет агенту инструкции по исследованию. Используйте `rea setup`, чтобы зарегистрировать MCP-сервер REA и установить соответствующие инструкции, затем перезапустите агента. См. [установку только skill](docs/installation.md#skill-only-installation).
Skill предоставляет агенту инструкции по исследованию. Используйте `npx rea-agents setup`, чтобы зарегистрировать MCP-сервер REA и установить соответствующие инструкции, затем перезапустите агента. См. [установку только skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ npx rea-agents@latest setup
Сообщайте об уязвимостях согласно [SECURITY.md](SECURITY.md).
## Участие в проекте
Будем рады вашей помощи с REA! [Откройте issue](https://github.com/morluto/rea/issues), чтобы сообщить об ошибке или предложить функцию, либо [отправьте pull request](https://github.com/morluto/rea/pulls) с улучшениями кода или документации.
Настройка среды разработки и проверки описаны в [CONTRIBUTING.md](CONTRIBUTING.md), направления проверки — в [руководстве по тестированию](docs/testing.md), а структура проекта — на [схеме архитектуры](docs/architecture.mermaid).
## Ссылки проекта
[Сайт](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Безопасность](SECURITY.md)
## История звёзд
🎉 **30 000 звёзд на GitHub — спасибо!**
🎉 **50 000 звёзд на GitHub — спасибо!**
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA предоставляет инструменты для законных исследований, анализа и реконструкции с помощью реверс-инжиниринга. Вы отвечаете за получение необходимых разрешений и соблюдение применимых законов. Проект не поддерживает незаконное или несанкционированное использование.
## Участие в проекте
Будем рады вашей помощи с REA! [Откройте issue](https://github.com/morluto/rea/issues), чтобы сообщить об ошибке или предложить функцию, либо [отправьте pull request](https://github.com/morluto/rea/pulls) с улучшениями кода или документации.
Настройка среды разработки и проверки описаны в [CONTRIBUTING.md](CONTRIBUTING.md), направления проверки — в [руководстве по тестированию](docs/testing.md), а структура проекта — на [схеме архитектуры](docs/architecture.mermaid).
## Лицензия
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA เริ่มบริดจ์การวิเคราะห์ภายใน Hopper ขณะตรวจสอบไบนารีเนทีฟ" width="1200" />
<br />
<br /><br />
<table aria-label="ชุมชน REA">
<tr>
@@ -135,13 +135,16 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
| ---------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| ไบนารีเนทีฟ | โค้ดเทียม แอสเซมบลี สตริง สัญลักษณ์ การเรียก และการอ้างอิง | Hopper, Ghidra หรือ IDA; [การวิเคราะห์เนทีฟ](https://rea.tools/guides/native/) |
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](docs/binary-diagnostics.md) |
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหก; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียม; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](https://rea.tools/guides/javascript/) |
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](https://rea.tools/guides/browser/) |
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](docs/web-network-captures.md) |
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](docs/managed-code-analysis.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS; [คู่มือ Android](docs/android-analysis.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](docs/android-analysis.md) |
| อุปกรณ์ Android | อุปกรณ์ แพ็กเกจ โพรเซส บันทึก ดัมพ์ ภาพหน้าจอ และการถ่ายโอน APK/ไฟล์ | adb ที่ผู้เรียกจัดเตรียม (โปรแกรมจำลองหรืออุปกรณ์จริง); [คู่มือ ADB](docs/adb-device-analysis.md) |
| โปรเจกต์ JEB | หน่วยโปรเจกต์จากเอนจิน, แฮชของอาร์ติแฟกต์ และซูโดโค้ดของไทป์/เมท็อด | ไคลเอนต์ JEB ที่ผู้เรียกเริ่มและให้บริการ MCP เลือกด้วย REA_JEB_MCP_URL; [คู่มือ JEB](docs/jeb-analysis.md) |
| ทรัพยากร Android | ไฟล์ manifest ที่ถอดรหัสแล้ว ตารางสตริง ภาษา และข้อมูลเวอร์ชัน | ตัวเรียก Apktool ที่ผู้เรียกจัดเตรียม; [คู่มือทรัพยากร](docs/apktool-resource-analysis.md) |
| เฟิร์มแวร์ | พื้นที่ข้อมูล ผลการแตกไฟล์ และการส่งต่อไปวิเคราะห์เนทีฟ | Binwalk / Unblob บน Linux; [คู่มือเฟิร์มแวร์](docs/firmware-analysis.md) |
| แพ็กเกจและทรัพยากร | รายการไฟล์ ค่าแฮช plist โครงสร้างบันเดิลของ Apple และทรัพยากรที่แตกออกมา | [คู่มืออาร์ติแฟกต์และ JavaScript](docs/javascript-artifact-reconstruction.md), [แอปพลิเคชัน Apple](docs/apple-application-analysis.md) |
| พฤติกรรมของโปรเซส | เอาต์พุตเทอร์มินัล การโต้ตอบ ข้อมูลการสิ้นสุดและระบบไฟล์ที่สังเกตได้ และการเปรียบเทียบการรัน | Linux/macOS ที่มี PTY เนทีฟ; [การบันทึกโปรเซส](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
## ตัวอย่างการใช้งาน
[![ภาพประกอบกรณีศึกษาการแพนเสียงใน DX-Ball บริดจ์คลิปบอร์ดของ Notion และวงแหวนกระสุนใน TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: สร้างการคำนวณแพนเสียงขึ้นใหม่
ติดตามการเรียกเสียงไปยังฟังก์ชันช่วยแปลงตำแหน่งเป็นค่าแพน ตรวจสอบคำสั่ง และแปลงโค้ดเทียมที่ยังไม่สมบูรณ์เป็น C การสร้างขึ้นใหม่นี้ผ่านการทดสอบ 3,205 กรณีเทียบกับ x86 ต้นฉบับ และสร้างไบต์ทั้ง 63 ไบต์ของฟังก์ชันที่คอมไพล์แล้วได้ตรงกัน
@@ -200,7 +205,7 @@ REA เริ่ม Hopper เมื่อการดำเนินการ
<details>
<summary><strong>การติดตั้งสกิลจาก skills.sh ทำอะไร?</strong></summary>
สกิลให้คำแนะนำการตรวจสอบแก่เอเจนต์ ใช้ `rea setup` เพื่อลงทะเบียนเซิร์ฟเวอร์ MCP ของ REA และติดตั้งคำแนะนำที่ตรงกัน แล้วเริ่มเอเจนต์ใหม่ ดู[การติดตั้งเฉพาะสกิล](docs/installation.md#skill-only-installation)
สกิลให้คำแนะนำการตรวจสอบแก่เอเจนต์ ใช้ `npx rea-agents setup` เพื่อลงทะเบียนเซิร์ฟเวอร์ MCP ของ REA และติดตั้งคำแนะนำที่ตรงกัน แล้วเริ่มเอเจนต์ใหม่ ดู[การติดตั้งเฉพาะสกิล](docs/installation.md#skill-only-installation)
</details>
@@ -252,19 +257,9 @@ npx rea-agents@latest setup
รายงานช่องโหว่ผ่าน [SECURITY.md](SECURITY.md)
## การมีส่วนร่วม
เรายินดีรับความช่วยเหลือในการพัฒนา REA! [เปิด issue](https://github.com/morluto/rea/issues) เพื่อรายงานบั๊กหรือเสนอฟีเจอร์ หรือ[ส่ง pull request](https://github.com/morluto/rea/pulls) เพื่อปรับปรุงโค้ดหรือเอกสาร
ดู [CONTRIBUTING.md](CONTRIBUTING.md) สำหรับการตั้งค่าสภาพแวดล้อมพัฒนาและการตรวจสอบ ดู[การทดสอบ](docs/testing.md) สำหรับแนวทางการตรวจยืนยัน และ[แผนผังสถาปัตยกรรม](docs/architecture.mermaid) สำหรับโครงสร้างโปรเจกต์
## ลิงก์ของโปรเจกต์
[เว็บไซต์](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [ความปลอดภัย](SECURITY.md)
## ประวัติดาว
🎉 **30,000 ดาวบน GitHub — ขอบคุณทุกคน!**
🎉 **50,000 ดาวบน GitHub — ขอบคุณทุกคน!**
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA มีเครื่องมือสำหรับการวิจัยวิศวกรรมย้อนกลับ การวิเคราะห์ และการสร้างขึ้นใหม่อย่างถูกกฎหมาย คุณมีหน้าที่ขออนุญาตตามที่จำเป็นและปฏิบัติตามกฎหมายที่เกี่ยวข้อง โปรเจกต์นี้ไม่สนับสนุนการใช้งานที่ผิดกฎหมายหรือไม่ได้รับอนุญาต
## การมีส่วนร่วม
เรายินดีรับความช่วยเหลือในการพัฒนา REA! [เปิด issue](https://github.com/morluto/rea/issues) เพื่อรายงานบั๊กหรือเสนอฟีเจอร์ หรือ[ส่ง pull request](https://github.com/morluto/rea/pulls) เพื่อปรับปรุงโค้ดหรือเอกสาร
ดู [CONTRIBUTING.md](CONTRIBUTING.md) สำหรับการตั้งค่าสภาพแวดล้อมพัฒนาและการตรวจสอบ ดู[การทดสอบ](docs/testing.md) สำหรับแนวทางการตรวจยืนยัน และ[แผนผังสถาปัตยกรรม](docs/architecture.mermaid) สำหรับโครงสร้างโปรเจกต์
## สัญญาอนุญาต
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Her şeyi tersine mühendislikle inceleyin
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA, yerel bir ikili dosyayı incelerken Hopper içinde analiz köprüsünü başlatıyor" width="1200" />
<br />
<br /><br />
<table aria-label="REA topluluğu">
<tr>
@@ -135,13 +135,16 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Yerel makine kodu içeren ikili dosyalar | Sözde kod, assembly kodu, dizeler, semboller, çağrılar ve referanslar | Hopper, Ghidra veya IDA; [yerel kod analizi](https://rea.tools/guides/native/) |
| Çevrimdışı ELF yapısı | Bölümler, segmentler, özgün semboller/yeniden konumlandırmalar ve statik analizden olası güvenlik önlemleri | Linux x64 üzerinde çağıranın sağladığı pwntools; [ikili dosya tanılama](docs/binary-diagnostics.md) |
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Linux x64 üzerinde çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](https://rea.tools/guides/javascript/) |
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](https://rea.tools/guides/browser/) |
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR; mitmproxy'nin kendi biçimindeki yakalamalar için Linux üzerinde mitmdump; [ağ yakalama rehberi](docs/web-network-captures.md) |
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](docs/managed-code-analysis.md) |
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
| Android cihazları | Cihazlar, paketler, süreçler, günlükler, dökümler, ekran görüntüleri ve APK/dosya aktarımları | Çağıranın sağladığı adb (emülatör veya cihaz); [ADB rehberi](docs/adb-device-analysis.md) |
| JEB projeleri | Motor destekli proje birimleri, artefakt özetleri ve tür/metot sözdekodu | Çağıranın başlattığı, MCP sunan bir JEB istemcisi, REA_JEB_MCP_URL ile seçilir; [JEB rehberi](docs/jeb-analysis.md) |
| Android kaynakları | Çözülmüş manifest, dize tabloları, diller ve sürüm bilgileri | Çağıranın sağladığı Apktool başlatıcısı; [kaynak rehberi](docs/apktool-resource-analysis.md) |
| Donanım yazılımı | Bölgeler, çıkarma sonuçları ve yerel kod analizine devirler | Linux üzerinde Binwalk / Unblob; [donanım yazılımı rehberi](docs/firmware-analysis.md) |
| Paketler ve kaynaklar | Dosya envanterleri, özet değerleri, plist'ler, Apple paket yapısı ve çıkarılmış kaynaklar | [Artefakt ve JavaScript rehberi](docs/javascript-artifact-reconstruction.md), [Apple uygulamaları](docs/apple-application-analysis.md) |
| Süreç davranışı | Terminal çıktısı, etkileşimler, sonlanma ve dosya sistemi gözlemleri, çalıştırma karşılaştırmaları | Yerel PTY ile Linux/macOS; [süreç yakalama](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Yerel makine kodu içeren ikili dosya biçimleri ve ana bilgisayar desteği sağ
## Örnek çalışmalar
[![DX-Ball ses kaydırma, Notion pano köprüsü ve TH04 mermi halkası örneklerinin çizimleri](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: Sesin stereo konumlandırma hesabını yeniden oluşturma
Bir ses çağrısından konumu stereo konumlandırmaya dönüştüren yardımcı fonksiyona ilerleyin, talimatları inceleyin ve eksik sözde kodu C'ye dönüştürün. Yeniden oluşturulan kod, özgün x86 üzerinde 3.205 test durumunu geçer ve derlenmiş fonksiyonun 63 baytının tamamını yeniden üretir.
@@ -200,7 +205,7 @@ REA, bir işlem gerektirdiğinde Hopper'ı başlatır. macOS'ta ilk çalıştır
<details>
<summary><strong>skills.sh üzerinden skill yüklemek ne yapar?</strong></summary>
Skill, ajanınıza araştırma talimatları sağlar. REA'nın MCP sunucusunu kaydetmek ve uyumlu talimatları yüklemek için `rea setup` kullanın, ardından ajanınızı yeniden başlatın. [Yalnızca skill yükleme](docs/installation.md#skill-only-installation) belgesine bakın.
Skill, ajanınıza araştırma talimatları sağlar. REA'nın MCP sunucusunu kaydetmek ve uyumlu talimatları yüklemek için `npx rea-agents setup` kullanın, ardından ajanınızı yeniden başlatın. [Yalnızca skill yükleme](docs/installation.md#skill-only-installation) belgesine bakın.
</details>
@@ -252,19 +257,9 @@ Web sitesindeki [uygulamalı rehberlerden](https://rea.tools/guides/) başlayın
Güvenlik açıklarını [SECURITY.md](SECURITY.md) üzerinden bildirin.
## Katkıda bulunma
REA'ya katkınızı bekliyoruz! Hata bildirmek veya özellik önermek için bir [issue açın](https://github.com/morluto/rea/issues); kodu veya belgeleri geliştirmek için bir [pull request gönderin](https://github.com/morluto/rea/pulls).
Geliştirme ortamı ve kontroller için [CONTRIBUTING.md](CONTRIBUTING.md), doğrulama süreçleri için [test rehberi](docs/testing.md) ve proje yapısı için [mimari harita](docs/architecture.mermaid) belgelerine bakın.
## Proje bağlantıları
[Web sitesi](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Güvenlik](SECURITY.md)
## Yıldız geçmişi
🎉 **GitHub'da 30.000 yıldız — teşekkürler!**
🎉 **GitHub'da 50.000 yıldız — teşekkürler!**
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
@@ -280,6 +275,12 @@ REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve d
REA, yasal tersine mühendislik araştırması, analizi ve yeniden oluşturma için araçlar sağlar. Gerekli izinleri almak ve geçerli yasalara uymak sizin sorumluluğunuzdadır. Proje yasa dışı veya yetkisiz kullanımı desteklemez.
## Katkıda bulunma
REA'ya katkınızı bekliyoruz! Hata bildirmek veya özellik önermek için bir [issue açın](https://github.com/morluto/rea/issues); kodu veya belgeleri geliştirmek için bir [pull request gönderin](https://github.com/morluto/rea/pulls).
Geliştirme ortamı ve kontroller için [CONTRIBUTING.md](CONTRIBUTING.md), doğrulama süreçleri için [test rehberi](docs/testing.md) ve proje yapısı için [mimari harita](docs/architecture.mermaid) belgelerine bakın.
## Lisans
[MIT](LICENSE)
+30 -29
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Реверс-інжиніринг будь-чого
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA запускає міст аналізу всередині Hopper під час дослідження нативного бінарного файла" width="1200" />
<br />
<br /><br />
<table aria-label="Спільнота REA">
<tr>
@@ -131,20 +131,23 @@ npx rea-agents@latest setup
REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а також npm. Додаткові інструменти й підтримувані системи залежать від цілі:
| Ціль | Що повертає REA | Вимоги й посібник |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/guides/native/) |
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення; [посібник EVM без запуску](docs/evm-bytecode.md) |
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/guides/javascript/) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/guides/browser/) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS; [посібник Android](docs/android-analysis.md) |
| Прошивки | Області, результати видобування й передавання до нативного аналізу | Binwalk / Unblob у Linux; [посібник прошивок](docs/firmware-analysis.md) |
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
| Ціль | Що повертає REA | Вимоги й посібник |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/guides/native/) |
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](docs/evm-bytecode.md) |
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/guides/javascript/) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/guides/browser/) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](docs/android-analysis.md) |
| Пристрої Android | Пристрої, пакети, процеси, журнали, дампи, знімки екрана та передавання APK/файлів | adb, наданий викликаючою стороною (емулятор або пристрій); [підручник ADB](docs/adb-device-analysis.md) |
| Проєкти JEB | Єдиниці проєкту від рушія, дайджести артефактів і псевдокод типів/методів | Запущений викликаною стороною клієнт JEB з MCP, обирається через REA_JEB_MCP_URL; [посібник JEB](docs/jeb-analysis.md) |
| Ресурси Android | Декодований маніфест, таблиці рядків, мови та відомості про версію | Засіб запуску Apktool, наданий викликаючою стороною; [підручник ресурсів](docs/apktool-resource-analysis.md) |
| Прошивки | Області, результати видобування й передавання до нативного аналізу | Binwalk / Unblob у Linux; [посібник прошивок](docs/firmware-analysis.md) |
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
Статична перевірка JavaScript і .NET читає надані файли, не запускаючи застосунок. Захоплення під час виконання запускає вибрану ціль або взаємодіє з нею з правами вашого користувача; відповідні посібники описують його вплив.
@@ -154,6 +157,8 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
## Приклади
[![Ілюстрації прикладів панорамування звуку в DX-Ball, мосту буфера обміну Notion та кільця куль у TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: відновлення розрахунку звукової панорами
Простежте звуковий виклик до допоміжної функції, що перетворює координату на панорамування, перевірте інструкції та перетворіть неповний псевдокод на C. Відновлена реалізація проходить 3 205 тестів з оригінальним x86-кодом і відтворює всі 63 байти скомпільованої функції.
@@ -200,7 +205,7 @@ REA запускає Hopper, коли він потрібен для опера
<details>
<summary><strong>Що дає встановлення skill із skills.sh?</strong></summary>
Skill надає агенту інструкції дослідження. Використовуйте `rea setup`, щоб зареєструвати MCP-сервер REA та встановити відповідні інструкції, а потім перезапустіть агента. Дивіться [встановлення лише skill](docs/installation.md#skill-only-installation).
Skill надає агенту інструкції дослідження. Використовуйте `npx rea-agents setup`, щоб зареєструвати MCP-сервер REA та встановити відповідні інструкції, а потім перезапустіть агента. Дивіться [встановлення лише skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ npx rea-agents@latest setup
Повідомляйте про вразливості згідно з [SECURITY.md](SECURITY.md).
## Участь у проєкті
Будемо раді вашій допомозі з REA! [Відкрийте issue](https://github.com/morluto/rea/issues), щоб повідомити про помилку чи запропонувати функцію, або [надішліть pull request](https://github.com/morluto/rea/pulls) з поліпшеннями коду чи документації.
Налаштування середовища розробки й перевірки описано в [CONTRIBUTING.md](CONTRIBUTING.md), шляхи верифікації — у [посібнику тестування](docs/testing.md), а структуру проєкту — на [схемі архітектури](docs/architecture.mermaid).
## Посилання проєкту
[Сайт](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Безпека](SECURITY.md)
## Історія зірок
🎉 **30 000 зірок на GitHub — дякуємо!**
🎉 **50 000 зірок на GitHub — дякуємо!**
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA надає інструменти для законних досліджень, аналізу й реконструкції за допомогою реверс-інжинірингу. Ви відповідаєте за отримання необхідних дозволів і дотримання застосовних законів. Проєкт не підтримує незаконне або несанкціоноване використання.
## Участь у проєкті
Будемо раді вашій допомозі з REA! [Відкрийте issue](https://github.com/morluto/rea/issues), щоб повідомити про помилку чи запропонувати функцію, або [надішліть pull request](https://github.com/morluto/rea/pulls) з поліпшеннями коду чи документації.
Налаштування середовища розробки й перевірки описано в [CONTRIBUTING.md](CONTRIBUTING.md), шляхи верифікації — у [посібнику тестування](docs/testing.md), а структуру проєкту — на [схемі архітектури](docs/architecture.mermaid).
## Ліцензія
[MIT](LICENSE)
+19 -18
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Kỹ thuật dịch ngược cho mọi thứ
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA khởi chạy cầu nối phân tích bên trong Hopper khi kiểm tra tệp nhị phân mã máy" width="1200" />
<br />
<br /><br />
<table aria-label="Cộng đồng REA">
<tr>
@@ -135,13 +135,16 @@ REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với np
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](https://rea.tools/guides/native/) |
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](docs/binary-diagnostics.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](https://rea.tools/guides/javascript/) |
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](https://rea.tools/guides/browser/) |
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](docs/web-network-captures.md) |
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](docs/managed-code-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS; [hướng dẫn Android](docs/android-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](docs/android-analysis.md) |
| Thiết bị Android | Thiết bị, gói, tiến trình, nhật ký, dump, ảnh chụp màn hình và truyền APK/tệp | adb do nơi gọi cung cấp (trình giả lập hoặc thiết bị); [hướng dẫn ADB](docs/adb-device-analysis.md) |
| Dự án JEB | Đơn vị dự án từ engine, hash của artifact và mã giả của kiểu/phương thức | Một ứng dụng JEB do nơi gọi khởi động, phục vụ MCP, chọn bằng REA_JEB_MCP_URL; [hướng dẫn JEB](docs/jeb-analysis.md) |
| Tài nguyên Android | Manifest đã giải mã, bảng chuỗi, ngôn ngữ và thông tin phiên bản | Trình khởi chạy Apktool do nơi gọi cung cấp; [hướng dẫn tài nguyên](docs/apktool-resource-analysis.md) |
| Phần sụn | Các vùng, kết quả trích xuất và dữ liệu chuyển sang phân tích mã máy | Binwalk / Unblob trên Linux; [hướng dẫn phần sụn](docs/firmware-analysis.md) |
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](docs/javascript-artifact-reconstruction.md), [ứng dụng Apple](docs/apple-application-analysis.md) |
| Hành vi tiến trình | Đầu ra terminal, tương tác, quan sát khi thoát và hệ thống tệp, cùng so sánh các lần chạy | Linux/macOS có PTY gốc; [ghi lại tiến trình](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Kiểm tra tĩnh JavaScript và .NET đọc các tệp được cung cấp mà k
## Các nghiên cứu điển hình
[![Minh họa các ví dụ về cân bằng âm thanh DX-Ball, cầu nối bảng nhớ tạm Notion và vòng đạn TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: tái tạo phép tính phân bố âm thanh trái phải
Lần theo lời gọi âm thanh đến hàm hỗ trợ chuyển vị trí thành giá trị phân bố âm thanh, kiểm tra các lệnh và chuyển mã giả chưa đầy đủ sang C. Bản tái tạo vượt qua 3.205 trường hợp kiểm thử với x86 gốc và tái tạo đủ 63 byte của hàm đã biên dịch.
@@ -200,7 +205,7 @@ REA khởi chạy Hopper khi một thao tác cần đến nó. Trên macOS, hộ
<details>
<summary><strong>Cài skill từ skills.sh có tác dụng gì?</strong></summary>
Skill cung cấp hướng dẫn điều tra cho tác nhân. Dùng `rea setup` để đăng ký máy chủ MCP của REA và cài hướng dẫn tương ứng, sau đó khởi động lại tác nhân. Xem [chỉ cài skill](docs/installation.md#skill-only-installation).
Skill cung cấp hướng dẫn điều tra cho tác nhân. Dùng `npx rea-agents setup` để đăng ký máy chủ MCP của REA và cài hướng dẫn tương ứng, sau đó khởi động lại tác nhân. Xem [chỉ cài skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,19 +257,9 @@ Bắt đầu với [hướng dẫn thực hành](https://rea.tools/guides/) trê
Báo cáo lỗ hổng theo [SECURITY.md](SECURITY.md).
## Đóng góp
Chúng tôi hoan nghênh bạn giúp phát triển REA! [Mở issue](https://github.com/morluto/rea/issues) để báo lỗi hoặc đề xuất tính năng, hoặc [gửi pull request](https://github.com/morluto/rea/pulls) để cải thiện mã hay tài liệu.
Xem [CONTRIBUTING.md](CONTRIBUTING.md) về thiết lập môi trường phát triển và các bước kiểm tra, [hướng dẫn kiểm thử](docs/testing.md) về các luồng xác minh và [sơ đồ kiến trúc](docs/architecture.mermaid) về cấu trúc dự án.
## Liên kết dự án
[Trang web](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Bảo mật](SECURITY.md)
## Lịch sử sao
🎉 **30.000 sao trên GitHub — xin cảm ơn!**
🎉 **50.000 sao trên GitHub — xin cảm ơn!**
Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính năng, kiểm thử bản dựng và đóng góp bản sửa lỗi.
@@ -280,6 +275,12 @@ Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính n
REA cung cấp công cụ cho nghiên cứu dịch ngược, phân tích và tái tạo hợp pháp. Bạn có trách nhiệm có được các quyền cho phép cần thiết và tuân thủ luật áp dụng. Dự án không ủng hộ việc sử dụng trái pháp luật hoặc không được cho phép.
## Đóng góp
Chúng tôi hoan nghênh bạn giúp phát triển REA! [Mở issue](https://github.com/morluto/rea/issues) để báo lỗi hoặc đề xuất tính năng, hoặc [gửi pull request](https://github.com/morluto/rea/pulls) để cải thiện mã hay tài liệu.
Xem [CONTRIBUTING.md](CONTRIBUTING.md) về thiết lập môi trường phát triển và các bước kiểm tra, [hướng dẫn kiểm thử](docs/testing.md) về các luồng xác minh và [sơ đồ kiến trúc](docs/architecture.mermaid) về cấu trúc dự án.
## Giấy phép
[MIT](LICENSE)
+20 -19
View File
@@ -1,8 +1,8 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:逆向分析一切
# REA:逆向一切
### 通過一個 MCP 服務,逆向分析二進位檔案、應用程式和執行階段行為。
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA 在 Hopper 中啟動分析橋,檢查原生二進位檔案" width="1200" />
<br />
<br /><br />
<table aria-label="REA 社群">
<tr>
@@ -135,13 +135,16 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| --------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 原生二進位檔案 | 偽程式碼、組合語言、字串、符號、呼叫和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
| 離線 ELF 佈局 | 節、段、原始符號/重定位資訊及靜態防護機制候選項 | Linux x64 上由呼叫方提供的 pwntools;[二進位診斷](docs/binary-diagnostics.md) |
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | 本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | 呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | Linux x64 上的本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](https://rea.tools/guides/javascript/) |
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](https://rea.tools/guides/browser/) |
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](docs/web-network-captures.md) |
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](docs/managed-code-analysis.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 裝置 | 裝置、套件、程序、日誌、傾印、螢幕擷取以及 APK/檔案傳輸 | 呼叫端提供的 adb(模擬器或實體裝置);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 專案 | 引擎支援的專案單元、成品摘要和型別/方法的虛擬碼 | 由呼叫端啟動、提供 MCP 的 JEB 用戶端,透過 REA_JEB_MCP_URL 選擇;[JEB 指南](docs/jeb-analysis.md) |
| Android 資源 | 解碼後的清單、字串表、語系和版本資訊 | 呼叫端提供的 Apktool 啟動器;[資源指南](docs/apktool-resource-analysis.md) |
| 韌體 | 區域、提取結果和轉交原生分析的內容 | Linux 上的 Binwalk / Unblob;[韌體指南](docs/firmware-analysis.md) |
| 軟體包與資源 | 檔案清單、摘要、plist、Apple bundle 結構和提取的資源 | [製品與 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 應用](docs/apple-application-analysis.md) |
| 處理程序行為 | 終端輸出、互動、退出和檔案系統觀察結果,以及執行對比 | 支援原生 PTY 的 Linux/macOS;[處理程序擷取](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
## 案例
[![DX-Ball 聲音平移、Notion 剪貼簿橋接與 TH04 彈幕環案例的插圖](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:重建聲像計算
沿聲音呼叫追蹤到根據位置計算聲像的輔助函數,檢查指令,將不完整的偽程式碼轉為 C。重建結果通過了 3,205 個原始 x86 測試用例,並復現了編譯後函數的全部 63 個位元組。
@@ -202,7 +207,7 @@ REA 會在操作需要時啟動 Hopper。在 macOS 上,首次執行時可能
<details>
<summary><strong>從 skills.sh 安裝 skill 有什麼作用?</strong></summary>
skill 為 AI 代理提供調查指引。使用 `rea setup` 註冊 REA 的 MCP 服務並安裝對應的指引,然後重新啟動 AI 代理。見[僅安裝 skill](docs/installation.md#skill-only-installation)。
skill 為 AI 代理提供調查指引。使用 `npx rea-agents setup` 註冊 REA 的 MCP 服務並安裝對應的指引,然後重新啟動 AI 代理。見[僅安裝 skill](docs/installation.md#skill-only-installation)。
</details>
@@ -254,19 +259,9 @@ npx rea-agents@latest setup
請按照 [SECURITY.md](SECURITY.md) 報告漏洞。
## 參與貢獻
歡迎幫助改進 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 報告錯誤或建議功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改進程式碼或文件。
開發設定和檢查見 [CONTRIBUTING.md](CONTRIBUTING.md),驗證流程見[測試指南](docs/testing.md),專案結構見[架構圖](docs/architecture.mermaid)。
## 專案連結
[網站](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [安全](SECURITY.md)
## Star 歷史
🎉 **GitHub Star 達到 30,000 個,感謝大家!**
🎉 **GitHub Star 達到 50,000 個,感謝大家!**
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
REA 為合法的逆向工程研究、分析和重建提供工具。你有責任取得所需授權並遵守適用法律。本專案不認同非法或未經授權的使用。
## 參與貢獻
歡迎幫助改進 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 報告錯誤或建議功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改進程式碼或文件。
開發設定和檢查見 [CONTRIBUTING.md](CONTRIBUTING.md),驗證流程見[測試指南](docs/testing.md),專案結構見[架構圖](docs/architecture.mermaid)。
## 授權條款
[MIT](LICENSE)
+20 -19
View File
@@ -1,8 +1,8 @@
<div align="center">
[English](README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:逆向分析一切
# REA:逆向一切
### 通过一个 MCP 服务,逆向分析二进制文件、应用程序和运行时行为。
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA 在 Hopper 中启动分析桥,检查原生二进制文件" width="1200" />
<br />
<br /><br />
<table aria-label="REA 社区">
<tr>
@@ -135,13 +135,16 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 原生二进制文件 | 伪代码、汇编、字符串、符号、调用和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
| 离线 ELF 布局 | 节、段、原始符号/重定位信息及静态防护机制候选项 | Linux x64 上由调用方提供的 pwntools;[二进制诊断](docs/binary-diagnostics.md) |
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | 本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | 调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | Linux x64 上的本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](https://rea.tools/guides/javascript/) |
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](https://rea.tools/guides/browser/) |
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](docs/web-network-captures.md) |
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](docs/managed-code-analysis.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 设备 | 设备、软件包、进程、日志、转储、屏幕截图以及 APK/文件传输 | 调用方提供的 adb(模拟器或实体设备);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 项目 | 引擎支持的项目单元、工件摘要和类型/方法的伪代码 | 由调用方启动、提供 MCP 的 JEB 客户端,通过 REA_JEB_MCP_URL 选择;[JEB 指南](docs/jeb-analysis.md) |
| Android 资源 | 解码后的清单、字符串表、语言区域和版本信息 | 调用方提供的 Apktool 启动器;[资源指南](docs/apktool-resource-analysis.md) |
| 固件 | 区域、提取结果和转交原生分析的内容 | Linux 上的 Binwalk / Unblob;[固件指南](docs/firmware-analysis.md) |
| 软件包与资源 | 文件清单、摘要、plist、Apple bundle 结构和提取的资源 | [制品与 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 应用](docs/apple-application-analysis.md) |
| 进程行为 | 终端输出、交互、退出和文件系统观察结果,以及运行对比 | 支持原生 PTY 的 Linux/macOS;[进程捕获](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
## 案例
[![DX-Ball 声音平移、Notion 剪贴板桥接与 TH04 弹幕环案例的插图](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:重建声像计算
沿声音调用追踪到根据位置计算声像的辅助函数,检查指令,将不完整的伪代码转为 C。重建结果通过了 3,205 个原始 x86 测试用例,并复现了编译后函数的全部 63 个字节。
@@ -202,7 +207,7 @@ REA 会在操作需要时启动 Hopper。在 macOS 上,首次运行时可能
<details>
<summary><strong>从 skills.sh 安装 skill 有什么作用?</strong></summary>
skill 为智能体提供调查指引。使用 `rea setup` 注册 REA 的 MCP 服务并安装匹配的指引,然后重启智能体。见[仅安装 skill](docs/installation.md#skill-only-installation)。
skill 为智能体提供调查指引。使用 `npx rea-agents setup` 注册 REA 的 MCP 服务并安装匹配的指引,然后重启智能体。见[仅安装 skill](docs/installation.md#skill-only-installation)。
</details>
@@ -254,19 +259,9 @@ npx rea-agents@latest setup
请按照 [SECURITY.md](SECURITY.md) 报告漏洞。
## 参与贡献
欢迎帮助改进 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 报告错误或建议功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改进代码或文档。
开发设置和检查见 [CONTRIBUTING.md](CONTRIBUTING.md),验证流程见[测试指南](docs/testing.md),项目结构见[架构图](docs/architecture.mermaid)。
## 项目链接
[网站](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [安全](SECURITY.md)
## Star 历史
🎉 **GitHub Star 达到 30,000 个,感谢大家!**
🎉 **GitHub Star 达到 50,000 个,感谢大家!**
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
REA 为合法的逆向工程研究、分析和重建提供工具。你有责任取得所需授权并遵守适用法律。项目不支持非法或未经授权的使用。
## 参与贡献
欢迎帮助改进 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 报告错误或建议功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改进代码或文档。
开发设置和检查见 [CONTRIBUTING.md](CONTRIBUTING.md),验证流程见[测试指南](docs/testing.md),项目结构见[架构图](docs/architecture.mermaid)。
## 许可证
[MIT](LICENSE)
+6 -7
View File
@@ -841,14 +841,13 @@ public final class ReaGhidraBridge extends HeadlessScript {
private JsonObject instructionReference(Reference reference) {
JsonObject item = new JsonObject();
RefType type = reference.getReferenceType();
JsonObject kind = referenceKind(reference);
item.addProperty("source_address", canonicalAddress(reference.getFromAddress()));
item.addProperty("target_address", canonicalAddress(reference.getToAddress()));
item.addProperty("type", type.getName());
item.addProperty("call", type.isCall());
item.addProperty("jump", type.isJump());
item.addProperty("indirect", type.isIndirect());
item.addProperty("computed", type.isComputed());
item.addProperty("operand_index", reference.getOperandIndex());
for (String field : List.of("type", "call", "jump", "indirect", "computed",
"operand_index", "data", "read", "write", "primary", "provenance"))
item.add(field, kind.get(field));
item.addProperty("source", normalizedSource(reference.getSource()));
return item;
}
+89
View File
@@ -0,0 +1,89 @@
import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.FlowType;
import ghidra.program.model.pcode.PcodeOp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* Undo wrong no-return flags from auto-analysis. A function flagged no-return that contains a
* real RET is an ordinary function (stream readers, cxa_guard_acquire, ...). Callers treated the
* call as a terminator and the decompiler truncated them. Clear the flag, then re-disassemble only
* the call sites of the functions that were cleared and refit their owning functions in place.
*/
public final class ReaGhidraNoReturnFix extends GhidraScript {
@Override
public void run() throws Exception {
// Windows P0 does not admit analysis-database mutation.
if (System.getProperty("os.name", "").startsWith("Windows")) return;
FunctionManager fm = currentProgram.getFunctionManager();
Listing li = currentProgram.getListing();
Set<Address> cleared = new HashSet<>();
for (Function f : fm.getFunctions(true)) {
monitor.checkCancelled();
if (!f.hasNoReturn() || f.isThunk()) continue;
for (Instruction ins : li.getInstructions(f.getBody(), true)) {
FlowType ft = ins.getFlowType();
boolean decodedReturn = false;
for (PcodeOp operation : ins.getPcode()) {
if (operation.getOpcode() == PcodeOp.RETURN) decodedReturn = true;
}
if (decodedReturn && !ft.isJump() && !ft.isCall()) {
f.setNoReturn(false);
cleared.add(f.getEntryPoint());
break;
}
}
}
// A thunk inherits the flag of the function it forwards to.
for (Function f : fm.getFunctions(true)) {
monitor.checkCancelled();
if (!f.isThunk()) continue;
Function target = f.getThunkedFunction(true);
if (target != null && cleared.contains(target.getEntryPoint())) {
cleared.add(f.getEntryPoint());
}
}
int redone = 0;
TreeSet<Address> owners = new TreeSet<>();
if (!cleared.isEmpty()) {
List<Address> sites = new ArrayList<>();
for (Instruction ins : li.getInstructions(true)) {
monitor.checkCancelled();
FlowType ft = ins.getFlowType();
if (!(ft.isCall() && ft.isTerminal())) continue;
Address[] flows = ins.getFlows();
if (flows.length == 0 || !cleared.contains(flows[0])) continue;
// Do not redisassemble into an independently identified function.
Address next = ins.getMaxAddress().add(1);
if (fm.getFunctionAt(next) != null || !currentProgram.getMemory().contains(next)) continue;
sites.add(ins.getAddress());
}
for (Address s : sites) {
monitor.checkCancelled();
Instruction ins = li.getInstructionAt(s);
if (ins == null) continue;
Function owner = fm.getFunctionContaining(s);
if (owner != null && !owner.isThunk()) owners.add(owner.getEntryPoint());
clearListing(ins.getMinAddress(), ins.getMaxAddress());
disassemble(s);
redone++;
}
for (Address e : owners) {
monitor.checkCancelled();
Function f = fm.getFunctionAt(e);
// Refit the body in place so the name, signature and calling convention survive.
if (f != null) CreateFunctionCmd.fixupFunctionBody(currentProgram, f, monitor);
}
// No analyzeChanges here: on libpl2.so it adds about 70 s, which pushes startup past the 330 s deadline.
}
println(
"REA no-return fix: cleared=" + cleared.size() + " sites=" + redone + " refit=" + owners.size());
}
}
+2
View File
@@ -716,6 +716,8 @@ def _analyze_function(document, params):
"referenced_strings": referenced_strings,
"referenced_names": referenced_names,
"basic_blocks": blocks,
"native_api": None,
"native_value_flow": None,
"limitations": [
"Native CallReference classifications are observed where available; detailed reference flags remain unknown.",
"Hopper's public Python API does not expose equivalent external or thunk classification in this dossier.",
+1 -2
View File
@@ -55,7 +55,7 @@ export default defineConfig({
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
{ text: "Provider evaluation", link: "/provider-evaluation" },
{ text: "Ghidra semantics", link: "/ghidra-provider" },
],
},
{
@@ -66,7 +66,6 @@ export default defineConfig({
{ text: "Tool design", link: "/tool-design" },
{ text: "Testing", link: "/testing" },
{ text: "Releasing", link: "/releasing" },
{ text: "Architecture decisions", link: "/adr/README" },
],
},
],
+170
View File
@@ -0,0 +1,170 @@
# ADB device inspection and acquisition
REA inspects connected Android devices, reads device state, and transfers
files and packages through the caller's `adb` binary. Emulators, USB
devices, and network devices participate alike: REA neither starts nor
manages them and never installs platform tools. Every operation composes a
fixed adb argument vector — caller values occupy positional arguments only
and are quoted when adb forwards them to the device shell.
The adb client may start its local server on first device query; that is adb
client behavior, recorded in the tool result when observed.
`inspect_adb_client` probes only the binary and never contacts the server.
## Supply tools
Use any Android platform-tools `adb` (verified with 34.0.5). Select it
through the environment:
```sh
# Optional: absolute path to the adb binary; without it, adb resolves from PATH.
export REA_ADB_PATH=/absolute/path/to/adb
```
REA never installs the Android SDK, an emulator, or a system image.
Readiness is `rea inspect-adb-client`: it runs `adb version` and reports the
resolved binary, its version, and where it was selected from. A missing
binary reports `capability_unavailable` with the `REA_ADB_PATH` remediation
rather than attempting an installation.
## Answer an analyst question
```sh
# Device identity
rea inspect-adb-client
rea list-adb-devices
rea inspect-adb-device emulator-5554
rea inspect-adb-display emulator-5554
rea list-adb-features emulator-5554
rea list-adb-services emulator-5554
# Find and acquire an app (the easy-get flow)
rea resolve-adb-packages emulator-5554 whatsapp
rea list-adb-packages emulator-5554 --scope third_party
rea inspect-adb-package emulator-5554 com.whatsapp
rea pull-adb-package emulator-5554 com.whatsapp --output-directory /tmp/acq
rea inspect-android-package /tmp/acq/com.whatsapp/base.apk
# Device state and files
rea list-adb-processes emulator-5554
rea inspect-adb-window emulator-5554
rea read-adb-setting emulator-5554 global adb_enabled
rea read-adb-logcat emulator-5554 --count 200
rea list-adb-directory emulator-5554 /data/data/com.whatsapp
rea pull-adb-file emulator-5554 /data/local/tmp/notes.txt --output-directory /tmp/acq
rea push-adb-file emulator-5554 /tools/frida-server /data/local/tmp/frida-server
rea capture-adb-screen emulator-5554 --output-directory /tmp/shots
rea collect-adb-bugreport emulator-5554 --output-directory /tmp/bugs
# Package lifecycle and dynamic analysis (device-mutating)
rea install-adb-package emulator-5554 /tmp/app.apk --replace
rea start-adb-app emulator-5554 com.example.app
rea read-adb-logcat emulator-5554 --pid 12345
rea start-adb-activity emulator-5554 android.intent.action.VIEW --data-uri https://example.com
rea stop-adb-app emulator-5554 com.example.app
rea uninstall-adb-package emulator-5554 com.example.app
```
Equivalent MCP methods use the snake_case names (`list_adb_devices`,
`pull_adb_package`, `resolve_adb_packages`, …). Device operations take
`serial` exactly as `adb devices` reports it. The pulled APK set feeds the
existing analysis families directly, for example
`rea inspect-android-package /tmp/acq/<package>/base.apk`.
## Operations
| Tool | Kind | What it does |
| ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inspect_adb_client` | read | Resolved binary, version, install path; never contacts the server |
| `list_adb_devices` | read | Serial, state, transport, model metadata, inferred emulator/physical kind with basis |
| `inspect_adb_device` | read | Fixed `getprop` whitelist: build, SDK, patch, fingerprint, product, ABIs, debuggable, `ro.kernel.qemu` |
| `inspect_adb_display` | read | `wm size` and `wm density` as declared |
| `list_adb_features` | read | `pm list features` (hardware/software features, hex GL versions) |
| `list_adb_services` | read | `service list` binder services and interfaces |
| `list_adb_processes` | read | `ps -A`: user, pid, ppid, rss, state, name |
| `inspect_adb_window` | read | `dumpsys window` focus declarations (what is on screen) |
| `read_adb_setting` | read | One `settings get` value; device-side null is reported as such |
| `read_adb_logcat` | read | Bounded `logcat -d -t` dump for one buffer, optional pid filter |
| `list_adb_packages` | read | `pm list packages -f` with scope; base APK device paths |
| `resolve_adb_packages` | read | Case-insensitive package-name substring search with exact-match flag |
| `inspect_adb_package` | read | `dumpsys package` projection: versions, install times, installer, flags, permission count |
| `list_adb_directory` | read | `ls -la`: kinds, permissions, owner, group, sizes, symlink targets |
| `pull_adb_package` | read | Complete split APK set from `pm path`, each file digested |
| `pull_adb_file` | read | One absolute device path pulled and digested |
| `capture_adb_screen` | read | One `screencap -p` frame (exec-out, no device-side file) with dimensions |
| `collect_adb_bugreport` | read | Device-generated bugreport zip, digested |
| `push_adb_file` | **mutates device** | One local file to a device path (e.g. pushing tools into `/data/local/tmp`); refuses existing targets without explicit overwrite; verifies via the device's own sha256sum |
| `install_adb_package` | **mutates device** | Local APK via `adb install [-r]`; preserves the device's Success/Failure verdict |
| `uninstall_adb_package` | **mutates device** | Removes a package and its data for user 0 |
| `start_adb_app` | **mutates device** | Resolves the package's launcher activity (`cmd package resolve-activity --brief`) and starts it (`am start -n`) |
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
| `stop_adb_app` | **mutates device** | Force-stops every process of a package, ending a dynamic-analysis run |
## Interpret the result
- **Inferences carry their basis.** Device `kind` reports
`kind_basis` (serial prefix or USB transport); APK `role` reports
`role_basis: file_name`; `emulator_observed` is the build's own
`ro.kernel.qemu` value, `null` when absent.
- **Device paths are not host paths.** `base_apk_device_path` values live on
the device filesystem. Only pulls and captures produce host-local paths,
each paired with byte size and SHA-256 digest.
- **Splits are part of the answer.** `pm path` enumerates the base APK and
every installed split; pulls cover the whole set. System packages whose
APKs keep other names report the `unknown` role rather than guessing.
- **Partial results keep facts.** Failed individual pulls return successful
artifacts with `coverage: "partial"` and per-file `failures`. Listings
that contain unrecognized lines report them as `unparsed_lines` and mark
partial coverage instead of dropping rows.
- **Mutations are explicit.** `push_adb_file`, `install_adb_package`, and
`uninstall_adb_package` declare `mutatesTarget` and never run implicitly:
pushes refuse existing device files unless `overwrite` is set and verify
the transfer with the device's own `sha256sum`; installs preserve the
device's `Failure [...]` reason verbatim.
- **Producer identity stays attached.** Every result embeds the producing
adb client (`binary_path`, `path_source`, `version`, `installed_path`).
## Resource and lifecycle limits
- Caller values reach adb only as positional arguments in fixed vectors;
no tool accepts an arbitrary shell command line, and UI interaction
(`input`, `am`, `monkey`) is deliberately not exposed.
- Per-invocation budgets: client/devices 10-20 s, shell reads 20-60 s with
64 KiB-8 MiB capture caps (logcat 4 MiB, screen 32 MiB), transfers and
bugreports 600 s. Exceeded budgets report `resource_constraint`; stopped
commands report `provider_timeout`.
- Pull and capture outputs are additive: the destination must not already
exist. Re-running a completed pull refuses the existing directory instead
of overwriting evidence.
- Cancellation during a package pull preserves caller-selected output. The
error includes partial observations identifying completed artifacts and the
interrupted local path; remaining APKs were not attempted.
- Failed package acquisition rollback retains its directory identity and retries
cleanup before later work and during shutdown. Cleanup refuses a replacement
directory. Terminal shutdown stops admission and drains active operations.
- The provider holds no long-lived processes; every invocation is one
bounded adb run. The adb server belongs to the caller.
## Related capability and follow-up lanes
UI interaction beyond intent starts (tapping, typing, monkey fuzzing, screen
recording) remains a separate lane: candidates such as
[mobile-device-mcp](https://github.com/srmorete/mobile-device-mcp) install
driver software on the device and pair with the Frida instrumentation lane
(#1359) behind explicit mutation-authority contracts. Network transports
beyond already-connected devices (`adb connect`) are not exposed yet.
## Real verification
`npm run verify:adb` exercises every operation against a live device. It
requires `adb` (or `REA_ADB_PATH`) and any attached emulator or phone;
`--serial` selects one when several are attached, `--pull PACKAGE` pulls a
real package and verifies the returned digests against the files on disk,
and `--install-apk PATH` drives a full install → resolve → uninstall
lifecycle with a lane-owned probe.
Record: verified against adb 34.0.5 on Linux against an Android 14
(API 34) x86_64 emulator — all operations above, a 224-package inventory,
287 services, 92 features, a real two-APK split set pulled with byte-exact
digests, a verified push/pull roundtrip, a 1.3 MB screen capture, and the
complete package lifecycle; see `docs/testing.md` for the lane summary.
@@ -1,572 +0,0 @@
# ADR-0001: Provider selection and analysis profiles
- Status: Accepted
- Date: 2026-07-15
- Implementation status: The provider registry, deterministic selection,
target binding, analysis-profile commitment, and snapshot/Evidence migration
are implemented. Ghidra discovery, target/profile resolution, doctor checks,
the private headless-session foundation, thirteen read-only inventory/load-image
capabilities, and twelve function-analysis capabilities are implemented with
real cross-format conformance. Linux/macOS also supports atomic session
function annotations; experimental Windows x64 P0 uses bundled native controls
and admits only the 25 read-only operations. See the
[release boundary](../installation.md#released-package-and-main).
## Context
Before this decision, REA composed the artifact, native macOS, and Hopper
providers with `CompositeProvider`. That class intentionally requires every
operation to have one route. Hopper and Ghidra will both implement the deep
static-analysis operation family, so putting both into that composite would
either fail at construction or make array order an undeclared selection policy.
The active `BinarySession` also owned one composite client. `open_binary` had no
provider selector, and the domain `BinaryTarget` contained Hopper loader
arguments. Analysis snapshot v1 committed those loader arguments and each
cached entry's provider identity, but it did not commit the selected analysis
engine, engine version, or complete analysis configuration. Two analyses of the
same bytes could therefore disagree because of language, compiler, loader,
analyzer, or provider-version differences while appearing target-compatible.
The decision addressed the earlier representations of
[`CompositeProvider`](https://github.com/morluto/rea/blob/main/src/application/binary/CompositeProvider.ts),
[runtime composition](https://github.com/morluto/rea/blob/main/src/composition/binary.ts),
[`BinarySession`](https://github.com/morluto/rea/blob/main/src/application/binary/BinarySession.ts),
[`BinaryTarget`](https://github.com/morluto/rea/blob/main/src/domain/binaryTarget.ts),
[analysis snapshot](https://github.com/morluto/rea/blob/main/src/domain/analysisSnapshot.ts), and
[session lifecycle inputs](https://github.com/morluto/rea/blob/main/src/contracts/sessionLifecycleInputs.ts).
The next deep provider must not weaken the existing product invariants:
- stable provider-neutral CLI and MCP tool names;
- exact provenance and explicit unavailable or degraded capabilities;
- CLI and MCP parity;
- no silent provider fallback;
- provider-specific code outside the domain and application models;
- local, actionable diagnostics with only genuine secrets redacted; and
- snapshot reuse only when semantic analysis inputs are identical.
## Decision drivers
1. Hopper and Ghidra need to declare overlapping operations without ambiguous
dispatch.
2. A target must have one explainable deep-analysis producer for its lifetime.
3. Target-free discovery must remain useful and must not start an analysis
process.
4. Existing Hopper-only configurations must keep working when no selector is
supplied.
5. Adding a second installed provider must not silently change results.
6. Snapshot and Evidence compatibility must include every setting that can
materially change analysis.
7. Provider-specific open settings must not leak into `BinaryTarget` or become
generic application fields.
## Terminology
- **Deep provider**: an engine such as Hopper or Ghidra that implements the
overlapping static-analysis operation family.
- **Auxiliary provider**: a provider with a disjoint operation family, such as
artifact inventory or native macOS inspection.
- **Candidate**: a registered deep provider before target selection.
- **Binding**: the selected deep provider and analysis profile attached to one
active target.
- **Analysis profile**: a canonical commitment to the selected provider,
provider version, and normalized semantic analysis settings.
- **Available**: the adapter and its required local runtime can be used on this
host.
- **Supported**: the candidate accepts the parsed target and supplied open
options. Availability and target support are separate observations.
## Decision
### 1. Separate disjoint composition from overlapping selection
`CompositeProvider` remains the mechanism for operation families whose routes
are disjoint. It must continue rejecting duplicate operation declarations. It
must not acquire priority, racing, fallback, or provider-selection behavior.
A new `AnalysisProviderRegistry` owns the configured deep-provider candidates.
Provider IDs are unique; duplicate IDs are a configuration error. The registry
may hold multiple candidates that declare the same operation. It performs
candidate discovery, target-support evaluation, option parsing, profile
resolution, and selection, but it does not choose a different provider for each
request.
After selection, the session composes exactly one bound deep provider with the
auxiliary disjoint families:
```text
target-free discovery
|
AnalysisProviderRegistry
/ \
Hopper Ghidra
\ /
one selected binding
|
+-------------------------+-------------------------+
| | |
selected deep family artifact family native family
+-------------------------+-------------------------+
|
BinarySession
```
An auxiliary operation continues to report its actual auxiliary provider as
provenance. A deep operation always reports the provider in the active binding.
The synthetic composite identity is never evidence that two engines jointly
produced one observation.
Operation ownership is fixed by family:
| Operation family | Executor |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| Deep direct operations and provider-native function analysis | The one bound Hopper or Ghidra provider |
| Application-enhanced deep workflows | Application composition over the bound provider's declared operations |
| Native macOS inspection | The disjoint native provider |
| Artifact inventory and extraction | The disjoint artifact provider |
| Browser and Electron observation | Their independently authorized CDP providers; they do not participate in deep-provider selection |
| Session lifecycle, Evidence, comparisons, and reconstruction | The application/session layer using the exact provider provenance recorded by their source operations |
Selecting a deep provider selects the whole deep family. If that provider marks
an operation unavailable, REA returns the unavailability; it does not borrow
that one operation from another deep provider. Application-enhanced workflows
run only when the bound provider supplies their declared dependencies.
### 2. Discover candidates without launching analysis
Each registered candidate exposes three bounded adapter-owned observations:
1. identity and declared capability descriptors;
2. host availability, including an actionable rejection when unavailable; and
3. target support plus normalized profile resolution when a target is known.
Target-free discovery may inspect configuration, manifests, executable
metadata, and documented version files. It must not import a target, create a
project, open a GUI, or start the long-lived analysis process. Any short-lived
version probe added later must be explicitly bounded and truthfully declared as
a process effect.
Candidate output is sorted by provider ID for determinism. Sort order is not
selection priority. Availability and support use stable codes plus a human
diagnostic:
| Code | Meaning |
| ---------------------------- | --------------------------------------------------------------- |
| `not_configured` | Required provider location or configuration is absent |
| `executable_missing` | The configured provider entry point is missing or not runnable |
| `runtime_missing` | A required provider runtime, such as Java, is unavailable |
| `unsupported_host` | The host platform or architecture is unsupported |
| `unsupported_version` | The discovered provider or runtime version is unsupported |
| `target_kind_unsupported` | The provider does not accept this target kind |
| `target_format_unsupported` | The provider does not accept this target format |
| `architecture_unsupported` | The selected target architecture is unsupported |
| `target_role_unsupported` | The provider rejects this executable image role |
| `managed_target_unsupported` | The provider does not admit managed code through this deep path |
| `open_options_invalid` | The selected adapter rejected its open options |
| `version_unresolved` | A concrete analysis-engine version could not be committed |
Diagnostics retain useful local paths, observed versions, architectures, and
mismatch details. Credentials, authorization headers, license secrets, and
other genuine secrets remain redacted.
### 3. Use one deterministic selection algorithm
The caller-visible selectors are:
- MCP `open_binary.provider_id`;
- `rea ... --provider <provider-id|auto>` on every one-shot command that needs
deep analysis; and
- `REA_ANALYSIS_PROVIDER=<provider-id|auto>`, defaulting to `auto`.
The literal value `auto` is reserved and cannot be a provider ID. Precedence is
request or CLI flag, then environment configuration, then the default `auto`.
An explicit request for `auto` overrides a concrete environment preference and
re-enters automatic selection.
Selection occurs after provider-neutral target parsing and before a deep client
is created:
1. A concrete requested provider ID must exist, be available, support the
target, accept its options, and resolve a concrete version and profile. Any
failure returns a typed selection error; another provider is never tried.
2. `auto` filters candidates by availability and target support.
3. Exactly one usable candidate is selected with source
`auto-single-candidate`.
4. More than one usable candidate is an `ambiguous` selection error. The
diagnostic lists the candidates and asks for `provider_id`, `--provider`, or
`REA_ANALYSIS_PROVIDER`. REA does not prefer Hopper, Ghidra, registration
order, the fastest startup, or the first health response.
5. When no deep candidate is usable, an automatic open may still establish an
unbound target so disjoint artifact or native operations remain available.
Deep operations are then explicitly unavailable with the candidate
rejections. A concrete request, or a concrete environment preference for a
deep-eligible target, remains a hard requirement and fails instead of
becoming unbound.
6. A target that no deep adapter declares support for, such as an artifact-only
target, is `not_applicable` rather than a failed deep analysis. Supplying a
concrete provider in that open request is still an actionable unsupported-
target error. A global environment preference does not make an artifact-only
target require a deep provider.
This preserves target opening for non-Hopper capabilities on hosts without a
deep engine while ensuring that installing a second usable deep engine never
changes analysis silently.
### 4. Bind once and never fail over mid-session
An active deep binding contains:
```text
canonical target identity
selected provider identity and concrete version
selection source: request | environment | auto-single-candidate
analysis profile commitment
owned provider client, once started
```
The binding is immutable until `close_binary` or an explicit open/switch
transaction. Provider client creation may remain lazy, but laziness cannot
change which provider was selected.
- Opening the same canonical target without a new selector keeps the existing
binding.
- Opening the same target with the same provider and profile is idempotent.
- A different explicit provider or a profile-changing option is a real switch:
drain active calls, close owned resources, resolve the new binding, and start
it as one serialized transaction.
- If a switch fails, restore the prior target and binding on a best-effort
transactional path and return the original switch error.
- Provider process exit, timeout, cancellation, capability failure, or adapter
error never triggers fallback. The binding stays visible and unavailable
until the caller explicitly switches or closes it.
- A snapshot never chooses or changes the provider. Selection happens first;
snapshot compatibility is checked against the resulting binding.
Calls already admitted to one binding complete or cancel against that binding.
No request can cross a concurrent target or provider transition.
### 5. Keep provider open options adapter-owned
`BinaryTarget` retains only provider-neutral source identity and classification:
canonical path, source digest, generic kind and format, selected architecture,
and available architectures. Hopper loader arguments leave the domain model.
Provider-owned databases use a generic analysis-database classification; their
adapter determines support. A `.hop` analysis database is therefore accepted only
by Hopper without teaching the domain how to open it. Ghidra v1 continues to use
private temporary projects and does not open user projects.
The generic transport may carry one bounded JSON `provider_options` object.
Only the selected adapter parses its keys and reports `open_options_invalid` at
that boundary. If this object is exposed over MCP, the CLI parity surface is
`--provider-options-json` with the same JSON schema and limits. Unknown keys,
wrong-provider options, excessive depth or size, and non-JSON values fail
closed.
Environment settings that are inherently adapter-specific, such as the Hopper
launcher or future Ghidra installation path, remain in adapter configuration.
They do not become `BinaryTarget` fields. The application layer transports an
opaque, already-bounded JSON value and the generic commitment described below;
it does not interpret Hopper or Ghidra option names.
### 6. Commit a canonical analysis profile
Before creating a deep client, the selected adapter normalizes every semantic
input that can affect analysis. Examples include Hopper loader selection and
architecture flags, or Ghidra language ID, compiler specification, import mode,
analyzer set, and analyzer options. Defaults are made explicit, unordered sets
are sorted, and implicit host-dependent choices are resolved.
The adapter returns this provider-neutral envelope:
```json
{
"provider": { "id": "ghidra", "version": "<concrete version>" },
"parameters": {},
"digest": "<sha256 of RFC 8785 canonical JSON excluding digest>"
}
```
`parameters` is bounded JSON interpreted only by that provider adapter. It
contains analysis semantics, not credentials, authorization data, temporary
paths, installation paths, process IDs, timestamps, or other incidental host
state. The generic domain validates the envelope and digest but treats the
parameters as opaque data.
A selected deep binding requires a concrete provider version. If the adapter
cannot determine it, the candidate is unavailable with `version_unresolved`;
REA does not persist a cache that merely commits `null` or "whatever is
installed". Provider identity, normalized parameters, or provider version
changes produce a different digest.
The same target, configuration, and provider must resolve the same profile over
CLI and MCP. Profile resolution must be side-effect-free and complete before
the provider imports the target.
### 7. Make snapshots provider- and profile-exact
Analysis snapshots replace Hopper loader arguments with an explicit binding
commitment:
```text
target: digest + generic format/kind + selected architecture
binding: provider identity + analysis profile commitment
entries: exact immutable queries
evidence_bundle: retained Evidence records
```
The snapshot target identity, canonical snapshot content digest, and every
query ID commit the provider ID, concrete provider version, and profile digest.
A cached entry is reusable only when all of the following match exactly:
- target digest, generic format and kind, and selected architecture;
- provider ID and provider version;
- profile digest;
- operation and canonical parameters; and
- the existing cacheability and immutability rules.
Provider or profile switches select a separate cache partition and cannot reuse
entries from the previous binding. Auxiliary operations are cacheable only if
their provider defines an equivalent explicit profile commitment; otherwise
they remain Evidence but not snapshot entries.
Snapshot v1 cannot be parsed as the current snapshot format. Its `loader_args`
cannot prove which engine version, defaults, or analyzer settings produced the
entries, so snapshots must be recaptured before they can be used as a cache.
An embedded Evidence bundle can still be imported separately through the
Evidence import flow; it is never promoted into an analysis cache.
### 8. Commit concrete or explicitly unknown analysis profiles in Evidence
Every Evidence record includes `analysis_profile`, either the canonical profile
envelope above or `null` when no profile was observed. Deep-analysis observations
commit the resolved provider ID, version, and effective configuration in this
profile. The field participates in the Evidence semantic ID.
An explicitly unknown profile can be displayed and cited, but cannot establish
profile compatibility, seed snapshot replay, or support an "unchanged"
conclusion that depends on identical analysis semantics. Snapshot query entries
must have matching profile-bound Evidence; imports reject missing or mismatched
observations instead of silently dropping query entries. Both `entries` and
`workflow_entries` are required arrays, including when empty.
Different providers or profile digests are never snapshot-compatible. A
derived comparison may compare cross-provider normalized facts only when its
own contract explicitly defines that semantic comparison. Exact pseudocode,
provider text, or provider-specific metadata is not treated as equivalent. A
missing or incompatible profile yields unknown or incompatible, never equal.
### 9. Expose selection truth in status and diagnostics
`binary_session`, `rea providers`, and `rea capabilities` expose the same
candidate and binding model. The target-free form does not start providers and
uses `unknown` for target support:
```json
{
"analysis_provider_binding": null,
"analysis_provider_candidates": [
{
"provider": {
"id": "hopper",
"name": "Hopper Disassembler",
"version": "<detected version>"
},
"availability": {
"status": "available",
"code": null,
"reason": null,
"diagnostics": {}
},
"target_support": {
"status": "unknown",
"code": null,
"reason": "No target is open."
},
"selected": false,
"capabilities": []
}
]
}
```
With a binding, `analysis_provider_binding` includes the selected identity,
selection source, and complete profile commitment. Every candidate reports
`supported`, `unsupported`, or `unknown` target support and whether it was
selected. Candidate capability descriptors preserve supported, unsupported,
and degraded truth independently.
An open target also exposes `analysis_run`. Its run ID is allocated by the
session before client construction and propagated into selected Hopper or
Ghidra bridge handshake and process environment. Dynamic clients retain
provider-attributed lineage snapshots only after revalidating launcher
parent/command and every observed launcher or descendant run token. `not_observed`
means no dynamic provider has supplied a snapshot. Once one or more start,
`snapshots` preserves every provider observation; each remains explicitly
`unavailable` or `verified` and records its `observed_at` time. Retained
snapshots are not live inventories, and a point-in-time observation never proves
historical absence.
Status exposes `analysis_provider_candidates` for configured deep providers and
`analysis_provider_binding` for the selected concrete provider and profile.
`capabilities` retains effective operation availability and exact provider
provenance, including auxiliary operation families. There are no synthetic
flat `provider` or `providers` aliases. Provider prompt completion uses the
actual selectable candidates.
Selection failures extend the tagged `ProviderSelectionError` with a stable
reason:
- `unknown_provider`;
- `provider_unavailable`;
- `target_unsupported`;
- `ambiguous`;
- `invalid_options`.
The error includes the requested ID or `auto`, candidate IDs, rejection codes,
and actionable local diagnostics. `AnalysisCapabilityUnavailableError` remains
the error for an operation the selected provider cannot supply.
`ProviderAdapterError` and more specific provider errors remain failures of the
already selected provider. None authorizes fallback.
A snapshot whose provider or profile differs from the selected binding returns
`EvidenceIntegrityError` with stable `profile_mismatch` details. It is an
integrity incompatibility after selection, not permission to select the
snapshot's provider.
### 10. Preserve CLI and MCP parity
- `open_binary.provider_id` and one-shot `--provider` use the same parser and
selection service.
- `provider_id: "auto"`, `--provider auto`, and
`REA_ANALYSIS_PROVIDER=auto` have identical auto semantics.
- Startup targets opened from environment configuration use the same service.
- `rea providers`, `rea capabilities`, and target-free `binary_session` use the
same candidate snapshot and reason codes.
- Guided prompt `provider_id` context is a preference to forward into the open
operation; it does not create a hidden routing channel.
- Tool names and normalized output contracts remain provider-neutral. REA does
not add `ghidra_decompile` or `hopper_decompile` tools.
## Provider and snapshot representations
| Behavior or data | Contract |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| No selector, one usable deep provider | `auto` selects the sole candidate |
| No usable deep provider | Automatic open may remain unbound for auxiliary operations; deep capabilities explain their unavailability |
| Several usable deep providers without a preference | Open fails with `ambiguous`; installation order never becomes policy |
| Hopper environment settings | Adapter configuration committed into the typed analysis profile, including effective loader arguments |
| `open_binary` output | Provider-neutral target identity only; no `loaderArgs` projection |
| `.hop` input | Analysis database accepted only by Hopper |
| Snapshots | Concrete provider/profile binding, required primitive and workflow entry arrays, and matching authenticated Evidence |
| Evidence without an observed profile | Explicit `analysis_profile: null`; ineligible for profile-dependent replay |
| Snapshot save receipt | `primitive_entries`, `workflow_entries`, and `evidence_records` counts without a duplicate `entries` alias |
| Provider failure after selection | Returned from that provider, without transparent retry through another engine |
## Required behavior scenarios
| Scenario | Result |
| ---------------------------------------------------------- | --------------------------------------------------------------------------- |
| Hopper is the only usable candidate, selector omitted | Hopper is bound by `auto-single-candidate` |
| Ghidra is the only usable candidate, selector omitted | Ghidra is bound by `auto-single-candidate` |
| Both are usable, selector omitted | Typed `ambiguous` error; neither provider starts |
| Environment selects Ghidra, request omits a selector | Ghidra is required and bound or the open fails with its rejection |
| Environment selects Ghidra, request selects Hopper | Request wins; Hopper is required |
| Environment selects Ghidra, request selects `auto` | Auto policy runs and is ambiguous when both are usable |
| Unknown concrete provider ID | Typed `unknown_provider`; no target transition |
| Selected provider rejects the target or options | Typed rejection from that candidate only |
| Selected provider times out after binding | Binding remains selected and unavailable; no fallback |
| Same target is reopened without a selector | Existing binding remains unchanged |
| Same bytes are opened with a different profile | Real provider switch and a separate snapshot partition |
| Snapshot provider or profile differs from the binding | Typed `EvidenceIntegrityError` with `profile_mismatch`; nothing is imported |
| Artifact-only target has no deep candidate | Target opens unbound; disjoint artifact capabilities remain usable |
| Environment prefers Ghidra for an artifact-only target | Deep selection is `not_applicable`; auxiliary operations remain usable |
| Concrete deep provider is requested for artifact-only data | Typed `target_unsupported`; the request is not silently ignored |
## Consequences
Positive consequences:
- Hopper and Ghidra can coexist without ambiguous operation routes.
- Provider choice is reproducible, visible, and stable for a target.
- Installation of another provider cannot silently change analysis.
- Snapshot and Evidence identities become analysis-configuration aware.
- Provider adapters retain ownership of their option schemas and diagnostics.
- Auxiliary capabilities remain usable when no deep engine is installed.
Costs and tradeoffs:
- Multi-provider hosts must choose when more than one candidate is usable.
- Snapshots must be recaptured when their provider or profile binding changes.
- Providers must expose deterministic availability, support, version, and
profile resolution before they can be admitted.
- Status and error contracts gain additive structured metadata.
- Hopper needs an adapter-owned version/profile implementation before profile-
exact snapshot persistence is complete.
## Rejected alternatives
### Let `CompositeProvider` choose the first duplicate route
Array order is not a product policy, becomes fragile during wiring changes, and
hides ambiguity from callers.
### Race providers and keep the first healthy response
Machine load would determine provenance and results. It also starts resources
the operator did not select and makes cancellation and cleanup harder.
### Fall back after a provider error
Mid-session fallback can combine incompatible engine state and evidence under
one apparent target. Explicit close or switch is required instead.
### Add provider-prefixed tools
Parallel Hopper and Ghidra tool families would leak adapters into the product
contract and prevent shared workflows from using capability metadata.
### Store raw provider options in `BinaryTarget`
That repeats the current Hopper coupling and makes every generic consumer learn
provider schemas. Only canonical profile commitments cross the adapter boundary.
### Treat matching target bytes and provider ID as sufficient for snapshots
Provider versions, analyzer defaults, loaders, languages, and compiler models
can change results without changing either value.
### Silently upgrade snapshot v1
The missing engine version and analysis settings cannot be reconstructed from
Hopper loader arguments. A fabricated profile would turn unknown provenance
into false certainty.
## Implementation progress
The first six implementation stages are shipped:
1. Provider-specific target state was replaced by generic profile and snapshot
v2 commitments while preserving Hopper execution behavior.
2. The registry, selectors, candidate status, binding lifecycle, and
overlapping-provider production seams were added.
3. Proven process-lifecycle primitives were extracted for shared use.
4. Ghidra availability, target/profile resolution, doctor checks, and a private
read-only headless session were admitted without declaring operations.
5. Program identity, procedures, strings, symbols, memory blocks,
address/name resolution, containing-procedure resolution, and search
were admitted with exact wire schemas and real debug/stripped ELF
conformance.
6. Function metadata, persistent decompilation, assembly, resolved
callers/callees, typed references, xrefs, CFG, and complete function dossiers
were admitted. A serial per-Program queue keeps API access ordered without a
fixed queue length or per-operation deadline. Real conformance covers
x86-64 and AArch64 ELF, PE, Mach-O, stripped symbols, targetless indirect
calls, cancellation, and cleanup.
Future stages may deepen format and indirect-flow coverage, but must continue
to compare normalized semantics rather than provider-specific pseudocode or
assembly text. Linux and macOS now admit atomic function-name and entry-comment
edits in the ephemeral database, with readback, rollback, and cache invalidation.
Executable bytes remain unchanged. Windows P0 retains its read-only boundary;
GUI and other unimplemented mutations remain unavailable.
@@ -1,551 +0,0 @@
# ADR-0002: Controlled JavaScript replay authority and sandbox policy
- Status: Superseded; the controlled JavaScript replay tool was removed
- Date: 2026-07-16
- Implementation status: The implementation was removed. The design below is
retained as historical context and does not describe a supported REA tool.
> Historical design note: The tool, sandbox backend, and plan/execute workflow
> described here are no longer part of REA. For runtime behavior, run probes
> directly against the application and use the available browser, Electron, or
> process capture workflows.
## Context
REA can reconstruct JavaScript and Electron artifacts, observe an existing
browser or Electron page through passive CDP, capture an explicitly approved
process scenario, and correlate those observations without executing bundle
code in the REA server. The next research workflow needs to execute selected,
extracted JavaScript modules with controlled inputs and deterministic stubs so
that parsers, sanitizers, serializers, and similar pure logic can be compared
across versions.
That workflow crosses a qualitatively different boundary. Source recovered
from an application is untrusted code. It can intentionally or accidentally
read files, contact services, spawn processes, exhaust resources, corrupt the
analysis process, forge protocol output, or interact with another same-user
process. A JavaScript realm or Node.js `vm` context is useful for constructing
an API surface, but it is not a security boundary. Node.js also documents its
permission model as protection against accidental access by trusted code, not
as containment for malicious code.
Existing authorities cannot be widened to cover this behavior:
- `browser_observe` and `electron_observe` authorize passive attachment to an
already-running, operator-owned target. They do not authorize evaluation,
navigation, input, or target lifecycle changes.
- `process_capture` authorizes one declared host process scenario and explicitly
states that it is not a sandbox. It cannot silently become permission to run
recovered code.
- static artifact reads authorize inspection of bytes, not execution of those
bytes.
- the Evidence authority `controlled-replay` already describes observations
from an approved process experiment. Reusing that epistemic authority is
correct, but reusing the process permission capability is not.
The implementation following this ADR must fail closed on hosts where REA
cannot establish the promised operating-system boundary. It must not copy the
research `vm.runInContext` scripts into the production server and call that
isolation.
## Decision drivers
1. Passive observation must never imply authority to execute application code.
2. The exact code, inputs, stubs, runtime, sandbox policy, and limits approved
by the operator must be the ones executed.
3. Recovered code must not run in the MCP server, CLI adapter, or any provider
process.
4. A sandbox failure must make the capability unavailable, not select a weaker
execution mode.
5. The default policy must provide no host network and no writable host path.
6. Time, memory, process count, temporary storage, protocol, and output must be
bounded independently.
7. Results must distinguish an observed return, an observed exception or
termination, a derived comparison, and an unresolved application-level
claim.
8. A reproducer must commit enough provenance to detect every relevant change
without committing proprietary application source to the repository.
9. CLI and MCP must expose the same plan, approval, execution, cancellation,
failure, and Evidence semantics.
## Terminology
- **Passive observation**: bounded reads from an existing browser or Electron
target without evaluating code, driving input, navigating, or controlling
its lifecycle.
- **Controlled replay**: execution of operator-selected code in a declared,
isolated environment with committed inputs and limits. This is an Evidence
authority, not a claim that the real application behaved identically.
- **Extracted-module replay**: the only admitted JavaScript replay mode in v1.
REA evaluates a finite manifest of module bytes and explicit stubs without
launching the application.
- **Application interaction**: launching or driving the original application,
browser, renderer, or Electron main process. This is not extracted-module
replay and is not authorized by this ADR.
- **Replay plan**: the canonical, content-addressed description of one proposed
run before execution.
- **Replay worker**: the disposable Node.js process inside the OS sandbox. It
is never the REA server process.
- **Sandbox backend**: the OS mechanisms and adapter that establish namespaces,
resource controls, filesystem visibility, and owned cleanup.
## Threat model
### Protected assets
The boundary protects:
- the REA MCP/CLI process, its memory, credentials, sockets, and Evidence
ledger;
- user files outside the approved source reads and all host files from writes;
- other same-user processes and their control interfaces;
- host network interfaces, loopback services, Unix sockets, and external
services;
- process, memory, CPU, temporary-storage, output, and protocol capacity;
- the integrity of the replay plan, result, Evidence provenance, and exported
reproducer; and
- proprietary module bytes, which remain local and are never repository
fixtures.
### Adversaries and failure sources
REA treats all of the following as untrusted:
- recovered module source, including transitive modules and source maps;
- caller-provided JavaScript stubs;
- structured test inputs and generated fuzz cases;
- returned values, exceptions, console data, and worker protocol messages;
- source paths, symbolic links, and files that can change between planning and
execution; and
- a worker that crashes, hangs, forks, allocates aggressively, or exits while
descendants remain alive.
An operator-controlled sandbox executable, kernel, Node.js runtime, and REA
installation are trusted computing base. A hostile host administrator, kernel
or sandbox vulnerability, hardware side channel, and denial of service by an
already-compromised same-user process are out of scope. These exclusions do not
permit REA to omit the per-run resource controls in this decision.
### Required mitigations
The implementation must address:
| Threat | Required control |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Server-process compromise | Separate worker process inside the OS sandbox; no in-process fallback |
| Host file reads | Empty sandbox root; only a minimal read-only runtime closure; module bytes enter over a private bounded channel |
| Host file writes | No writable bind mounts; size-limited private tmpfs only |
| Network access | Separate network namespace with no host or external connectivity; no allowlist mode in v1 |
| Host process control | PID/user/IPC/UTS isolation, no inherited control sockets, new session, dropped capabilities |
| Kernel escape/inspection surface | Architecture-checked seccomp denial policy in addition to namespaces, capabilities, and cgroups |
| Fork, memory, or CPU exhaustion | Per-run cgroup v2 task, memory, swap, and CPU limits plus an outer wall-clock deadline |
| Output/protocol exhaustion | Independent byte/message/depth limits enforced by the parent before parsing or retaining output |
| Symlink and file-change races | Canonical authorization, descriptor-backed reads, digesting, staging, and exact plan revalidation |
| Undeclared dependencies | Closed module manifest; exact imports only; missing/dynamic imports fail rather than use host resolution |
| Nondeterministic globals | Versioned clock, PRNG, locale, timezone, platform, and API stubs; undeclared globals are unavailable |
| Orphan descendants | Owned PID namespace and cgroup kill followed by an observable empty-cgroup cleanup check |
| Forged result claims | Framed worker protocol, strict schemas, parent-computed commitments, and bounded stderr kept separate |
| Secret leakage | Empty environment, no credential inheritance, bounded local results, and existing genuine-secret redaction |
## Decision
### 1. Add a distinct `javascript_replay` permission capability
JavaScript replay receives a new permission capability named
`javascript_replay`. It does not inherit, imply, or satisfy
`process_capture`, `browser_observe`, `electron_observe`, artifact-read, or
workspace permissions. Grants for any of those capabilities do not satisfy a
JavaScript replay request, and a JavaScript replay grant does not authorize
them.
The administrator ceiling is disabled by default. Its eventual configuration
must commit:
- canonical roots from which module and optional stub files may be read;
- the exact Node.js and sandbox-backend executables;
- filesystem mount authority needed only to construct the private sandbox;
- network mode `none`; and
- no inherited environment names.
Configuration establishes only the maximum authority. Every execution also
requires an active permission grant and literal per-call approval bound to the
exact replay plan. Project, session, and administrator grants may satisfy the
permission-policy layer, but none replace that per-run approval.
Reproducer export is a separate host write after the sandbox has stopped. This
ADR's root-scoped `evidence_write` authority was removed; current exports use
the path supplied by the caller, while replay still waits for complete sandbox
cleanup before writing.
### 2. Admit extracted modules only
The v1 mode executes a finite, closed manifest of JavaScript modules. The
manifest identifies one entry module and every admitted dependency by a stable
sandbox alias and SHA-256 digest. Imports resolve only to another manifest
entry or to an explicitly declared, versioned stub. Bare package lookup,
ambient `node_modules`, import maps from the host, network imports, native
addons, WASI, FFI, child processes, workers, inspector activation, and implicit
dynamic import are unavailable.
Modules and stubs are read and hashed by the authorized parent, then copied as
bytes through a bounded private channel. Original host paths are not mounted
into the sandbox. The worker cannot reopen the operator's source path.
Source maps may supply locations, but source-map source code is not executed
unless its bytes are separately present in the approved manifest. A source-map
name or Webpack module ordinal is never execution authority.
REA does not launch, attach to, navigate, click, type into, or terminate the
user's application under this capability. A full application process remains
an independently approved Process Capture experiment; browser and Electron
targets remain passive. Any future mode that drives an application or permits
host/allowlisted network requires a new ADR and a distinct permission scope.
### 3. Use a two-phase, content-bound approval flow
One public replay surface supports a plan phase and an execute phase with the
same schema through CLI and MCP.
The plan phase:
1. validates all caller input and hard limits before file access;
2. obtains authority to read every selected module or stub path;
3. canonicalizes and opens each file without following an unapproved identity;
4. reads bounded bytes, computes digests, and closes the source descriptors;
5. resolves and probes the exact runtime and sandbox backend without running
application code;
6. normalizes stubs, inputs, generator settings, and limits; and
7. returns the complete proposed effects and a canonical `plan_digest`.
The plan must disclose at least:
- module aliases, canonical local paths, byte counts, and SHA-256 digests;
- input and stub identities, provenance, and digests;
- runtime and sandbox executable paths, versions, and executable digests;
- sandbox policy version and digest;
- network `none`, visible read-only runtime paths, and private writable tmpfs
size;
- time, CPU, memory, swap, task, temporary-storage, input, output, protocol,
case-count, and serialization limits;
- deterministic clock, PRNG seed/algorithm, locale, timezone, and platform
projection; and
- expected Evidence and cleanup behavior.
Execution requires the exact `plan_digest`. REA
rebuilds the plan immediately before admission. Any changed file, runtime,
sandbox executable, policy, stub, input, limit, or environment commitment
returns `plan_stale` before application code starts. Approval is not transferable
to a different plan and cannot be represented by a bare Boolean alone.
Interactive CLI may print the plan and ask for confirmation. Non-interactive
CLI and MCP must perform the same explicit plan/execute exchange; they may not
auto-approve because the caller requested JSON output or because permission
elicitation is supported.
### 4. Require an OS sandbox; fail closed elsewhere
The first production backend is Linux-only. It must combine:
- an empty mount namespace rooted in private tmpfs;
- a new user namespace with all capabilities dropped and further nested user
namespaces disabled;
- new PID, network, IPC, UTS, and cgroup namespaces;
- a new terminal session and parent-death behavior;
- no host D-Bus, agent, browser, Docker, Wayland/X11, SSH, GPG, audio, device,
or application sockets;
- a minimal, read-only runtime closure rather than `/`, the user's home,
working directory, or host `/tmp`;
- a fresh `/proc` for the sandbox PID namespace and a minimal private `/dev`;
- a parent-generated, architecture-checked seccomp policy that denies at least
namespace or mount changes, `ptrace` and cross-process memory inspection,
BPF/perf access, kernel keyring and module control, reboot/swap controls, and
the `TIOCSTI` terminal injection path;
- cgroup v2 `memory.max`, `memory.swap.max=0`, `pids.max`, and bounded CPU
controls owned for the one run; and
- an outer REA supervisor that can kill the complete cgroup and verify it is
empty.
The seccomp program is passed by descriptor, has a version and digest committed
to the replay plan, validates the syscall architecture before the syscall
number, and never permits `ptrace`-based mediation. Seccomp reduces exposed
kernel surface; it is not described as a complete sandbox by itself.
The reference backend for the implementation PR is Bubblewrap for namespace,
mount, and seccomp construction plus a delegated cgroup v2 manager for resource
enforcement. REA must feature-probe the actual required operations; version
text alone is insufficient. A setuid Bubblewrap installation, a backend that
silently skips a requested namespace or filter, unavailable user namespaces,
missing cgroup delegation, or inability to prove cleanup makes the capability
unavailable. REA setup must not install or upgrade Bubblewrap, systemd, Node.js,
or kernel components.
macOS, Windows, Linux hosts without every required feature, containers that
block the required namespaces, and alternative backends are unavailable in
v1. They must return precise diagnostics and remediation, not a process-only or
`vm`-only degraded mode.
Node.js runs with its permission model enabled and without grants for network,
filesystem, child processes, workers, native addons, WASI, FFI, or inspector.
That layer is defense in depth. It is never cited as the OS security boundary,
because Node.js explicitly does not promise containment of malicious code.
### 5. Make the worker disposable and deterministic by construction
Each approved run receives a new sandbox, runtime root, worker process, module
loader, and deterministic state. No module cache, realm, timer, file, global,
or child survives into another run. Within a multi-case run, every case gets a
fresh realm and fresh module instances; case order and generator state are
committed.
The worker exposes a small versioned set of language primitives and explicitly
selected stubs. It does not expose `process`, `require`, host `console`, timers,
`fetch`, sockets, filesystem APIs, `Buffer`, worker APIs, native bindings, or
ambient environment variables. Date/time, randomness, locale, timezone, and
platform values come only from committed deterministic providers. An
unsupported global or import produces an observed exception; REA does not
substitute a convenient host implementation.
Caller-provided stubs are executable untrusted code and receive the same
sandbox treatment as recovered modules. Built-in stubs have stable IDs,
versions, canonical source digests, and documented semantics. No undeclared
fallback stub is allowed.
Inputs are bounded canonical JSON. Results are projected without invoking
getters, proxies, `toJSON`, or arbitrary coercion: only admitted primitives,
arrays, and plain data properties are serialized. Cycles, accessors, functions,
symbols, unsupported prototypes, excessive depth, excessive nodes, and
oversized values become explicit serialization outcomes. Worker stdout is the
framed protocol only; bounded diagnostic stderr and bounded, opt-in console
observations remain separate.
### 6. Enforce independent resource ceilings
Every limit has a conservative product default. The v1 plan and result commit:
- an outer wall-clock deadline for the complete disposable run;
- cgroup memory, swap, task, and CPU ceilings;
- Node/V8 heap ceiling as defense in depth;
- private tmpfs bytes;
- serialized worker-protocol bytes, aggregate module bytes, and case-input
bytes; preset-generated cases also have a fixed preflight count ceiling;
- stdout, stderr, exception, stack, and aggregate retained-output bytes; and
- structured-result depth and node count.
The parent enforces protocol and output limits while bytes arrive, before JSON
parse or Evidence retention. The worker cannot request wider limits. A limit
hit terminates the complete run cgroup and is an observed termination, not a
partial successful return.
### 7. Preserve exact provenance and the right Evidence authority
A run that reaches worker admission produces Evidence with:
- provider `rea-javascript-replay` and a concrete implementation version;
- operation `run_controlled_replay`;
- authority `controlled-replay`;
- confidence `observed` for the exact returned value, thrown exception,
sandbox denial, limit termination, signal, exit, or crash that REA directly
observed;
- environment isolation `container`, the host platform/architecture, runtime
identity, sandbox-backend identity, and sandbox-policy digest;
- the replay plan digest, module and stub digests, canonical input or generated
case digests, deterministic providers, and every effective limit;
- bounded raw input, output, and exception data when retained, plus their
canonical digests and truncation state;
- start/admission/termination/cleanup states; and
- explicit limitations for incomplete output, nondeterminism not checked,
sandbox diagnostics, or cleanup that could not be proven.
The host module path remains an actionable local diagnostic and Evidence
subject location, while the worker sees only a stable alias. Module source is
not embedded in ordinary Evidence. A separately approved reproducer may copy
module/stub bytes or may retain path-plus-digest references; its manifest says
which mode was used. Repository tests use source-owned fixtures, and real-app
verification stores only digests and expected structural facts.
Derived differential results use confidence `derived` and link every source
run Evidence ID. A repeat with the same commitment can establish
`repeat-confirmed` for those runs; a single deterministic plan is only
`committed-not-confirmed`. Neither state proves behavior in the original
application.
When replay observations are added to the JavaScript Application Graph, their
graph-fact authority is `controlled-replay`. A claim that the real renderer,
preload, main process, or remote service behaves the same remains inferred or
unknown until compatible runtime authority exists. Static inference, passive
CDP observation, controlled replay, and real application interaction are never
promoted into one another.
### 8. Treat post-admission failures as observations
Pre-admission failures return a typed error and create no claim that module code
ran. Once the worker is admitted, REA retains a bounded execution record even
when the requested function does not return normally.
| Condition | Caller result and Evidence semantics |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| Disabled capability or missing grant | `permission_required`/`capability_unavailable`; no worker admission and no replay observation |
| Sandbox/runtime probe failure | `capability_unavailable` with exact failed feature; no module execution |
| Plan digest mismatch or changed source | `plan_stale`; no module execution |
| Sandbox setup fails before worker admission | `execution_failure`; no controlled-replay claim about the module |
| Module returns admitted data | Observed return value with complete or explicitly limited coverage |
| Module throws or result serialization rejects | Successful replay observation with outcome `exception` or `serialization_error`; application claim unknown |
| Node permission or sandbox denies an operation | Observed denial/termination when attributable; no claim that all attempted side effects were enumerated |
| Timeout, memory, CPU, task, tmpfs, or output hit | Observed limit termination; requested functional result unknown |
| Signal, runtime crash, or malformed protocol | Observed termination plus bounded diagnostics; functional result unknown |
| Caller cancellation after admission | Kill full cgroup, record cancellation/cleanup if possible, and project the public cancellation contract |
| Cleanup proves an empty cgroup and removed root | `cleanup: complete` |
| Cleanup cannot prove emptiness or removal | `cleanup_incomplete`, name every residual resource, and do not report success |
An exception is data, not an adapter failure. A sandbox setup error is not
evidence that the module crashed. A timeout is not evidence that the function
would never return. An output limit is not evidence that the truncated prefix
equals the full result. These distinctions are part of the public contract.
Cancellation and cleanup must be idempotent. REA first stops admission and
input, kills the owned cgroup, waits for an empty-cgroup observation, removes
the private runtime root, closes protocol descriptors, and releases timers.
Failure at one cleanup step does not skip the remaining steps.
### 9. Keep replay records reproducible without overstating determinism
The canonical replay manifest commits:
```text
plan structure and policy identity
REA/provider/runtime/sandbox executable identities and digests
module aliases, dependency graph, bytes digests, and source references
stub IDs, versions, source digests, and caller-provided stub digests
canonical inputs or generator algorithm, seed, case order, and case digests
clock, PRNG, timezone, locale, platform, and exposed-global commitments
all resource and serialization limits
network and filesystem projections
expected entry export and invocation convention
```
The result manifest adds canonical output/exception/termination digests,
coverage, dropped-data counts, cleanup state, and source Evidence links.
Canonical digests are computed by the trusted parent; worker-provided digests
are ignored.
Reproduction requires exact manifest compatibility. A runtime, sandbox policy,
built-in stub, module byte, generated case, limit, architecture, or platform
change is a different experiment. Cross-environment comparison may still be a
derived investigation, but it is never an exact replay.
### 10. Expose availability and policy truth before execution
`rea doctor`, capability inventory, and the planning response must report the
JavaScript replay capability without executing application code. Diagnostics
name the exact missing executable, unsupported host, failed namespace feature,
cgroup delegation failure, setuid rejection, runtime mismatch, or cleanup-probe
failure. Genuine secrets remain redacted; local executable paths, versions,
digests, and kernel feature failures remain visible.
The capability must be absent from executable tool routing until implemented.
Accepting this ADR does not increase the current tool count and does not add a
hidden experimental flag.
## Required implementation and verification gate
The implementation PR cannot merge until all of the following are true:
1. `javascript_replay` exists in configuration, permission policy, project
grants, policy explanation, CLI, MCP, docs, and capability inventory with
fail-closed defaults.
2. Plan and execute phases have schema-identical CLI/MCP behavior and an exact
plan-digest stale check.
3. No replay-disabled static, browser, Electron, session, setup, doctor, or
application workflow can reach module execution.
4. The worker never imports into the REA server process and no adapter offers a
`vm`-only fallback.
5. The Linux backend feature-probes namespaces, seccomp installation and
denial, delegated cgroup v2 limits, and the exact admitted architecture.
Every plan content-addresses the worker, seccomp filter, Node executable,
ELF loader, shared-library closure, and sandbox executables.
6. Source-owned fixtures cover parser, sanitizer, clipboard, exception,
ambient side-effect attempts, memory pressure, and busy loops. The worker
exposes no filesystem, environment, network, process, worker, native-addon,
timer, inspector, or ambient package-resolution API.
7. Tests and the real verifier prove bounded protocol/diagnostics, timeout and
OOM cgroup termination, and observed cgroup cleanup.
8. Evidence tests cover observed return/exception/termination, derived
comparison with source Evidence links, stale admission, cancellation
projection, and explicit limitations on application-level claims.
9. Package verification exercises the target-free public contract. The
dedicated real-Linux workflow exercises the sandbox backend; environments
without delegated user namespaces or cgroups report truthful unavailability
rather than selecting a weaker backend.
10. A real operator-local Notion-like parser or sanitizer benchmark can run
without committing its source, and exports only approved local reproducer
material.
## Rejected alternatives
### Reuse `browser_observe`, `electron_observe`, or `process_capture`
Rejected because those grants authorize different effects. Reuse would turn a
passive or unsandboxed process permission into recovered-code execution.
### Execute in the MCP server with `vm.runInContext`
Rejected because a VM context is not a security boundary and a crash, resource
attack, or escape would compromise the long-lived session and its credentials.
### Use only the Node.js permission model
Rejected because Node.js documents it as a seat belt for trusted code and
explicitly does not guarantee containment of malicious code. It remains a
defense-in-depth layer inside the OS sandbox.
### Ship a process-only fallback on unsupported hosts
Rejected because it changes the security claim while preserving the same tool
name. Unsupported hosts return unavailable.
### Permit network allowlists in v1
Rejected because DNS, redirects, proxies, credentials, service identity, and
response nondeterminism would substantially expand the threat and Evidence
model. The v1 namespace has no host or external network.
### Mount the approved project root read-only
Rejected because one approved module does not imply authority to disclose
every file in its project. The parent stages only exact, digested bytes.
### Treat exceptions, crashes, or limit hits as ordinary tool errors only
Rejected because that discards the principal behavioral observation and makes
negative results impossible to reproduce. Post-admission termination is
retained with explicit functional uncertainty.
## Consequences
- JavaScript replay is Linux-only at first and may be unavailable on containers
or distributions that disable user namespaces or cgroup delegation.
- The implementation requires more host probing and lifecycle code than a
simple Node worker, but the public security claim remains stable.
- Plans require two calls in non-interactive environments and become stale when
any committed input changes.
- Network-dependent modules and full application interactions are excluded;
their absence is explicit rather than emulated implicitly.
- Results are reproducible for the committed isolated experiment, not proof of
production behavior.
- Adding another sandbox backend, network mode, or application-interaction mode
requires a separate reviewed decision and conformance suite.
## References
- [Node.js permissions](https://nodejs.org/api/permissions.html) documents that
the permission model does not protect against malicious code and describes
its known filesystem and cross-process limitations.
- [Bubblewrap README](https://github.com/containers/bubblewrap/blob/main/README.md)
describes its namespace construction and makes clear that the caller's
arguments, not Bubblewrap alone, define the sandbox security model.
- [Linux seccomp filter documentation](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html)
explains that syscall filtering reduces kernel surface but is not a complete
sandbox by itself.
- [ADR-0001](0001-provider-selection-and-analysis-profiles.md) establishes the
existing rule that provider selection, Evidence provenance, and capability
unavailability remain explicit and never silently fall back.
@@ -1,452 +0,0 @@
# ADR-0003: Managed-code evidence and provider boundary
> Historical design record: The non-executing runtime-correlation planning
> tool described in earlier revisions was removed. This ADR's current
> implementation status below covers only the static managed tools that ship.
- Status: Superseded for runtime planning; static evidence boundary remains in force
- Date: 2026-07-16
- Implementation status: Read-only PE/CLI triage and exact identity are shipped
through `inspect_managed_artifact` / `rea inspect-managed-artifact`. Bounded
metadata, signatures, method bodies, raw CIL hashes, limited
decoded-instruction-tuple v1 hashes, exception regions, call edges, and
field-access anchors are shipped through `inspect_managed_members`; `rea
inspect-managed-members` provides CLI parity. Static member comparison and build-local
token remapping are shipped through `compare_managed_members` /
`rea compare-managed-members`. Declaration-only managed/native boundary
inventory for ModuleRef, ImplMap/PInvoke, ReadyToRun indicators, and non-IL
method flags is shipped through `inspect_managed_native_boundaries` /
`rea inspect-managed-native-boundaries`. Managed/native export or function
Evidence matching is shipped through `verify_managed_native_boundaries` /
`rea verify-managed-native-boundaries`; it verifies only supplied P/Invoke
export/function observations and does not map managed tokens to native
addresses. Decompiler reconstruction import is
shipped through `import_managed_reconstruction` /
`rea import-managed-reconstruction`; it records user-supplied C#/IL/pseudocode
as analyst inference only after exact static member locks match. Managed
inspection does not execute assemblies or observe CLR internals. Managed static graph
projection is shipped through
`project_managed_application_graph` /
`rea project-managed-application-graph`; it projects authenticated managed
Evidence into the application graph without changing managed tokens into
native addresses. Native-body bridge mapping and an actual runtime executor
remain future contracts.
## Context
Professional C# reverse engineering is not one decompiler operation. A file
described as “.NET” can be ordinary Common Intermediate Language (CIL),
ReadyToRun code containing both CIL and native implementations, a single-file
deployment, C++/CLI mixed mode, Unity Mono, Unity IL2CPP, or NativeAOT. Those
forms have different sources of truth and different native-analysis needs.
Choosing a decompiler before classifying the artifact can therefore produce a
plausible but false model.
The durable static facts in an ordinary managed PE are its PE/CLI headers,
metadata tables, signatures, method bodies, exception regions, and CIL. A C#
decompiler reconstructs source-like control flow and language constructs from
those facts. That reconstruction is valuable, but it is not the original
source and cannot replace the underlying metadata and CIL evidence. Obfuscation
makes names especially weak while tokens remain coordinates in only one build.
REA already separates one selected deep native provider from disjoint auxiliary
providers under [ADR-0001](0001-provider-selection-and-analysis-profiles.md).
It also separates static evidence, passive observation, process capture, and
interactive observation authorities. Managed analysis must fit those boundaries
without requiring a CLR to inspect an artifact, loading target code into the
REA process, or treating a managed token as a native address.
The design is informed by exact-build, reflection-free metadata extraction,
hash-locked method manifests, independent behavior models, and managed/native
boundary analysis performed against a local C# application. The application,
its decompiler output, and its runtime observations are research inputs only;
they are not distributable REA fixtures.
## Decision drivers
1. Classify the deployment before selecting an analysis route.
2. Make metadata and CIL independently inspectable without a CLR or target
execution.
3. Preserve exact-build provenance while enabling structural comparison across
builds whose MVIDs, tokens, names, and layout differ.
4. Compose managed and native analysis without introducing another ambiguous
deep-provider candidate.
5. Keep decompiled C# useful but epistemically subordinate to canonical bytes.
6. Analyze Linux, macOS, and Windows managed artifacts through the same local
CLI/MCP contracts on REA's supported hosts.
7. Keep setup additive and prevent managed analysis from installing .NET,
ILSpy, an SDK, or another unrelated toolchain.
8. Prove semantics with source-built conformance artifacts and compact,
operator-local real-application checks.
## Terminology
- **Managed artifact**: a PE, bundle component, or related metadata artifact
that carries a CLI header, CLI metadata, CIL, or another managed-runtime
commitment.
- **Classification vector**: independently observed container, runtime family,
implementation form, and architecture. It is not one guessed label.
- **Canonical static observation**: a bounded value decoded directly from the
target bytes under a versioned parser contract.
- **Reconstruction**: source-like output, including decompiled C#, derived from
canonical observations.
- **Structural inference**: a relationship or cross-version match derived from
signatures, APIs, constants, control/data-flow shape, or other observations.
- **Validation**: an independently checked proposition, for example a
source-built oracle assertion or a behavior-model corpus result.
- **Runtime observation**: a separately authorized fact obtained by attaching,
loading, debugging, instrumenting, or otherwise executing code.
## Decision
### 1. Classify before analyzing
Managed triage returns a classification vector and the observations supporting
each dimension. Absence of a marker produces `unknown` or `not_applicable`, not
an invented runtime family.
| Dimension | Initial values |
| ------------------- | ------------------------------------------------------------------------------------------------------------ |
| Container | PE file, single-file bundle, bundle component, Unity metadata pair, native image, malformed, unknown |
| Runtime family | .NET Framework, modern .NET, Unity Mono, Unity IL2CPP, NativeAOT, mixed CLR/native, unknown |
| Implementation form | CIL, CIL plus ReadyToRun, native only, C++/CLI mixed, metadata only, unsupported, unknown |
| Architecture | PE machine plus CLI flags; component-specific architecture for bundles; conflicting or unknown when required |
Target-framework attributes, assembly references, metadata stream versions,
bundle manifests, ReadyToRun directories, and native headers are observations.
They may support a runtime-family inference, but no single string is treated as
authoritative when the other bytes conflict.
Classification selects these routes:
| Observed form | Managed route | Native route and limitation |
| --------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| Ordinary Framework or modern CIL | Full metadata, signatures, method bodies, and CIL | Optional only for declared interop boundaries |
| Obfuscated CIL | Same canonical route; names receive no special trust | Optional for declared interop boundaries |
| Unity Mono assembly | Same canonical route with Unity context retained | Optional for engine/native boundaries |
| ReadyToRun | Metadata/CIL where present; implementation availability is per method | Selected Hopper/Ghidra analyzes native sections; CIL absence is reported per method |
| C++/CLI mixed mode | Metadata/CIL for managed members and explicit mixed-mode boundary observations | Selected Hopper/Ghidra analyzes native bodies; REA never converts tokens directly to native addresses |
| Single-file deployment | Inventory the bundle, then analyze each authenticated managed component | Selected Hopper/Ghidra analyzes the host/native components; unsupported compression remains explicit |
| Unity IL2CPP | Pair and authenticate available Unity metadata; do not claim canonical CIL | Selected Hopper/Ghidra analyzes the generated native binary; semantic recovery is degraded until supported |
| NativeAOT | Report any independently present managed metadata, otherwise no CIL claim | Treat as a native target with NativeAOT provenance; managed source reconstruction is unavailable |
| Malformed or unsupported artifact | Return bounded partial observations and typed unavailable/unknown scopes | Do not silently retry by loading or executing the file |
Classification is byte-driven and bounded. File extensions, product names,
process names, and an operator's description are hints only.
### 2. Implement managed static analysis as a disjoint auxiliary provider
The initial producer is a REA-owned auxiliary provider with ID
`rea-dotnet-static`. It owns a disjoint managed-artifact operation family. It is
not registered as a Hopper/Ghidra deep-provider candidate because it does not
compete for the same operation names and must be able to coexist with the one
selected native provider.
```text
one opened artifact/session
|
SessionProviderRouter
/ \
rea-dotnet-static auxiliary selected deep binding
PE/CLI metadata and CIL Hopper or Ghidra
\ /
explicit managed/native links
|
Evidence and workflows
```
An ordinary managed artifact can therefore remain unbound to a deep native
provider while managed operations work. ReadyToRun, C++/CLI, IL2CPP, NativeAOT,
and interop workflows may additionally require a caller-selected native
binding. Native-provider failure never causes managed evidence to be relabeled,
and managed-parser failure never causes an implicit native fallback.
Provider mechanics live under a provider directory such as `src/dotnet/`.
Provider-neutral identities, evidence states, and bounded values may live in
the domain/contracts layers. Application code composes results but does not
parse PE headers, metadata tables, signatures, CIL, ReadyToRun headers, or
provider-specific output.
### 3. Make the production static path byte-only and execution-free
`rea-dotnet-static` reads approved local bytes and implements the required
PE/CLI metadata and CIL subset in TypeScript. It does not call any reflection
API and does not require the .NET runtime. In particular, static inspection
must never:
- call `Assembly.Load`, `Assembly.LoadFrom`, `ReflectionOnlyLoad`, or an
equivalent runtime loader;
- resolve target dependencies by executing target-controlled resolver code;
- run module initializers, constructors, entry points, build tasks, plugins, or
generated helpers;
- start the target, attach to a process, contact a service, or inherit target
configuration and credentials; or
- interpret a decompiler, CLR, or native-provider diagnostic as an observation
from the artifact bytes.
The parser uses checked offsets and additions, explicit endianness, bounded
table/heap/body counts, cycle-safe traversal, and typed partial results. A bad
row, signature, body, resource, or stream does not authorize an unbounded retry
or a CLR load. Complete-coverage claims require every applicable bounded region
to have been admitted; otherwise coverage is partial, unknown, or unavailable
with exact offsets and reasons.
The caller selects the local input path directly. Local artifact
paths, digests, MVIDs, tokens, malformed offsets, and analysis metadata are
actionable diagnostics and are not secrets. Credentials, authorization data,
and genuine secrets remain redacted.
### 4. Bind every finding to exact artifact and producer identity
Every managed result carries a commitment with at least:
```text
artifact: canonical path + byte length + SHA-256
component: container identity + component path/name + component SHA-256, when applicable
classification: container + runtime family + implementation form + architecture
assembly/module: simple name + version + culture + public-key identity + module name + MVID
producer: provider ID + exact version + analysis-affecting parameters + profile digest
```
An assembly-qualified name does not replace the artifact digest or MVID.
Neither an MVID nor an Authenticode signature proves who authored the behavior.
Bundle components retain both their container and component commitments so that
bytes extracted from another host cannot be silently substituted.
Method observations add:
```text
declaring type + normalized CLI signature
build-local metadata token
RVA/file extent when present
raw CIL byte length + SHA-256 when the body is admitted
decoded-instruction-tuple SHA-256 when CIL is valid
separate max-stack, locals-token, and exception-region observations
```
The shipped `il_sha256` commits only the raw CIL byte stream identified by the
method header's `il_size`. It does not commit the method header, local-signature
blob, alignment padding, or extra sections such as exception clauses. Those
facts remain separate observations and the enclosing artifact SHA-256 binds
them to the exact file. A digest over the complete method body is not shipped.
The caller-visible field remains named `normalized_il_sha256`, but its shipped
v1 meaning is deliberately narrower than a canonical semantic CIL identity.
For a completely decoded method, REA serializes the instruction-order array of
`[opcode, operand_kind, operand]` tuples with JavaScript `JSON.stringify`,
encodes that text as UTF-8, and reports its lowercase SHA-256. The tuple
projection is defined here; the member result carries only the described
normalized digest.
Operands retain the current decoder projection: metadata and user-string
operands are build-local lowercase hexadecimal tokens, scalar branch operands
are decimal target CIL byte offsets, and `switch` retains only its decimal case
count. Constants and variable indexes are decimal strings; an operand-free
instruction uses kind `none` and value `null`. Opcode names preserve distinct
short forms and prefix instructions, but instruction offsets, branch target
instruction identity, switch targets, resolved token identities, method
headers, locals, and exception regions are not part of this digest. A partial
or malformed decode has no `normalized_il_sha256`.
Consequently v1 is a deterministic decoded-tuple fingerprint, not proof of
semantic equivalence. In particular, methods with the same opcodes and switch
case counts can share it despite different switch targets, and token movement
can change it without a semantic change. Cross-build comparison may use it as
one unique-only structural tier while retaining artifact/MVID commitments and
ambiguity; it must not describe the digest itself as token-remapped canonical
CIL. Canonical operand resolution, complete control-flow operands,
exception/local commitments, and an explicit algorithm version require a new
normalized-CIL schema.
Metadata tokens are reported because they are precise coordinates inside one
module. Cross-version identity never consists of a token alone. Matching tries
exact CIL/signature identity, then an exact declared-type/name/signature tuple,
then structural shape; a name by itself never selects a pair. Partial or
malformed bodies leave body facets unknown after a signature tuple pairs the
methods. Matches cite both build commitments, both local tokens, and all
competing candidates. V1 cannot cite a separate matching-algorithm version
because none is exposed.
### 5. Separate five evidence layers
Managed workflows retain these layers independently:
| Layer | Examples | Permitted claim |
| ---------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------- |
| Static observation | Metadata row, signature, CIL opcode, literal, exception region | “These bounded bytes decode to this value.” |
| Reconstruction | Decompiled C#, async/iterator source shape, expression simplification | “This is one source-like representation of cited observations.” |
| Structural inference | Likely caller, field flow, behavior slice, cross-build method match | “These cited structures support this relationship.” |
| Independent validation | Synthetic oracle, corpus result, second parser agreement | “This declared proposition passed the named independent check.” |
| Runtime observation | Exact-build attach/load/instrumentation event | “This separately authorized experiment observed this event.” |
Each layer has its own producer, authority, state, confidence, coverage, and
limitations. A readable C# method is never emitted as original source or exact
semantic proof. A validator does not upgrade unrelated claims. Runtime
agreement does not retroactively turn a static inference into an observation.
Negative results are scope-qualified. For example, “no declared P/Invoke rows
were found in the admitted metadata tables” does not prove the application has
no native, dynamically resolved, generated, server-side, or protected path.
### 6. Admit ILSpy only as an optional reconstruction and conformance tool
REA's canonical static operations do not depend on ILSpy, a .NET SDK/runtime,
dnlib, or Mono.Cecil. The following review was current on the decision date:
| Tool | Reviewed coordinate | License | Runtime/host observation | Decision |
| ---------------------------- | ------------------- | ------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `System.Reflection.Metadata` | 10.0.10 | MIT | Library targets .NET Framework 4.6.2, .NET 8/9/10, and .NET Standard 2.0 | Pinned independent metadata oracle for conformance; not shipped or invoked by production parsing |
| `ICSharpCode.Decompiler` | 10.1.1.8388 | MIT | Library targets .NET Standard 2.0; output is reconstruction | Pinned reconstruction/differential oracle candidate |
| `ilspycmd` | 9.1.0.7988 | MIT | Cross-platform .NET 8 tool; newer 10.1.1.8388 requires .NET 10 | Initial optional BYO reconstruction coordinate because it matches the source research baseline |
| dnlib | 4.5.0 | MIT | Cross-platform library; also exposes assembly-writing APIs | Differential test candidate only; its writable model is outside the production trust boundary |
| Mono.Cecil | 0.11.6 | MIT | Cross-platform .NET Framework/.NET Standard library with read/write support | Differential test candidate only; not a production dependency |
Coordinates and package hashes used by real verification are checked into a
source-owned lock manifest when that verifier is implemented. “Latest” is
never a reproducibility coordinate. A version change requires conformance and
an explicit profile/version change.
Artifact platform and REA host support are separate. The byte-only parser must
inspect PE/CLI artifacts produced for Windows on a supported Linux or macOS REA
host; that is not a claim that REA itself currently runs on Windows. Managed
library/tool candidates above are cross-platform at their reviewed targets, but
native composition remains limited by the selected Hopper/Ghidra host and
format support. Real verification runs the canonical path on Linux and macOS
and may run pinned oracle checks on Windows without turning that development
check into a public Windows-host claim.
If a caller-visible C# reconstruction operation is admitted, it is a distinct
optional capability. It accepts only an exact supported BYO `ilspycmd`, records
the tool and decompiler version, runs in an owned bounded process without
loading target code into REA, and links output to the canonical method
observation. Setup and installers do not download or install ILSpy, .NET, an
SDK, or a runtime. Doctor may inspect an explicitly configured executable and
report exact actionable incompatibility. Missing reconstruction never removes
canonical metadata/CIL capabilities.
This decision does not make a decompiler process a security sandbox. The
initial public path can defer C# reconstruction while canonical contracts and
process isolation are proven.
### 7. Use source-built conformance and operator-local real targets
The repository stores source, build descriptions, expected semantic facts,
and tool lock manifests, but not compiled managed binaries. An isolated build
step creates fixtures outside source directories and records their SHA-256 and
MVID before verification. At minimum, the corpus covers:
- Framework-compatible and modern .NET metadata;
- AnyCPU, x86, and x64 PE/CLI flags;
- generics, nested types, overloaded signatures, properties, events, resources,
attributes, and constants;
- exceptions, filters, prefixes, switch branches, P/Invoke, async and iterator
state machines;
- obfuscated and Unicode names without assigning semantics from names;
- malformed headers, tables, heaps, signatures, bodies, and exception regions;
and
- two semantically related builds with different MVIDs, tokens, layout, and
selected names.
Expected facts are checked directly and against pinned
`System.Reflection.Metadata`; ILSpy, dnlib, or Mono.Cecil may add differential
coverage but do not vote by majority. Disagreement is a failing or explicitly
unsupported case, not silently normalized output.
The real-application benchmark is an operator-local, opt-in osu! check derived
from the research workflow. It accepts an explicit path plus a compact
expectation manifest; verifies target SHA-256, MVID, architecture, and expected
assembly identity before analysis; and emits only bounded identities, tokens,
signatures, IL lengths/hashes, match states, and assertion results. It does not
emit full IL, decompiled source, runtime logs, user data, credentials, or
service/account material. No proprietary binary, hash-locked application
manifest, or derived dump is committed to REA.
### 8. Keep runtime behavior separate from static managed analysis
No managed runtime planning or execution tool ships. Managed inspection does
not execute assemblies or establish which methods ran. Where supported, direct
process capture can record target-level inputs and outputs, but it does not
prove CLR method execution or resolution. Internal managed behavior remains
unknown until independently observed with suitable runtime evidence.
## Public contract consequences
- Managed static operations will have CLI and MCP parity and produce the same
Evidence commitments.
- Adding managed operations changes the caller-visible tool inventory and
generated product catalog only in the implementation PR that admits them.
- Partial parsing includes admitted/dropped counts, exact limitations, and
coverage; it never returns a partial list labeled complete.
- Managed addresses distinguish file offsets, RVAs, native virtual addresses,
metadata tokens, and CIL offsets. They are not interchangeable.
- Cache compatibility is exact on artifact/component commitment, member-result
fields, parser profile, and producer version. For shipped v1,
`normalized_il_sha256` has no independent algorithm-version field.
- Provider-neutral workflows may compose canonical managed findings with the
one native binding, but every source operation retains its actual producer.
## Alternatives rejected
### Make ILSpy the only managed provider
This would make canonical metadata/IL inventory depend on a separately
installed CLR and conflate source reconstruction with byte observations. It
would also make tool-version drift part of ordinary inventory. ILSpy remains a
valuable optional reconstruction and conformance tool instead.
### Use `Assembly.Load` or reflection-only loading
Both delegate parsing and dependency behavior to a CLR and make static support
runtime-dependent. Ordinary loading can execute target code; reflection-only
loading still establishes a CLR load boundary and is unavailable across modern
runtimes in a uniform way. Neither is required to decode ECMA-335 bytes.
### Register the managed analyzer as another deep candidate
That would force callers to choose managed analysis instead of Hopper/Ghidra
for ReadyToRun and mixed-mode artifacts even though both are needed. Disjoint
auxiliary composition represents the real ownership boundary.
### Treat tokens, names, or decompiler output as durable identity
Tokens and obfuscated names change across builds, while decompiler output
changes across tools and versions. They remain useful build-local coordinates
or reconstruction labels but are insufficient for exact or structural
cross-version identity.
### Package a .NET runtime or mutable managed library in REA
This would expand installer effects, package size, patching obligations, and
the target-parsing attack surface. The initial byte parser keeps canonical
support within REA's existing Node runtime; external managed tools remain BYO
or development-only oracles.
## Rollout gates
1. Add read-only triage and identity with malformed-input bounds. Shipped.
2. Add metadata, signatures, method bodies, deterministic decoded-CIL tuple
fingerprints, and exact artifact Evidence. Shipped with the v1 limitations
above; full normalized-CIL semantics remain planned.
3. Add obfuscation-resistant slices and cross-build match states. Shipped.
4. Compose explicit managed/native boundaries with Hopper/Ghidra. Declaration
inventory and native export/function Evidence matching shipped; native-body
bridge mapping remains planned.
5. Add source-built, pinned real-tool, package, CLI, and MCP conformance.
Source-owned conformance is shipped; pinned external real-tool checks remain
planned.
6. Project authenticated managed static Evidence into the application graph.
Shipped.
Every gate must keep unsupported ReadyToRun, NativeAOT, IL2CPP, mixed-mode, or
bundle cases explicit rather than broadening claims to make a fixture pass.
## References
- [ECMA-335: Common Language Infrastructure](https://ecma-international.org/publications-and-standards/standards/ecma-335/)
- [.NET ReadyToRun deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run)
- [.NET Native AOT deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)
- [.NET single-file deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview)
- [`System.Reflection.Metadata` package](https://www.nuget.org/packages/System.Reflection.Metadata/10.0.10)
- [ILSpy repository and releases](https://github.com/icsharpcode/ILSpy)
- [dnlib repository](https://github.com/0xd4d/dnlib)
- [Mono.Cecil repository](https://github.com/jbevain/cecil)
-11
View File
@@ -1,11 +0,0 @@
# Architecture decision records
Accepted decisions describe the architecture that implementation PRs must
follow. Acceptance does not by itself mean the behavior is shipped; each record
states its implementation status separately.
| ADR | Status | Implementation |
| ------------------------------------------------------------------------------------------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [0001: Provider selection and analysis profiles](0001-provider-selection-and-analysis-profiles.md) | Accepted | Provider selection and 25 read-only Ghidra operations on Linux/macOS and experimental Windows x64 P0; Linux/macOS session annotations |
| [0002: Controlled JavaScript replay authority and sandbox policy](0002-controlled-replay-authority-and-sandbox.md) | Superseded | Historical design; the controlled JavaScript replay tool was removed |
| [0003: Managed-code evidence and provider boundary](0003-managed-code-evidence-and-provider-boundary.md) | Partially superseded | Seven static managed tools remain; runtime planning removed |
+23 -3
View File
@@ -118,10 +118,25 @@ selected overload. Native/abstract methods with no decompiled body report
responses remain in Evidence. Source revision is populated only for bytes
matching the audited release JAR.
If a later step fails, the error's `details.partial_observation` retains the
selected and resolved APK paths, digest, observed provider identity and versions,
and each upstream request and reply collected before the failure. Failed replies
remain available even when their payload cannot be interpreted. Cancellation
also stops target hashing before provider admission.
These operations do not execute the APK or provide split APK/AAB handling,
signature validation, full resource-table semantics, native-library analysis or
Android runtime capture. Existing artifact inventory/extraction tools can supply
archive evidence. Project that Evidence with the execution-free inventory tool:
Android runtime capture. An `.aab` suffix is a ZIP archive, not an APK, so
Android tools and the application graph do not treat it as a standalone APK.
Existing artifact inventory/extraction tools can supply archive evidence.
Inventory records an APK root only for ZIP bytes whose name ends in `.apk`.
The projection adds a limitation when no root `AndroidManifest.xml` was
observed, because such a ZIP may not be an APK. Nested members take a ZIP or
ASAR family from their bytes; an unread member keeps an unknown format.
Inventory keeps ZIP names that differ only in case and records that a
case-insensitive destination cannot store both spellings. Extraction fails
only when that destination directory cannot keep both names. Project that
Evidence with the execution-free inventory tool:
```sh
rea project-android-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'
@@ -138,7 +153,12 @@ rea project-android-application-graph '{"inventory_evidence":[<inventory_artifac
The projection reports exact component paths and hashes, runtime-family hints,
and path-based bridge hypotheses. It does not decode DEX or claim observed
runtime calls. Bridge hypotheses form a DEX/JVM-class by native-library
runtime calls. Framework hints match complete native library names, such as
`libreactnativejni.so`, `libreactnative.so`, `libhermes.so`,
`libhermes_executor.so`, `libflutter.so`, and `libunity.so`; unrelated names
such as `libcommunity.so` and `libreactivity.so` do not identify those families.
The bridge basis is inferred from the native path and repeated for each managed
component, so it does not identify a specific JNI binding. Bridge hypotheses form a DEX/JVM-class by native-library
Cartesian product. The projection computes the product and exact serialized
candidate-array size before creating candidate objects, then retains a
deterministic prefix within a 2 MiB UTF-8 JSON budget. If candidates are omitted,
+86
View File
@@ -0,0 +1,86 @@
# Apktool resource decoding
REA decodes Android resource tables and the binary manifest through the
caller's Apktool launcher. This completes the static triad for Android
targets: Java/Kotlin sources through the JADX family, engine-grade
decompilation through JEB, and resources through this family. REA never
installs Apktool or a Java runtime.
## Supply tools
Use Apktool 2.7.0 or newer (verified with 2.7.0) and a Java runtime the
launcher can find. Select the launcher through the environment:
```sh
# Optional: absolute path to the apktool launcher (upstream wrapper or a
# java -jar script); without it, apktool resolves from PATH.
export REA_APKTOOL_COMMAND=/absolute/path/apktool
```
Readiness is `rea inspect-apktool-client`: it runs `apktool --version` and
reports the resolved launcher, its selection source, and its version. A
missing launcher reports `capability_unavailable` with the
`REA_APKTOOL_COMMAND` remediation rather than attempting an installation.
## Answer an analyst question
```sh
rea inspect-apktool-client
rea decode-android-resources /targets/Example.apk
rea decode-android-resources /targets/Example.apk --locale de
rea decode-android-resources /targets/Example.apk --no-strings
```
Equivalent MCP methods are `inspect_apktool_client` and
`decode_android_resources`. The decode request takes `path`, an optional
`locale` (project `res/values-<locale>/strings.xml` instead of the default
table), and `include_strings` (default true). Regional locales such as `pt-BR`
select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
`b+zh+Hans+CN` may also be supplied directly.
## Interpret the result
- **An owned APK snapshot is digested and decoded.** `target.sha256` and
`target.bytes` bind the observation to the exact APK that was decoded.
- **Metadata comes from apktool.yml as apktool printed it.** Version codes
keep their own spelling (`'7'` versus `7`); `package_name` is read from
the decoded manifest, not inferred.
- **The manifest is the decoded text**, bounded at 512 KiB and reported as
truncated when larger.
- **Strings are projected verbatim.** Escaped entities stay escaped, and
entries containing nested markup (`<b>`, `<xliff:g>`) are counted as
unparsed rather than flattened — the limitation names the count. The
default table is bounded to 2000 entries with partial coverage when more
exist; `locales` lists every `values-<locale>` that has a strings table.
- **Smali is skipped by design** (`apktool d --no-src`): Java-source
recovery belongs to the JADX family. Resource smali edits and rebuild are
a follow-up lane with mutation authority.
- **Workspaces are owned and short-lived.** Decoding happens in a
provider-owned temporary directory that is removed before the result is
returned. The APK snapshot and framework cache both live inside this directory.
If removal fails, the result names the residual path and the provider retains
ownership for a cleanup retry on close, including failed decodes.
## Resource and lifecycle limits
- The decode runs with a 600 s deadline and a 4 MiB output capture budget;
a stopped decode reports `provider_timeout` and exceeded budgets report
`resource_constraint`.
- Manifest reads are bounded to 512 KiB before decoding UTF-8. Strings XML
reads are bounded to 8 MiB; larger documents are skipped with partial
coverage and an explicit limit, rather than reported as missing.
- `decoded_file_count` is capped at 100,000 files; the cap is reported in
the limitations when hit.
- Apktool's own decode failures (`AndrolibException`, directory traversal
refusals) surface as `unsupported_target` with apktool's reason preserved
verbatim.
## Real verification
`npm run verify:apktool -- --apk PATH` exercises both operations against a
real launcher. Record: apktool 2.7.0-dirty (Debian packaging) on Linux with
OpenJDK 25 against a signed aapt2-built probe APK carrying two resource
locales — launcher version, on-disk digest agreement, apktool.yml metadata
(1.2.3, SDK 24–34), manifest package agreement, default and `de` string
tables projected. Parser goldens in the test suite come from the same
decode. See `docs/testing.md` for the lane summary.
+10
View File
@@ -7,6 +7,16 @@ hashes, detected formats, bundle anatomy, runtime-family hints, and path-based
bridge hypotheses. It does not parse plist or CMS semantics or claim observed
runtime calls.
Framework hints match complete path segments such as `React.framework`,
`ReactNative.framework`, `hermes.framework`, `Flutter.framework`, and
`UnityFramework.framework`. Substrings in `Preact.framework`,
`Community.framework`, or `MyApp.framework` do not identify those families.
A generic `App.framework` also does not identify Flutter by itself. Runtime
families remain inventory-derived hints, not observed loading. Generic framework
and dylib paths do not establish Swift or Objective-C; this projection does not
decode language metadata. A bridge basis is inferred from the native path and
repeated for each paired script, rather than proving a particular binding.
```sh
rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'
```
+1 -1
View File
@@ -58,7 +58,7 @@ graph TD
end
subgraph "Configuration"
CONFIG["src/config.ts + src/config/<br/>Zod-validated env parsing<br/>provider settings and origins"]
CONFIG["src/config/<br/>Zod-validated env parsing<br/>provider settings and origins"]
end
subgraph "Tests"
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

+51
View File
@@ -91,6 +91,12 @@ one-shot invocations pass portable inline Evidence JSON; an MCP session uses
the retained `evidence_id`. Page `limit` is required and bounded by the
measured MCP stdio budget documented on the tool contract.
Over MCP, `inspect_binary_layout` with `"detail": "summary"` retains the
complete layout Evidence in the session and returns only its summary view.
Its `normalized_result.parent_evidence_id` names the retained layout for later
section, symbol, mitigation or linkage views. The default `complete` detail and
CLI output are unchanged.
Complete results have a 32 MiB input, 64 MiB reply, 1 MiB combined diagnostics
and 30-second owned command deadline. The reply budget applies to the decoder
record; the CLI/MCP Evidence envelope adds copies and encoding overhead. The
@@ -136,3 +142,48 @@ malformed limit reports remain unknown with their read failure preserved. A
received signal alone does not establish its exact cause. Dynamic tags require
a complete DT_NULL inside PT_DYNAMIC; interpreter names and ranges end at the
first NUL, with any padding still represented by the original segment range.
## Portable PE resources
`inspect_pe_resources` / `inspect-pe-resources` inspects an explicit PE32 or
PE32+ file without an active target, native engine, Python, or Windows SDK:
```sh
rea inspect-pe-resources ./selected.exe --json
```
```json
{
"name": "inspect_pe_resources",
"arguments": { "path": "/artifacts/selected.exe" }
}
```
The complete Evidence identifies the stable artifact snapshot by path, byte
count and SHA-256. Resources retain separate type, name and language identities:
numeric IDs are distinct from UTF-16 names, whose original bytes are also
reported. Directory headers, entries, data entries and payloads retain original
file offsets and lengths. Each opaque payload has its own SHA-256; code page and
reserved data-entry fields are preserved.
RT_GROUP_ICON records expose original image descriptors and RT_ICON candidates.
A reference resolves only when an icon with the same numeric ID and language
exists. Missing references, other-language candidates and declared-size mismatch
remain explicit. Encoded dimensions are preserved (zero denotes 256 pixels).
This is static reference inspection; no image decoding, language fallback,
resource loading or selected-file execution occurs.
An absent resource data directory is a complete empty inventory. Malformed
headers, truncated tables, cycles, duplicate sibling identities, unbacked or
ambiguous RVA mappings, nonidentical overlapping ranges and unsupported tree
shapes fail explicitly, rather than returning partial inventories. Exact shared
payload ranges are supported. The supported tree has three levels: type, name,
and language. Other resource payload formats remain opaque.
`max_file_bytes` defaults to 64 MiB (maximum 512 MiB); `max_entries` defaults to
4096 (maximum 65536). CLI options are `--max-file-bytes` and `--max-entries`.
Metadata is bounded to 8 MiB; exceeding any budget fails without truncation.
Large Evidence envelopes may require a caller-configured MCP transport receive
buffer because envelope copies add overhead. Requests honor cancellation during
snapshot reading, directory traversal and payload hashing. The operation reads
regular files only and rejects symbolic links.
+3 -2
View File
@@ -14,10 +14,11 @@ REA can attach to a user-owned Chrome-family browser through the Chrome DevTools
- `inspect_web_page` / `rea inspect-web-page` captures DOM structure, accessibility nodes, scripts, resources, safe response/DOM metadata, attach-window network and console metadata, WebSocket frame sizes, workers, quota, and optionally selected storage key names, redacted storage-content fingerprints, or script sources.
- `analyze_web_bundle` / `rea analyze-web-bundle` parses selected script artifacts without execution and derives chunk edges, route and endpoint candidates, vendor fingerprints, static WebMCP declarations, and optionally source-map/original-source evidence.
- `observe_web_session` / `rea observe-web-session` arms an observation window of the requested duration for an external user action and records ordered reload, SPA navigation, redirect, failure, lifecycle, and target-termination metadata.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete structural input-schema summary inline. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. REA never exposes `WebMCP.invokeTool`; malformed protocol payloads fail explicitly instead of returning incomplete tool metadata.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete observed `input_schema` declaration and canonical `input_schema_sha256` digest inline. Declarations are untrusted JSON data, including declared types, required fields, enums, examples and reference URLs. REA does not resolve schema references. These fields replace `input_schema_shape`. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. REA never exposes `WebMCP.invokeTool`; malformed protocol payloads fail explicitly instead of returning incomplete tool metadata.
- `compare_web_captures` / `rea compare-web-captures` compares passive captures or exact-step-aligned browser scenarios. Scenario results commit reproducible literal normalization and expose alignment failures plus artifact-level action, screenshot, DOM, accessibility, URL, history, storage, and event differences. Missing or truncated evidence is never treated as equivalence.
- `capture_web_screenshot` / `rea capture-web-screenshot` returns a content-addressed visible-viewport PNG.
- `compare_web_screenshots` / `rea compare-web-screenshots` performs bounded local PNG pixel comparison without OCR or external services.
- The CLI comparison commands accept each capture, screenshot artifact or normalization policy as inline JSON or a JSON file path. Use files for screenshot artifacts and scenario captures, whose embedded PNG bytes can exceed the host's command-line length limit.
- Every surface has equivalent CLI and MCP contracts and returns Evidence provenance.
- MCP tools return complete results inline and include the Evidence ID. Session evidence can be exported with `export_evidence_bundle`.
@@ -134,7 +135,7 @@ REA retains local observation data and removes only URL userinfo credentials, ex
- DOM snapshots retain node types, node names, value lengths, and attribute names, but not text or attribute values.
- Accessibility structure and roles are retained by default, while names and descriptions require `include_accessibility_text: true`.
- Network observations retain method, status, MIME type, size, type, initiator stack location, and complete URLs with userinfo credentials removed. Redirects reported by CDP are attached as ordered `redirects` on the one request ID, with the prior request URL, CDP response URL, method/type, response status/MIME/encoded length, request timestamp, and the next `requestWillBeSent` event timestamp. CDP delivers `redirectResponse` with that next request event, so the latter is an event boundary rather than an exact response timestamp. Redirect response headers and bodies are discarded; hops outside the selected origins are discarded with the request chain. Headers are discarded after an allowlisted projection of length/encoding, structured CSP/Link/policy fields, and untrusted agent hints. Cookies and authorization headers are never retained.
- Request/response bodies are not requested or parsed by default. When selected, only allowed-origin JSON media types are read, converted immediately to complete value-free property paths/types, and discarded. `Network.getResponseBody` is never sent unless JSON body shape capture is selected.
- Request/response bodies are not requested or parsed by default. When selected, only allowed-origin JSON media types are read, converted immediately to complete value-free typed paths, types and observation counts, and discarded. Each path segment is either `{ "kind": "property", "name": "raw property name" }` or `{ "kind": "array-element" }`; array-element types include primitives and nested arrays. Literal `*` properties remain distinct from array elements. `Network.getResponseBody` is never sent unless JSON body shape capture is selected. Comparison uses body shapes only when both captures selected them, and compares request/response shapes only where both observations provide those facts. Unavailable or truncated selected coverage makes equivalence unknown; observed differences still report changed.
- Console observations with a stack source retain call type, argument types, timestamp, and source location. When console text capture is selected, already-delivered primitive values are retained verbatim; objects, getters, and remote properties are never expanded.
- WebSocket observations retain direction, opcode, and payload byte length. When shape capture is selected, text frames are classified as text or complete value-free JSON shape; binary bytes, hashes, prefixes, and raw frames are never retained.
- Storage observations always redact values. Key names, IndexedDB names, and cache names require `include_storage_keys`; stable content fingerprints require the additional `include_storage_fingerprints` selection. Cookie fingerprints cover cookies applicable to the current main-frame URL, including its path, rather than every cookie path on that origin. Other storage remains scoped to the origin. Cache bodies above 64 KiB and partial IndexedDB remote objects make fingerprint coverage incomplete, so identical observations remain `unknown`.
+5 -4
View File
@@ -236,12 +236,13 @@ network metadata observation; listing `network` in `events` is then optional.
Each observed request object receives a capture-scoped `transaction_id`.
Requests sharing a URL remain distinct. Redirects link to the preceding
transaction only when it was observed; a null predecessor does not establish
that no earlier hop existed. Older captures without IDs remain readable and
their transaction association is unknown.
that no earlier hop existed. Request events require both transaction fields;
an absent ID is malformed capture data, while a null redirect predecessor is
an explicit unknown.
`scenario.network_content` records the resolved content selection. Comparing
captures with different selection, or legacy captures without that coverage
information, reports network evidence as unknown with a recovery instruction.
captures with different selections reports network evidence as unknown with a
recovery instruction.
Capturing more data alone does not establish a website change.
`network-content` events reference the exact request or response event through
-477
View File
@@ -1,477 +0,0 @@
# Incremental capability migration
This working guide tracks the migration in #740. Update it as concrete domains
migrate. Existing public contracts and domain-specific ports remain authoritative;
there is no new universal provider interface or fixed module manifest.
## Ownership to preserve
| Responsibility | Current owner | Migration direction |
| --------------------------------------------- | ----------------------------------- | ----------------------------------------------------- |
| Analyst semantics and Evidence representation | domain | Keep pure and provider-neutral |
| Named public input/output contracts | contracts | Keep exact CLI/MCP meaning and complete discovery |
| Producer parsing and external tool protocols | provider adapters | Keep behind the relevant typed port |
| Shared analyst workflows | application | Share between CLI and MCP |
| Concrete provider construction | composition, MCP startup | Keep fresh typed factories at the production boundary |
| Investigation Evidence and Unknowns | InvestigationRecords/EvidenceLedger | Consume narrow read/write/atomic record ports |
| Target/profile snapshots and invalidation | BinarySessionRecords/BinarySession | Keep binary-owned |
| Subprocess ownership and host primitives | process/windows | Reuse; preserve cancellation and cleanup |
| Public translation | CLI/MCP adapters | Delegate to shared workflows and named contracts |
Retain exact Evidence IDs, provenance, detached reads, atomic Evidence/Unknown
mutations and optimistic revisions. Preserve current close and failed-cleanup
record clearing while extracting ownership; #721 owns any retention-policy change.
Each CLI invocation and MCP connection keeps its own state. Provider registration
must not launch engines or install prerequisites.
## Migrate before generalizing
1. Record the actual callers, state, environment, protocol and verification owner
of the capability being migrated.
2. Move concrete construction behind its existing typed port. Preserve injected
ports, selected environment, queues, failure state and cleanup behavior.
3. Test both caller paths and the applicable package/real-provider boundary.
4. Use independently migrated capabilities to identify repeated metadata and
composition needs. Derive a small source declaration only when those needs
are established; keep unlike target/lifecycle semantics separate.
5. Move a coherent capability's files, fixtures and verification lanes in a
mechanical PR. Update all path-sensitive consumers in that same PR.
Pure helpers do not need an interface each. A capture-format adapter or typed
factory may be sufficient. Avoid generic JSON execution, external MCP catalog
passthrough, eager provider acquisition, new permission fields or a multi-package
rewrite. Optional loading should preserve successful peers and report the failed
capability without hiding tools from the catalog.
## Checks before and after a move
`npm run verify:test-discovery` compares actual Vitest file discovery with every
repository-owned `*.test.ts` under src and tests, including newly added files. The
check requires Git, includes untracked non-ignored tests, and excludes removed
paths during a move. It
rejects missing files and overlapping project ownership. It only lists files;
it does not replace behavior tests or real-provider verification.
Check imports, project isolation and coverage, development-test selection,
lint exceptions, catalog/generator imports, npm and CI verification entrypoints,
fixture ownership, and installed-package bridge/native path resolution.
Domain and contracts must not import application workflows, caller adapters or
provider implementations. Production composition is a deliberate outer boundary.
Other existing adapter imports will migrate incrementally; do not widen a lint
exception to conceal new protocol code inside application workflows.
`npm run verify:module-boundaries` parses repository-owned source imports,
reexports, type imports and literal dynamic imports, then checks their resolved
source layer. Nested names such as `domain/android` are domain code; `src/android`
is the provider adapter. The check runs with lint, including cached static gates.
It covers tracked and untracked non-ignored TypeScript source and skips cached
paths removed during a move. Pass exact source paths for a focused check.
Pure source and its tests keep inward dependencies. Application/server provider
construction guards cover the migrated deep, Android, firmware, JavaScript recovery and observation
implementations. Application workflows cannot import composition, including the
former binary runtime entrypoint; shared browser capture/export helpers remain admitted while their
ownership is reviewed. Test lane restrictions still use Oxlint. Producer-dependent
browser and managed comparison tests live in boundary lanes with their original
fixtures and assertions. This is a development guard, not runtime authorization.
Select verification by the claim changed: schema/composition, package, real
engine or host-native workflow. Record host/target prerequisites and source-owned
fixtures. Run heavy lanes serially with bounded workers/heaps and reuse existing
engines. Recording ports do not prove real provider or platform support.
## Extension examples to validate during migration
An implementation of an existing port should require a provider adapter, typed
production factory selection, exact producer parsing/provenance and matching
verification. Existing workflow meaning and public contracts should stay stable.
A new analyst capability deliberately adds semantics, named contracts, a typed
port/workflow when needed, both caller adapters, availability, documentation and
verification. Its integration is broader than swapping a provider. The migration
should eliminate incidental duplicate wiring, not erase those design decisions.
Update these examples with real migrated entrypoints before closing #740.
## First production factory migration
`src/composition/android.ts` and `src/composition/firmware.ts` construct providers
behind the existing AndroidAnalysisPort and FirmwareAnalysisPort. CLI registrars
pass their selected environment; MCP uses the process environment unless a caller
injects a port. Each factory call returns a fresh instance and acquires no process,
workspace or toolchain. Queues, cleanup-failure state and per-request cleanup stay
inside the provider. The existing launcher seams remain available to boundary
fixtures, which now exercise the production factories.
Application workflows and MCP registration must not import these concrete
providers. Composition may import their implementations. Binary composition also
uses this outer boundary after its direct-analysis callers were migrated.
This concrete pilot does not introduce a shared provider interface or module
manifest.
## Independent optional observation adapters
Browser observation, browser scenarios, Electron observation, Electron scenarios
and V8 Inspector observation now have separate factories in `src/composition/`.
CLI commands reuse them; MCP startup dynamically imports each factory independently.
`OptionalObservationProviders` describes these five existing typed ports only. It
is provisional startup wiring, not an extensible plugin manifest or a universal
provider interface.
A failed import or constructor retains the successful peers. The complete tool
catalog remains advertised. Session availability reports the failed adapter and
its actual reason, and affected handlers return the existing capability-unavailable
error. Explicit loading failures take precedence over configured availability.
Passive Electron and active Electron failures are independent; static JavaScript
analysis and runtime reconciliation remain usable without either adapter. CLI
Electron commands also load only their selected runtime factory at execution.
Source identities are available without importing the optional implementations.
Registration acquires no engines, probes no endpoints, changes no permissions and
installs nothing. Core transport failures and shutdown still use their existing
lifecycle. Fault-injection coverage uses the production loading/startup path and
actual MCP SDK calls; recording ports establish composition behavior, while the
real Inspector lane separately establishes runtime behavior.
## Investigation record ownership pilot
`src/application/investigation/InvestigationRecords.ts` owns one existing
EvidenceLedger per runtime. The production session composition constructs that
owner explicitly; the direct BinarySession constructor retains a fresh default
for compatibility. There is no second ledger, global store, persistence or new
retention policy.
The ledger, Unknown Evidence helper and the ledger's two original behavior tests
now live beside the owner in `src/application/investigation/`. Bundle validation
and record-owner consumers follow the new paths; retained-reference access still
uses the narrow record ports. The move preserves implementation bodies and test
assertions. Binary snapshot/cache files remain with their existing owner.
EvidenceReader, EvidenceWriter and EvidenceUnknownWriter describe existing
read/write/atomic callback needs. UnknownRegistryPort preserves optimistic
revisions and consistency verification. Non-binary MCP registrars use these
record types without depending on the binary execution/lifecycle surface.
BinarySessionPort retains its compatible record methods through composition.
BinarySessionRecords remains the snapshot owner and compatibility facade. It
passes the actual active target explicitly for recordUnknown/updateUnknown;
recordEvidenceWithUnknown keeps its target-free mutation subject. Snapshot import
merges records without notifying midway, then emits after the cache commits.
Bundle import retains the full change delta so Unknown-only changes notify even
when recordsAdded is zero. Clearing resets records, cache and invalidation before
notification; observer failures remain best effort after a committed mutation.
Close and failed-cleanup clearing, ordinary target-switch retention, detached
reads, Evidence identities and deterministic bundle transfer keep their existing
behavior. Snapshots still require an active target and concrete analysis profile;
extracting investigation ownership does not make them a target-free record store.
#721 remains responsible for any future lifetime-policy change.
## Inspector adapter ownership
`src/inspector/` owns V8 Inspector discovery, passive capture, script/target
location interpretation and its lightweight provider identity. The composition
factory and optional loader use this owner. Browser CDP connection, endpoint/value
and Electron file-location helpers remain deliberate shared adapter utilities at
their existing paths; no provider wire protocol moves into domain or process.
Loopback fixtures and producer boundaries now live under
`tests/fixtures/inspector/` and `tests/boundary/inspector/`. The socket-backed
unresolved-target reconciliation test moves from composition into the forked
boundary lane with its original assertions. Adapter tests retain fork isolation.
`npm run verify:inspector` keeps its public development entrypoint and delegates
to `scripts/verify/inspector/runtime-observation.mjs`, using the real Node fixture
under `tests/conformance/inspector/`. Catalog imports, source guards and test
discovery follow the new paths. Observation authority, lifecycle, producer
interpretation and caller-visible contracts stay unchanged.
## Auxiliary source declaration pilot
Artifact, macOS native and managed static metadata now belongs to each adapter's
`*ProviderMetadata.ts` module. The implementation and
`src/composition/auxiliaryAnalysisProviders.ts` reuse the same identity and exact
capability descriptors. The declarations reference existing AnalysisProvider
loaders; they cover these three disjoint auxiliary implementations only. Deep
candidate selection and the five typed observation ports remain separate.
The binary runtime reads these source declarations while auxiliary construction
stays lazy. The separate managed-only entrypoint retains direct construction for
its execution-free workflow. The MCP catalog generator reads declarations without
constructing implementations, using its canonical macOS platform; actual runtime
host restrictions remain explicit.
Discovery and binary operation-kind routing now consume canonical source contracts
rather than their generated JSON artifact. No declaration imports its generated
output. Generated catalog facts and public schemas stay unchanged.
All observation registrars resolve contracts by name. An isolated compiled-process
test reverses presentation arrays and performs actual MCP SDK calls to verify
advertised schemas and handler meaning. Reordering metadata must not select a
different operation, schema, provider or deep-provider priority.
## Android layer and verification ownership
Android workflows and their existing typed port live in `src/application/android/`,
pure APK/inventory semantics in `src/domain/android/`, and the named inspection
contracts in `src/contracts/android/`. The headless JADX producer remains in
`src/android/`; `src/composition/android.ts` supplies its fresh factory to both
caller adapters. Public names, result meaning and JVM/queue/cleanup limits are
unchanged. Inventory-only application projection remains execution-free.
The real lane and signal-cleanup helper belong to `scripts/verify/android/`; its
explicit downloader and fixed manifest belong to `scripts/fixtures/android/`.
`verify:android` and `fixtures:android` keep their command names and repository-root
`_reference/apk-integration/` fixture default. Synthetic producer fixtures stay in
`tests/fixtures/android/`, with matching boundary and composition ownership. Real
JADX CLI/MCP parity requires the fixed APK and existing audited JAR; synthetic
protocol/cancellation success does not establish that engine or an unverified host.
## Deep-provider source declarations
Hopper, Ghidra and IDA declare their implemented analyst operations in their
own `*ProviderCapabilities.ts` modules. Hopper's inventory is typed against the
existing direct-operation contracts; Ghidra reuses its inventory/function adapter
operations; IDA retains its read-only operation family. Frozen operation arrays
feed the existing capability builders without importing generated catalog data.
The catalog generator reads these source declarations and joins operation names
to canonical `TOOL_CONTRACTS`. A missing contract identifies the declaring provider
and operation. Public schemas and descriptions remain owned by contracts; the
declarations describe implementation coverage. Provider adapters must not consume
the generated MCP catalog that is derived from them. The resolved module guard
checks this edge while admitting canonical source contracts, generated package
metadata and the existing application snapshot-cache consumer.
Exact provider effects and lifecycle differences remain in their adapters:
Hopper's GUI and mutation effects, Ghidra's experimental Windows authority and
mutation restrictions, and IDA's attached/headless effects and live observations.
This source increment introduces no common provider lifecycle or new interface.
## JavaScript application ownership
`src/application/javascript/` owns JavaScript/Electron artifact analysis and
graph projection, feature/version/export/source comparisons, runtime Evidence
and reconciliation, observation ports, and source recovery workflows. Pure
analysis and public schemas keep their existing domain/contract ownership;
shared artifact inventory, investigation records and execution types remain
shared. CLI, MCP and production factories import the owning workflow directly.
`src/domain/javascript/` owns static parsing and semantic IR, application and
semantic graphs, Electron facts, runtime reconciliation, recovery result
semantics, and source-to-bundle comparisons. Shared Evidence, digests, ordering,
comparison semantics and historical-source graphs stay at their existing owners.
Native handoffs link exact-subject Evidence without selecting or executing a
provider.
`src/contracts/javascript/` owns the JavaScript/Electron observation and recovery
contracts, JavaScript-specific workflow requests, and their examples. The shared
`applicationToolContracts.ts` aggregate stays at the contract root because it also
owns reconstruction and Android/Apple projection operations. Canonical tool
aggregation, named handler binding and SDK schema presentation remain unchanged.
Catalog source paths, compiled verifier/SDK fixtures and recovery CI filters
follow the domain/contract owners.
`scripts/verify/javascript/` groups application-workflow, runtime-reconciliation,
large-digest and real-recovery entrypoints. Their existing npm commands retain
their invocation semantics. Recovery fixture compilation lives beside its
unchanged sources under `scripts/fixtures/javascript-recovery/`. Its default
REA entrypoint still resolves to `scripts/rea.mjs`. Managed conformance imports
the relocated compiled workflow; owning CI source filters follow the new paths.
`src/artifacts/javascript/` owns directory/ASAR reader construction and relevant
file acquisition, including root/nested byte verification, UTF-8 diagnostics and
nested reader cleanup. Its narrow factory returns the existing `ArtifactReader`;
the application retains input admission, inventory, graph construction and its
original root-reader `finally` close. Pure file facts live in
`src/domain/javascript/javascriptArtifactFiles.ts`, and the shared immutable
inventory snapshot lives in `src/domain/artifactInventorySnapshot.ts`. Inventory
options and integrity policy remain application-owned. Shared stream hashing
lives in `src/artifacts/ArtifactHash.ts`, preserving complete byte counts and the
bounded classification prefix. Acquisition/hash guards reject imports from
application, composition or caller adapters; JavaScript workflows use the factory
instead of importing concrete ASAR/directory reader classes.
ZIP, native-DMG and Mach-O inventory reader selection keep their existing
lifecycles. Runtime ports retain their distinct Inspector, passive Electron and
active Electron effects; shipped Electron hooks remain at their existing
provider boundary.
## Managed capability ownership
`src/domain/managed/` owns managed artifact and member semantics, reconstruction
import, native-boundary verification and application graph projection.
`src/application/managed/` owns their shared Evidence workflows, and
`src/contracts/managed/` owns their named contracts and examples. Producer
metadata/IL parsing stays in `src/dotnet/`; target resolution, Evidence, ordering
and investigation records retain their shared owners. Path-based member
comparison preserves its actual target/byte-digest admission and existing parser
helper.
`scripts/verify/managed/` groups the portable conformance entrypoint and its
support, manifest, oracle and completion-report helpers. Its PE byte fixture
builder and declaration live in `scripts/fixtures/managed/`, shared with the
installed-package lane and existing managed conformance tests. `verify:managed`
keeps its command name and optional caller-cwd manifest resolution. Compiled
catalog and generator imports follow the owners; document-check cache inputs
include the relocated runtime verifier and fixture files.
Portable byte fixtures, optional operator-local manifests, actual ILSpy oracles
and real Ghidra NativeAOT checks retain their distinct proof levels and
prerequisites. The existing NativeAOT fixture/engine lane keeps its owner. This
move preserves implementations, Evidence identities and generated commitments.
## Binary application ownership
`src/application/binary/` owns the active session, deep-provider registry and
evaluation, operation routing, disjoint provider composition, lazy auxiliary
clients, cancellation and client cleanup. Its records facade and snapshot
cache/files remain bound to the exact target and analysis profile. Investigation
records still have their separate owner in `src/application/investigation/`.
`AnalysisProvider.ts` stays shared because its identity/execution types also serve
nonbinary ports. `BinaryTargetResolver.ts` stays shared because Android, firmware,
managed and artifact workflows use its target parsing. Production wiring lives
in `src/composition/binary.ts`; application workflows gain no outward composition
dependency.
The three colocated application tests move with their owner. Composition cases
remain in `tests/composition/analysis-sessions/`; filesystem and SDK cases retain
their boundary lanes. The shared `tests/fixtures/binarySession.ts` factory supports
several capability families. Existing recursive application globs discover the
moved tests; bridge assets and real-verifier entrypoints remain at their owners.
## Firmware layer and verification ownership
Firmware workflows and their existing typed port live in
`src/application/firmware/`, pure request/result semantics in
`src/domain/firmware/`, and named contracts in `src/contracts/firmware/`.
`src/firmware/` keeps producer commands, report parsing, source copies, publication
and cleanup; `src/composition/firmware.ts` supplies a fresh typed factory.
The real lane belongs to `scripts/verify/firmware/analysis.mjs`; the fixture runner
and its unchanged Python producer belong together in `scripts/fixtures/firmware/`.
The npm command names and selected `REA_FIRMWARE_FIXTURE_ROOT` are unchanged. The
runner retains its working-directory-relative default; the verifier retains its
repository-root default. Both point to `_reference/firmware-integration/generated`
when invoked through the documented npm commands. Optional ext4/Ghidra lanes keep
their own prerequisites. Source-fixture generation and synthetic producer tests
do not establish real Binwalk/Unblob analysis or another host's execution support.
## Apple artifact capability ownership
`src/domain/apple/` owns Apple application anatomy/projection, asset catalog
facts, Interface Builder graphs, keyed archive semantics and plist values.
`src/application/apple/AppleApplicationService.ts` retains the shared workflow
that projects authenticated IPA/macOS inventory Evidence.
`src/artifacts/apple/` owns the actual producer boundary: directory acquisition,
assetutil invocation, plist/NIB decoding, encoded view-parent interpretation and
keyed archive inspection. These helpers are used by ArtifactProvider, retain
its existing typed analysis boundary, injected assetutil seam and original reader
cleanup, and do not require a new port for each helper. Producer code no longer
lives in the application layer. Guards reject application/composition/caller
imports from this owner while admitting pure facts and shared artifact readers.
Adapter-source tests retain their assertions in the existing forked adapter lane.
`scripts/verify/apple/` groups archive, asset catalog, Interface Builder,
Objective-C/Swift dispatch and macOS bundle verification. The macOS bundle fixture
builder lives in `scripts/fixtures/apple/`; NIB byte fixtures stay beside their
artifact decoder. Existing format-specific conformance sources and goldens keep
their locations, and relocated verifiers resolve them against their own file
URLs. Public npm entrypoints and CLI/MCP contracts stay stable; generated-document
cache inputs include the relocated runtime scripts and fixture builder.
Portable decoder and injected producer tests establish their format/boundary
claims. Actual Swift/Xcode, assetutil, native NIB, bundle signing and DMG lifecycle
claims require the real Apple lane. Native binary API/value-flow semantics and
shared cross-domain contract aggregates keep their separate owners.
## Artifact inventory and extraction ownership
`src/artifacts/inventory/` owns format classification, reader selection, inventory
policy, canonical scanning and artifact graph construction. The shared artifact
provider and JavaScript reconstruction workflow consume this owner. Snapshot
semantics remain in `src/domain/artifactInventorySnapshot.ts`.
`src/artifacts/extraction/` owns member selection, integrity checks and transactional
materialization through the existing readers and safe output tree. Reader cleanup,
cancellation, rollback, archive containment and caller-visible results retain their
existing behavior. Acquisition guards reject imports from these producer owners
into application workflows, production composition or CLI/MCP adapters.
`src/application/artifacts/ArtifactExtractionDestination.ts` owns the caller's
default temporary output-root choice for both CLI and MCP. The adapters pass this
destination to the existing provider operation; format handling and member writes
remain in the artifact owner.
Add format-specific acquisition behavior beside the inventory readers and exercise
its actual producer representation in filesystem boundary tests. Add caller
workflow behavior in the application owner and verify both adapters. The installed
package lane checks inventory identity and extraction through CLI and MCP; the
real Apple bundle lane separately establishes DMG mount and detach behavior.
## Binary production composition closure
`src/composition/binary.ts` is the shared production owner for deep candidate
construction, lazy auxiliary composition and the managed-only session factory.
It preserves the existing constructor bodies, selection policy and fresh session
per invocation. Factory registration acquires no engine or target.
`DirectAnalysis` and `DirectAnalysisStatus` receive these two existing factories
through `DirectAnalysisDependencies`. They retain configuration parsing, selected
status environment, cancellation, snapshot replay/binding, Evidence projection
and finally-close. The dependency uses the existing BinarySession type, including
its replay policy; it adds no universal backend or lifecycle contract.
`src/composition/directAnalysis.ts` binds the production factories for CLI and
one-shot managed MCP callers. Binding creates no session and stores no retained
analysis state. MCP startup constructs its connection session through the same
binary factory. Source and compiled fixtures use these entrypoints. The former
application runtime path is removed, and the source guard no longer admits its
outward provider/composition imports.
## Native analyst capability ownership
`src/domain/native/` owns portable native inspection, instruction/data types,
load-image facts, API boundaries, annotations, metadata recovery, UI observation
semantics and value/investigation graphs. `src/application/native/` owns shared
API projection, call routes, dispatch inspection and UI/value tracing. Its tests
keep the existing service lane. `src/contracts/native/` owns the named native
adapter contracts; shared official/enhanced aggregates remain at their owners.
Producer interpretation, external commands and host UI lifecycle remain in
`src/native/`, Hopper, Ghidra and IDA. The shared function dossier still lives in
`domain/hopperValues.ts`: its historical name does not make its meaning exclusive
to Hopper. This move retains existing typed ports, exact result schemas,
observed/derived/unknown distinctions, profiles and Evidence links.
Source and compiled verifier imports follow the new owners. Host UI and real
native-value verifier locations are retained until their own proof lanes migrate;
interactive macOS UI success and real dependency tracing require their respective
host/engine workflows. Portable source fixtures and injected call-route tests
establish their narrower boundaries, without expanding provider/platform support.
## Process capture and analyst workflow ownership
`src/domain/process/` owns scenario/capture validation, portable process trees,
trace specifications, observations, comparisons and the canonical process Evidence
identity. The standalone contract example lives in `src/contracts/process/`;
shared session contracts retain their broader investigation owner.
`src/process/capture/` owns the actual PTY boundary, terminal rendering, sampling,
selected child environment, filesystem snapshots/effects, runtime path admission,
event journal, settlement and resource cleanup. It reuses `src/process/` ownership
primitives and the Windows host substrate. Its identity import follows the
existing pure declaration directly. A source guard rejects outward application,
composition and caller imports; no new provider or lifecycle interface is added.
`src/application/process/` retains Evidence projection and file-backed CLI
capture/comparison workflows. Capture helper tests use the forked adapter lane;
Evidence/host integration tests use the serial process-boundary lane. Their
fixtures and assertions remain unchanged. Installed capability-probe URLs follow
the new compiled adapter path, including the optional-dependency failure probe.
Windows PTY capture retains its existing unavailable outcome because descendant
cleanup is not yet verified. Native Job Objects and a PTY binary do not establish
that capture workflow. Real POSIX capture/cleanup and installed terminal/PTY module
resolution require their actual host and package lanes; portable comparison
fixtures establish their separate evidence semantics.
+32 -2
View File
@@ -20,6 +20,23 @@ files when neither `--provider` nor `--snapshot` is supplied. See
[JavaScript artifact reconstruction](javascript-artifact-reconstruction.md)
for results, integrity checks and coverage.
The complete application Evidence can be hundreds of megabytes for a real
application. When an agent or a person reads the result, save it to a file and
project a summary, a module page or one module from the saved Evidence:
```bash
rea analyze-javascript-application /absolute/path/to/app --json > app-evidence.json
jq -c '{source: {kind: "inline", evidence: .}, view: {kind: "summary"}}' app-evidence.json > app-view.json
rea inspect-analysis-view app-view.json
```
For example, a 334 MB Obsidian application Evidence file yields a summary view
of about 10 KB. Replace the view with
`{"kind": "page", "collection": "modules", "offset": 0, "limit": 32}` for a
module page. See
[JavaScript application workflows](javascript-application-workflows.md) for
views, feature traces and comparisons that take the same saved Evidence.
## Native analysis
Configure [Hopper or Ghidra](installation.md#hopper), or the
@@ -80,7 +97,7 @@ or close. Provider failures are returned with their original reason. For an
`ambiguous` selection error, choose from `details.candidate_ids`; for
`provider_unavailable`, run `rea doctor --provider ID --json` to diagnose the
selected engine. See [task readiness](installation.md#check-readiness-for-your-task)
and [provider selection](adr/0001-provider-selection-and-analysis-profiles.md).
and [provider selection](mcp-contracts.md#identity-and-discovery).
The session reports work still in progress through `analysis_activity`.
A client timeout can end its wait while the provider continues analyzing.
@@ -96,6 +113,12 @@ an exact result when the target bytes, operation, parameters, provider and
settings match. Mutations and cursor-dependent calls are excluded from the
cache. Snapshot files are local and use owner-only permissions.
Snapshots retain eligible target-scoped question histories in full, including
mutation Evidence recorded while another target was active. Observations and
related questions must still belong to the saved target. If those dependencies
cannot be retained, the entire history is excluded instead of reverting the
question to an earlier revision or disposition.
```bash
rea analyze /absolute/path/to/program --provider ghidra --snapshot /absolute/path/to/analysis/program.json
# Repeat the same query to reuse its saved result.
@@ -147,6 +170,10 @@ from observations of the current app. File names do not automatically exclude
files. Set `REA_REFERENCE_SECRET_PATTERNS_JSON` to a JSON array of ignore
patterns when you want to exclude selected paths.
JavaScript and TypeScript import parsing requires valid UTF-8. Malformed source
bytes retain their original hashes and sizes with a decoding diagnostic; REA
does not infer module targets from replacement characters.
Historical-source import requires safe no-follow file opens on Linux or
macOS. Native Windows returns `unsupported_host`; use Linux REA inside WSL
or another supported host. See
@@ -169,7 +196,10 @@ user permissions; consult the chosen guide for host requirements and effects.
## Output and exit status
The default terminal format is TOON. Use `--json` when saving results for a
JSON consumer. Output selection and formatting do not change operation status.
JSON consumer. `--json` is indented on a terminal and compact when piped or
redirected, which keeps large results smaller for agents and scripts; pipe
through `jq .` for indented files. Output selection and formatting do not change
operation status.
| Status | Meaning |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
+7 -1
View File
@@ -15,7 +15,11 @@ when both Evidence sets already exist.
The request supplies a literal-port loopback endpoint and, for inspection, a
target ID. REA accepts local hostless `file://` URLs that resolve to regular
files; remote hosts, encoded path separators, and nonexistent paths are
files, including pages a packaged application serves from inside `app.asar`.
For those, the first `.asar` path component that is a regular file is the
archive, the remainder must name a regular file in its header, and the reported
path is the canonical archive path joined with that member. Remote hosts,
encoded path separators, ASAR directories or links, and nonexistent paths are
rejected. The endpoint exposes every eligible target and its local path
metadata.
@@ -120,3 +124,5 @@ projection is intentionally target-only and partial: it binds the selected
application path and capture outcome to the static graph, while frames, scripts,
workers, and execution claims remain unavailable until a separate passive runtime
capture provides them.
ASAR observation reads the header through one open file handle, validates its declared lengths against the archive size, and limits encoded JSON headers to 16 MiB before parsing. The header cache also retains at most 16 MiB of encoded headers across eight archives. Oversized headers produce a scope refusal.
+6
View File
@@ -25,6 +25,12 @@ extraction have independent prerequisites; one does not require the other.
Both require util-linux `prlimit`, normally `/usr/bin/prlimit`; override its
absolute path with `REA_FIRMWARE_PRLIMIT_COMMAND` if needed.
REA retains at most 8 MiB of combined stdout and stderr per command. Exceeding
that diagnostic budget stops analysis with an explicit truncated-output error;
child process limits do not bound parent-side pipe retention. Completed commands
drain their output streams before recording diagnostics. Failed worker cleanup
retains the worker and workspace for retry before another request or at shutdown.
Unblob needs the external extractor for the selected format on its inherited
`PATH`: for example, `debugfs` for ext2/ext3/ext4. Its default Landlock sandbox
and skip rules stay enabled. Sandbox startup failures remain actionable errors;
+100
View File
@@ -0,0 +1,100 @@
# MIPS ELF analysis through Ghidra
This lane extends native ELF analysis; it does not execute MIPS code or rehost
firmware. It advances the generic-MIPS portion of
[#718](https://github.com/morluto/rea/issues/718), not the whole firmware roadmap.
PSP/Allegrex remains a separate specialization tracked in
[#1330](https://github.com/morluto/rea/issues/1330).
## Admission boundary
ELF `EM_MIPS` is retained as the provider-neutral `mips` family. The target also
retains class, byte order, `e_type`, raw `e_flags`, and inspected ABI declarations.
Recognition does not mean every provider or MIPS variant is supported. Existing
PE, managed and Mach-O architecture sets are unchanged.
The first Ghidra lane admits ELF32 `ET_EXEC`, little or big endian, with explicit
o32 and `EF_MIPS_ARCH_32R2` flags and no machine-specific or ASE encoding flags.
These are header declarations, not proof that every instruction conforms to
that ISA. ELF64, n32/n64, unspecified ABI, MIPS16/microMIPS, machine-specific
variants, shared/relocatable objects and PSP PRX are not covered by this lane.
Their family may be identified, but provider selection returns the specific
unsupported constraint rather than guessing a compatible profile.
Explicit `EF_MIPS_FP64` and `EF_MIPS_NAN2008` declarations are refused. Their
absence is insufficient: Clang can emit identical `e_flags` for FP32, FP64 and
soft-float targets. Target resolution also reads the 24-byte ABI flags record
identified by `PT_MIPS_ABIFLAGS` and/or `SHT_MIPS_ABIFLAGS`, without relying on
section names or the record being inside the initial 4 KiB header probe.
Program and section declarations must agree; duplicate, conflicting, truncated
or out-of-file records are rejected. Stripped section tables and section-only
records are supported. Extended table numbering is explicitly unsupported.
The field layout follows
[`Elf_MIPS_ABIFlags_v0`](https://github.com/bminor/glibc/blob/master/elf/elf.h).
Provider admission requires record version 0, MIPS32r2, 32-bit GPR/CPR1, no CPR2,
and a double-precision or FPXX ABI declaration with no ISA extension, ASE or
unknown general flags. Missing records remain unknown rather than defaulting
to a compatible ABI, and this initial lane refuses them. Unknown record values
are retained for diagnosis but do not gain provider support. These checks bind
the declared interpretation; the integer-only fixture does not establish full
floating-point behavioral conformance.
MIPS header and ABI record facts are committed in the analysis profile so
interpretation changes invalidate profile-bound snapshots. The support-lane
identity is versioned independently of file identity. Evidence, lifecycle
outputs and saved snapshots preserve the `mips` family. Hopper and IDA adapters
do not implicitly gain MIPS support. Windows Ghidra P0 remains PE x86/x86-64 only.
## Use
With a caller-installed Ghidra and compatible JDK on a supported Linux/macOS host:
```bash
rea analyze /absolute/path/to/mips.elf --provider ghidra --json
rea function /absolute/path/to/mips.elf function_name --provider ghidra --json
```
MCP uses the existing tools, including `open_binary` with an absolute path and
`provider_id: "ghidra"`. No MIPS-specific tool catalog or emulator is introduced.
Inspect instructions, caller relationships and data alongside pseudocode. In
particular, delay-slot semantics are supplied by Ghidra, not reconstructed by
REA's ELF parser.
## Verification
The source-owned freestanding fixture is `tests/conformance/c/mips.c`. The
optional cross-target lane requires a caller-supplied Clang with MIPS targets,
LLD, GNU `readelf`, Ghidra and its compatible JDK; ordinary host-native checks
do not acquire these tools. `REA_MIPS_CLANG` selects Clang and
`REA_MIPS_READELF` selects GNU readelf (for example `greadelf` on macOS).
These are test-time prerequisites, not REA runtime providers.
```bash
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:mips
```
The lane compiles both byte orders and never executes the targets. GNU readelf
independently supplies header/ABI facts and symbol addresses, compared with the
production REA target resolver before provider startup. Its version, bounded
command output and selected tool path are retained in the verification report.
The parser deliberately recognizes only this fixture's GNU output, rejecting
missing, ambiguous or unexpected fields rather than substituting defaults.
Existing public MCP operations check Ghidra's **observed** language/compiler
specification and loaded-file hashes. The source-owned `mips-probe.S` supplies
fixed ADDIU and conditional-branch encodings: verification checks bytes, length,
immediate and direct destination, independent of decompiler variable names.
Global and string bytes are checked at independently reported symbol addresses.
ELF load-image results retain observations even though REA's independent
load-image comparison currently covers DOS, not ELF; this lane checks those
observations and does not relabel the upstream result as verified.
CLI/MCP discovery and decompilation, direct calls, target/profile/Evidence
identity, snapshot round-trip and final process cleanup remain covered.
Pseudocode presence is a liveness check, not proof of semantic equivalence.
Instruction decoding and reader agreement likewise do not establish runtime,
delay-slot execution or complete floating-point semantics. Assertion regressions
reject incorrect byte order, constants, destinations and loaded identities.
Parser/profile tests are narrower checks, not substitutes for this real-provider
run. Report the actual lanes run and leave unexecuted verification pending.
+75
View File
@@ -0,0 +1,75 @@
# Ghidra provider semantics
REA imports one target into an ephemeral Ghidra database. Linux/macOS support
read-only analysis and atomic function-name/entry-comment edits; Windows P0 is
read-only. GUI controls and persistent database mutation are unavailable.
Executable bytes remain unchanged.
Use [installation](installation.md#ghidra) for supported hosts, prerequisites,
configuration, startup deadlines, resource controls, and cleanup recovery.
[Windows P0](windows-ghidra-p0.md) has its own admission and lifecycle boundary;
[NativeAOT recovery](ghidra-nativeaot.md) is an optional, separately verified
extension. Check the [release boundary](installation.md#released-package-and-main)
when using npm.
Provider selection and profile identity follow
[MCP contracts](mcp-contracts.md#identity-and-discovery). One deep
provider stays bound to the target; runtime failure never selects another
provider automatically. The contracts below describe Ghidra observations,
not equivalence with another engine's pseudocode or analysis database.
## Admitted inventory semantics
| Concern | Ghidra contract |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Program identity | One `analyzeHeadless` import produces exactly one Program; `list_documents` therefore returns exactly one name. |
| Addresses | Default memory uses lowercase `0x` hexadecimal. Non-default and external spaces use `<percent-encoded-space>:0x<hex>` and remain round-trippable. The handshake commits image base and default address-space name. |
| Symbols | `list_names` includes address-bearing memory and external symbols, including dynamic symbols, while excluding variable and no-address namespace records. Each item reports primary, dynamic, external, symbol type, and source facts. |
| Procedures | Both non-external and external functions are listed. A local thunk remains distinct from its resolved target; exact and qualified name lookup fails on ambiguity rather than guessing. |
| Strings | Only Ghidra-defined string `Data` is observed. Items report charset, byte length, and whether a required null terminator is missing. The API cannot distinguish a present terminator from fixed/Pascal layouts when no terminator is missing, so that state is named `present_or_not_required`. |
| Memory | Memory-block end addresses are exclusive. Read/write/execute, initialization, overlay, address space, and image base are direct Ghidra observations. |
| Inventory | Procedure, symbol, and string listings plus searches return the complete matching collection in one response; callers do not provide offsets or result-count limits. |
| Search | Literal and Java-regex searches scan the complete immutable inventory and return all matching entries inline. Search waits for a reply or caller cancellation; there are no caller-supplied offsets or result-count limits. |
| Analysis state | The socket is exposed only after default auto-analysis completes. Established operations wait for their reply or caller cancellation; there is no fixed response-size ceiling. |
## Admitted function-analysis semantics
| Concern | Ghidra contract |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Decompiler lifetime | One persistent `DecompInterface` is opened for the imported Program and disposed during bridge shutdown. Native decompilation has no fixed per-function deadline. External functions or functions without bodies return `null`; cancellation and native failure remain distinct. |
| Serialization | A FIFO sends one Program request at a time. Caller cancellation removes queued work promptly and is passed to active socket waits. This is an adapter safety commitment, not a claim that every Ghidra API is thread-safe. |
| Function identity | Every function result carries the entry address and Ghidra FunctionManager classification for external, thunk, and resolved thunk target. These are observations, not proof that unresolved targetless calls have been recovered. |
| Assembly and pseudocode | Assembly is complete Ghidra Listing text; pseudocode is Ghidra decompiler output. Neither is original source, and cross-provider comparison never treats Hopper and Ghidra text as equal or unequal semantic facts. |
| Instruction fast path | `read_function_instructions` returns every raw Listing instruction for the requested function without invoking the decompiler or whole-program name/string inventories. |
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
| CFG | Dossiers use `BasicBlockModel` and retain only non-call successors inside the function body. CFG topology is address-normalized for comparison; provider-specific block construction remains a declared difference. |
| P-code value flow | Function dossiers include up to 3,000 high-p-code operations, at most 64 inputs per operation, and 12,000 def-use edges. Results identify memory reads/writes, branches, and calls by p-code opcode, and mark decompiler-dead operations. Large results report truncation, an omitted-operation lower bound, and known omitted-input/edge counts. The dossier is an intra-function graph; `trace_native_values` composes derived parameter/argument and return/output dependencies across resolved calls. It does not resolve memory aliasing, call side effects, runtime behavior, persistent state, or business meaning. |
| Result extent | Function instruction scans and native API boundary observations remain complete. P-code flow is the explicit bounded exception; its count fields distinguish exact retained counts from lower-bound or known-omitted counts. Caller cancellation and provider failures remain distinct. |
`npm run verify:ghidra` compiles the versioned C oracle into debug and stripped
host-native targets (x86-64/AArch64 ELF on Linux or Mach-O on macOS), plus a native
DWARF 4 type-layout object. It proves the admitted operations, external functions, resolved thunks, exports, stripped-name
behavior, direct and targetless indirect calls, typed references, strings/xrefs,
multi-block CFG, bounded p-code def-use/effect links, semantic enhanced workflows, cancellation, startup deadlines,
serialized concurrency, malformed-target rejection, profile identity, and
process/project cleanup against real Ghidra 12.1.4. Unit fixtures separately
cover startup deadlines, process exit, queued cancellation, and malformed wire
output.
`npm run verify:ghidra:cross-format` adds AArch64 ELF, x86-64 PE, and x86-64
Mach-O target coverage. It requires `clang`, LLD, and `lld-link`; set
`REA_CLANG`, `REA_LLD`, or `REA_LLD_LINK` to select them. The verifier checks
these tools before compilation. Keeping this matrix separate lets Linux
host/provider acceptance run with only the host compiler.
`npm run verify:ghidra:windows` checks source-owned native x86-64 PE applications;
`-- --x86` selects x86 and `-- --dll` selects DLLs, and the flags can be combined.
These lanes check all 25 read-only operations, target/snapshot/import SHA-256 linkage,
and project, endpoint, process, and runtime cleanup. The independent native
lane checks DACLs, handle admission, cancellation, and Job Object lifecycle.
`npm run verify:ghidra:windows:package` packs and installs REA into an isolated
prefix, then checks ordinary-user CLI/MCP operations against canonical contracts.
It accepts the same architecture and DLL flags and verifies the selected PE role
in the analysis profile.
All lanes require matching native controls; package startup alone establishes
only package compatibility.
+161 -10
View File
@@ -95,7 +95,7 @@ npx skills add morluto/rea --skill reverse-engineer-anything
This installs agent instructions and bundled references, not REA MCP
registration or analysis engines. Follow the skill's
[conditional connection guide](https://github.com/morluto/rea/blob/main/skill-src/reverse-engineer-anything/SKILL.md#connect-only-when-needed).
[conditional connection guide](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/SKILL.md#connect-only-when-needed).
Working tools can be used immediately. If tools are missing, inspect the current
client's registration with `doctor --client codex --json` (substitute its client
ID), then plan repairs with `setup --client codex --dry-run --json`. Show and
@@ -135,16 +135,138 @@ listed after the table because its connector is not one of these files:
| Antigravity | `antigravity` |
| GitHub Copilot CLI | `copilot_cli` |
| Command Code | `commandcode` |
| Qwen Code | `qwen_code` |
| VS Code | `vscode` |
| Grok Build | `grok_build` |
| OMP | `omp` |
| Pi | `pi` |
| Hermes | `hermes` |
For [Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md),
setup writes a `type: "stdio"` entry under `mcpServers.rea` in the user-level
`~/.pi/agent/mcp.json` and installs the bundled skill under `~/.agents/skills`.
Use `rea setup --client pi --dry-run --json` to inspect the plan, then
`rea setup --client pi --yes --json` to approve it. Check the registration with
`rea doctor --client pi --json`. Pi reads `mcp.json` as strict JSON, like its
own loader: comments, trailing commas, a byte-order mark, or an empty existing
file are invalid, and setup reports them instead of rewriting the file. Repair
such a file to plain JSON first, then rerun setup.
Setup follows Pi's `PI_CODING_AGENT_DIR`: unset or empty selects the default;
`~` and `~/` expand to the home directory; absolute paths and file URLs select
that directory; relative paths stay relative to the command's working directory.
On Windows, native paths, `~\`, and Git Bash/MSYS, Cygwin, and WSL drive paths
are normalized as Pi does. Run REA and Pi from the same working directory when
using a relative override. Pi has no profiles: `OMP_PROFILE`, `PI_PROFILE`,
`PI_CONFIG_DIR`, and OMP's `enabledServers`/`disabledServers` lists do not affect
Pi registration. Doctor accepts an omitted `type` for stdio but reports a
non-stdio type as invalid; `enabled: false` stays disabled.
REA configures only the user scope. Pi also reads `.pi/mcp.json` in trusted
projects; a same-name project entry can replace the user entry or override its
enabled state and exposure. Check that file if the user registration is aligned
but unavailable in a project. An extension that registers `/mcp` can replace
Pi's built-in MCP support and use its own configuration instead. Run `/reload`
in an existing Pi session after changing servers outside the session.
For Qwen Code, setup registers `rea` in the `mcpServers` table of the
user-level `~/.qwen/settings.json`, or `$QWEN_HOME/settings.json` when configured.
Setup and doctor follow Qwen Code's tilde and working-directory-relative home
overrides. Qwen Code also discovers personal skills in `~/.agents/skills`,
where setup installs the bundled workflow.
Gemini CLI uses `$GEMINI_CLI_HOME/.gemini/settings.json` when that home override
is nonempty, including its shared personal skills at
`$GEMINI_CLI_HOME/.agents/skills`. Setup and doctor check MCP allow/exclude
policies from system defaults, user settings, trusted workspace settings, and
system overrides. Workspace trust follows `GEMINI_CLI_TRUST_WORKSPACE`,
`GEMINI_RESTRICTED_MODE`, the effective `security.folderTrust.enabled` setting,
and the selected `trustedFolders.json` (including
`GEMINI_CLI_TRUSTED_FOLDERS_PATH`). Settings in an untrusted workspace do not
participate. A workspace or system `mcpServers.rea` replaces the entire user
entry; setup stops if the winning definition conflicts with its planned entry.
Review those files manually: setup never edits administrator/workspace settings
or grants workspace trust. Trust supplied only by a running IDE is outside this
standalone CLI check.
Codex treats an unset or empty `CODEX_HOME` as `~/.codex`. Devin honors
`XDG_CONFIG_HOME` for its `devin/mcp_config.json` on non-Windows systems.
For OMP, setup writes a `type: "stdio"` entry to the user-level
`~/.omp/agent/mcp.json`. It follows `PI_CONFIG_DIR` and
`PI_CODING_AGENT_DIR` (relative to the setup working directory), and the profile selected by `OMP_PROFILE` or
`PI_PROFILE` (`~/.omp/profiles/<name>/agent/mcp.json`). Setup also removes
`rea` from that file's `disabledServers` list, which would otherwise hide the
registration. Doctor treats an `enabled: false` entry as active when
`enabledServers` lists `rea`, as OMP does, unless `disabledServers` also lists
it. Run setup under each profile that should load REA.
For Hermes, setup writes a `mcp_servers.rea` entry to `config.yaml`, preserving
comments and unrelated settings. It resolves that file from `HERMES_HOME`, else
from the platform default Hermes itself uses — `%LOCALAPPDATA%\hermes` on
Windows, `~/.hermes` elsewhere — including any `HERMES_DATA_DIR_SUFFIX`. Hermes
connects an entry unless `enabled` is false, so setup states `enabled: true`.
Hermes personal skills install under the active Hermes home's `skills` directory.
Setup, doctor and uninstall follow the root's `active_profile` selection, as
plain Hermes CLI commands do. An explicit `HERMES_HOME` pointing to
`profiles/<name>` selects that named profile directly. An invalid, missing or
deleted sticky profile is reported instead of writing into the default home;
repair the profile or run `hermes profile use default` before retrying.
REA follows `HERMES_HOME` whitespace trimming, environment-variable expansion,
and home expansion before resolving that profile. Setup previews the resolved
configuration and skill destinations; doctor and uninstall use those same paths.
### DeepSeek Harness
DeepSeek Harness uses a Cordis YAML patch sequence rather than a `mcpServers`
object. REA's `setup --client` does not edit this format. For Harness
`0.2.0-rc.2`, append the following entry to `$DSH_HOME/cordis.patch.yml`
(`~/.dsh/cordis.patch.yml` when `DSH_HOME` is unset). Preserve existing patches
and replace the executable paths with absolute paths from your installation:
```yaml
- insert:
- id: rea-mcp
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: rea
transport: stdio
command: /absolute/path/to/node
args: ["/absolute/path/to/rea/scripts/rea.mjs", mcp]
cwd: !!js process.cwd()
```
For a global npm installation, the launcher is under
`$(npm root -g)/rea-agents/scripts/rea.mjs`. Check the Node executable with
`command -v node`. Register `serverName: rea` only once in each active profile,
then restart Harness. It exposes tools as `mcp__rea__<tool_name>`.
Run `rea setup --skill --dry-run`, review the destination, then
`rea setup --skill --yes` to install the workflow in `~/.agents/skills`.
Harness discovers that directory, or `$DSH_AGENTS_HOME/skills` when configured;
its native `skill` tool can load `reverse-engineer-anything`.
REA's optional [native client verification](testing.md#end-to-end-integration-and-golden-evidence)
checks headless chat, skill loading, all tool input schemas and actual analysis
using the installed Harness and a local model fixture. This establishes the
Harness integration, with live DeepSeek API compatibility remaining unverified.
See the [Harness MCP guide](https://github.com/deepseek-ai/deepseek-harness/blob/639ed015397290b3745d163aafe02ffee4aa3f84/packages/mcp/mcp-client/README.md)
for its native configuration contract.
### Other client settings
For OpenCode, setup writes the V1 `mcp.rea` entry, which OpenCode V1 and V2
both load. If the configuration already uses OpenCode V2's native
`mcp.servers` table, setup registers REA there instead and replaces any earlier
`mcp.rea` entry from REA.
`mcp.rea` entry from REA. Setup honors `OPENCODE_CONFIG_DIR` and
`OPENCODE_CONFIG`, preferring the later-loaded JSONC file when both JSON and
JSONC exist. The ordinary XDG global configuration still participates when a
custom directory is selected. Doctor checks the merged user registration; uninstall removes
REA-owned entries from every applicable user file so an older entry cannot
become active again. Malformed applicable files block setup before changes.
Grok Build loads `[mcp_servers.rea]` from `$GROK_HOME/config.toml`, or from
`~/.grok/config.toml` when `GROK_HOME` is unset. Setup edits that server
`~/.grok/config.toml` when `GROK_HOME` is unset or empty. Setup edits that server
table, `[mcp_servers.rea.env]`, and a root `disabled_mcp_servers` entry that
names `rea`. It sets `startup_timeout_sec = 30` and leaves every other name
in that list. The shared skill installed under `~/.agents/skills` is already
@@ -182,6 +304,20 @@ default. Hopper is a separate optional choice: setup shows its proposed
installation or connection and requires its own explicit approval. It can also
save verified paths for an existing Ghidra installation.
The bundled skill is installed where each selected client discovers personal
skills: Claude Code uses `~/.claude/skills` (or
`$CLAUDE_CONFIG_DIR/skills` when configured). Gemini CLI uses `.agents/skills`
under its selected home; Antigravity 2.0 uses `~/.gemini/config/skills`.
Other integrations, including Qwen Code, use `~/.agents/skills`.
A mixed selection plans each distinct destination. Selecting the skill without a client uses the shared
directory. Setup leaves existing skill copies in other locations untouched.
`doctor --skill --json` verifies the selected copies against the bundled
instructions and references. Consumers should use `identity.skill.state`,
`installed_version`, and `installed_tool_count` for skill readiness. The
obsolete `installed_catalog_digest` field has been removed; current catalog
identity remains available at `identity.catalog`.
After selection, review the plan's exact paths and changes and approve before
REA writes files or installs Hopper. You can cancel at any prompt.
@@ -189,7 +325,7 @@ Before applying changes, REA checks your current configuration. The plan lists:
- an existing Hopper installation, a verified existing Ghidra installation, or the official Hopper package it proposes to install;
- each detected agent configuration path;
- the REA skill destination;
- each selected REA skill destination;
- external software, network origins, integrity evidence, and package-manager
commands.
@@ -280,7 +416,7 @@ vendor-defined limits, and a paid license is optional. REA reuses any detected
installation and preserves Hopper during uninstall.
The supported native host baseline is macOS 12+, Ubuntu 24.04+, Fedora 41+,
64-bit Arch Linux, or CachyOS. Ghidra and IDA have their own provider-specific
Nobara 44+, 64-bit Arch Linux, or CachyOS. Ghidra and IDA have their own provider-specific
host requirements; Windows Ghidra uses the [experimental P0 boundary](windows-ghidra-p0.md).
On macOS, approved setup downloads the official DMG, checks its published size
@@ -406,6 +542,17 @@ Closing or switching a target closes its bound Hopper document, shuts down REA's
bridge and removes its temporary socket directory while preserving the Hopper
application and unrelated documents. A `cleanup_incomplete`
result identifies resources whose cleanup could not be verified.
REA retains unresolved cleanup ownership and any confirmed shutdown phases.
After addressing the reported failure, retry `close_binary` on the same
connection. Unconfirmed document or process cleanup retains the target/application
lease and prevents another client from launching against that owned resource.
Once document and process closure are confirmed, the lease can be released even
if temporary-file cleanup fails. Another client can then launch, but the owning
client must finish its retained cleanup before starting again.
An unconfirmed external document can be retried while its authenticated bridge
remains connected. If that bridge has disconnected, another close cannot confirm
the document: inspect and close the reported document in Hopper before ending
the owning REA connection.
### Hopper in CI
@@ -438,8 +585,11 @@ and JDK 21. Each installation must include the native decompiler for the host
architecture in `Ghidra/Features/Decompiler/os/<platform>/` or the corresponding
`build/os/<platform>/` directory. Linux ARM64 uses `linux_arm_64`; official
release archives may require you to build that native component separately.
REA checks the executable prerequisite and does not build or install native
tools, or change Gatekeeper quarantine settings.
REA checks the executable prerequisite by inspecting the file's own executable
header, so a native component built for another platform or architecture is
reported as incompatible instead of being admitted from its directory name, and
a header that cannot be read or recognized is reported as unknown. REA does not
build or install native tools, or change Gatekeeper quarantine settings.
The adapter exposes 25 read-only operations: thirteen inventory/name/search
operations and twelve function-analysis operations. These cover metadata,
@@ -452,7 +602,7 @@ entry comments atomically and returns refreshed analysis. These session metadata
edits leave executable bytes unchanged and are discarded on close. GUI controls
require Hopper; Windows P0 remains read-only.
Windows P0 admits native x86 and x86-64 PE applications on fixed local NTFS volumes.
Windows P0 admits native x86 and x86-64 PE applications and DLLs on fixed local NTFS volumes.
The npm package bundles native Job Object ownership, protected private runtime
DACLs, and handle-based path admission; no separate addon installation is needed.
See the [Windows Ghidra P0 guide](windows-ghidra-p0.md) for verified scope and
@@ -637,7 +787,8 @@ and other MCP servers. Purging removes only REA's cache and state under
`~/.rea`. A client configuration that is malformed, unreadable, or at an unsafe
path stops the operation before anything is removed, and a client that fails
while being updated stops the remaining removals. A purge path that is a
symbolic link is retained and reported rather than followed. See the
symbolic link is retained and reported rather than followed. Uninstall checks
REA's managed shared and Claude Code personal skill locations. See the
[CLI guide](cli.md#output-and-exit-status) for exit statuses.
## MCP Registry
@@ -659,7 +810,7 @@ For a client that requires manual configuration, use:
"mcpServers": {
"rea": {
"command": "npx",
"args": ["-y", "rea-agents@6.2.0", "mcp"]
"args": ["-y", "rea-agents@6.3.0", "mcp"]
}
}
}
+12
View File
@@ -73,6 +73,18 @@ The directed relation vocabulary is `contains`, `loads`, `imports`, `maps_to`,
and `changed_from`. Provider names are deliberately absent from both
vocabularies.
For a `maps_to` edge targeting a source-map node, the edge carries
`resolved_path` and `declared_url_sha256`. The target node's reference
observation carries that same digest and the exact `declared_url`; match the
digest to select the URL belonging to that edge when several references share
one physical source map. The full URL is kept out of node identity, display
label, and edge properties, so large inline data URLs are stored once per
source-map reference.
Consumers previously reading `edge.properties.declared_url` should follow
`target_node_id` and select the observation by `declared_url_sha256` instead.
Node labels serve display; the observation preserves the original URL.
For example, a source-owned synthetic fixture proves this path without using a
third-party application:
+74 -8
View File
@@ -23,6 +23,15 @@ artifact digest and structural graph ID. Semantic tracing requires the semantic
relation graph and reports when it is unavailable rather than treating missing
data as an empty graph.
The semantic graph wire format stores shared non-location provenance once in
its required `evidence_contexts` table. Each node, relation, fingerprint, and
unknown retains its exact `evidence.location` and names the owning context with
`evidence.context_id`. This is a breaking representation change: consumers
reading fields such as `evidence.authority` must look up the context by ID and
combine its fields with the fact's location. Semantic trace results include the
canonical context subset referenced by their returned facts, so those facts
remain self-contained in the response.
## Feature tracing
Select one literal seed kind: node ID, route, string, API, IPC channel, module,
@@ -60,13 +69,12 @@ validation boundaries, and built-in resource acquisition/release.
Mutation tracking covers explicit member assignments, updates, deletion, and
loop assignment targets, including the supported local aliases and shared
nested references. Calls such as `Object.assign`, `Reflect.set`, and
`Reflect.deleteProperty`, and writes reaching a caller's object through another
function's parameter, are not tracked by this mutation pass. These channels
can leave an initializer-derived literal in the graph even after the runtime
value changes. Treat such a result as an uncovered mutation channel, not as
proof of the current runtime value; a follow-up needs to model that channel
and verify its caller/alias behavior.
nested references. Calls conservatively invalidate exposed mutable references;
callee bodies and built-ins such as `Object.assign`, `Reflect.set`, and
`Reflect.deleteProperty` are not interpreted to establish exact post-call
values. This uncertainty does not prove that a call actually mutated a value.
Interprocedural aliasing beyond the supported call-site references remains
outside this mutation pass.
Function fingerprints commit normalized syntax, control-flow shape, relation
shape, literal sets, arity, and detected effects without using local names or
@@ -82,6 +90,44 @@ keep the result ambiguous. Runtime Evidence can later corroborate an exact
mapped candidate, but structural reachability, semantic influence, runtime
observation, and causal proof remain separate claims.
Semantic literal nodes keep their complete value in `properties.value`; literal
queries match that field. String labels use `string literal` when that is
shorter than the complete JSON value. A literal's `identity.role_key` commits
its canonical JSON value as `value-sha256:<digest>` when the digest key is
shorter; smaller values keep their existing JSON key. This keeps large values
out of identity and display metadata without expanding short values or
truncating their Evidence.
New analyses therefore produce different IDs for hashed literals from the
earlier payload-bearing role keys. Use IDs returned by the selected parent
graph and read literal values from `properties.value`, rather than decoding
role keys or labels. Previously stored graphs and their original IDs remain
valid inputs.
Endpoint nodes keep the exact endpoint in each observation's `properties.value`;
semantic request and response nodes keep it in `properties.endpoint`. Endpoint
identity keys use `value-sha256:<digest>` over the canonical JSON string when
that is shorter, or when the original value starts with the reserved digest
prefix. Other short endpoint keys remain unchanged. Endpoint labels use the
shorter of the exact value and `<kind> endpoint`; semantic request/response
labels use the shorter of the endpoint and operation method. These labels are
display metadata, not endpoint lookup values.
New analyses therefore change hashed endpoint IDs and longer endpoint labels.
Use IDs from the selected graph and read the complete endpoint properties;
previously stored graphs still support their original IDs. Literal endpoint
search, semantic tracing, and version comparison use the preserved values.
Event and listener nodes likewise preserve the complete event name in
`properties.event_name`. Event role keys use the same reserved-prefix string
digest rule, scoped to the emitter; repeated registrations, removals, and
dispatches keep one event per exact emitter/name pair. Long event labels use
`event`, and listener labels use the shorter of `<method>:<name>` and
`<method>:listener`. Dynamic names remain `null` with explicit uncertainty. New analyses
change hashed event IDs and longer event/listener labels; query the preserved
name or select IDs from the parent graph. Previously stored graphs keep their
original IDs and remain valid trace inputs.
## Version comparison
REA pairs entities only when a tier produces one unique candidate on each side.
@@ -137,6 +183,20 @@ Direct return expressions, including expression-bodied arrows, are evaluated
through an execution-free value lattice. Literal object fields and direct
return sites are represented in the result. Calls, dynamic spreads, computed
keys, and parser recovery remain partial or unknown.
Objects and arrays passed to calls, constructors, or tagged templates, used
as method receivers, or stored through property targets are not assumed
unchanged afterward. Property stores conservatively retain reference escape
uncertainty rather than pretending to execute later writes. References
handed back by local functions, methods, constructors, async functions, and
generators also retain escape uncertainty, including when the call is read-only;
this does not establish that a mutation occurred. Aliases
and shared children in spread and rest copies retain that uncertainty; copied
primitive slots and unrelated containing properties remain known. Object rest
excludes consumed keys, array rest excludes the consumed prefix for known
arrays, and later explicit data properties and methods replace earlier object
spread references. A known array prefix does not expose values from a following
spread. Accessors, custom or uncertain iteration, unknown computed keys, and
unknown spread lengths retain conservative uncertainty.
Nested callable returns are not assigned to their parent callable. Projected
graph observations carry source ranges but never source text.
@@ -162,6 +222,8 @@ value alone does not make an observed property uncertain. `summary.added` and
`summary.removed` count
presence-level add/remove as well as literal value add/remove;
`summary.unknown` does not absorb complete-coverage presence-only gaps.
A partial comparison still records an unknown in the MCP session when matching
uncertain projections produce no changes and `summary.unknown` is zero.
The output includes exact selector candidates, omissions, Evidence links,
coverage, and limitations; it does not execute JavaScript. When runtime
@@ -171,10 +233,14 @@ or process workflows.
## CLI and verification
All five CLI commands accept inline JSON or a path to a JSON file. The CLI
All six CLI commands accept inline JSON or a path to a JSON file. The CLI
returns an Evidence record directly. Put the full records in a later CLI input;
a separate CLI process has no retained MCP connection state.
File inputs must be regular files; symlinks to regular files are accepted.
Directories, named pipes and device files produce an input error before JSON
parsing.
For a literal string trace, analyze your supplied tree once, then build the
input from the saved Evidence (replace the target and seed):
+40 -4
View File
@@ -22,7 +22,7 @@ The tool reads the caller-selected local directory or ASAR path directly:
```bash
rea analyze /absolute/path/to/apps/app.asar --json
rea analyze-javascript-application /absolute/path/to/apps/app.asar \
--json
--integrity-policy record-and-continue --json
```
Generic `rea analyze` selects this static provider for directories and `.asar`
@@ -47,11 +47,14 @@ The equivalent MCP input is:
```json
{
"input_path": "/absolute/path/to/apps/app.asar",
"format": "auto"
"format": "auto",
"integrity_policy": "fail"
}
```
`input_path` must be absolute. `format` accepts `auto`, `asar`, or `directory`.
`integrity_policy` accepts `fail` or `record-and-continue`; both CLI routes and
the MCP tool default to `fail`.
The result retains the canonical local path, root artifact digest, artifact
manifest and graph commitments, JavaScript Application Graph, static
Electron summary, reconstruction statistics, and explicit limitations. It does
@@ -63,8 +66,12 @@ ASAR inventory checks Electron integrity metadata for embedded archive entries
and supplied `.asar.unpacked` companion files. An integrity failure identifies
the logical path, declared and calculated SHA-256 values, and whether the entry
was unpacked. By default, a mismatch is returned as a failure with its artifact
context. Requests that support `integrity_policy` can explicitly select
`record-and-continue` to inspect verified siblings while retaining the mismatch.
context. Application analysis can explicitly select `record-and-continue` to
analyze observed bytes while retaining each contradiction's declared and
observed hashes and `observed-untrusted` trust. Such results mark application
graph coverage partial and include every contradicted path in the limitations.
Mismatched nested ASARs stay opaque rather than being expanded. An unpacked
entry whose companion bytes were not supplied remains `unavailable`.
An unpacked entry whose companion bytes were not supplied remains
`unavailable`. REA continues analyzing embedded JavaScript and records the
@@ -105,6 +112,33 @@ Field selection remains useful when the caller needs a
smaller view, for example `--format json --filter-output
evidence_id,normalized_result.statistics`. Streaming output does not bound the
memory needed to construct the analysis graph itself.
CLI workflows parse larger JSON input files incrementally from one verified
regular-file handle, without constructing a document-sized string. Smaller
files retain native JSON parsing. Both paths require strict JSON and valid
UTF-8, and return one complete value; the assembled object still needs memory.
An individual JSON string exceeding the native length limit or the available
heap headroom for assembly returns
`resource_constraint` with `input_reason: "too-large"`. Supply a smaller valid
value; for Evidence workflows, re-analyze a smaller selection of the original
target and use its complete Evidence. Splitting JSON text or trimming Evidence
fields does not produce a valid workflow input.
Evidence bundle and analysis snapshot file readers still decode whole
documents. Their runtime string-limit failures report a resource constraint
with the selected path, observed bytes and UTF-16 limit, rather than malformed
JSON.
`analyze_javascript_application` returns the complete analysis Evidence by
default. Select `"detail": "summary"` to retain that complete Evidence in the
current session and receive only its `inspect_analysis_view` summary: artifact
identity, statistics, Electron surface counts, application and semantic
coverage, limitations, and `normalized_result.parent_evidence_id`. Pass that ID
to `inspect_analysis_view` for module pages or items, or to the application
workflows as a retained reference. The summary does not repeat or truncate the
analysis; a server without session retention refuses summary detail with
`capability_unavailable`. CLI output is unchanged and always complete.
MCP prepares the complete repeated response incrementally against the pinned
SDK's 10 MiB stdio receive-buffer budget. Oversized results return an actionable
transport constraint and the exact same-session Evidence reference. Use
@@ -283,6 +317,8 @@ such as `./web3:app.js` still names a local artifact.
Package `exports` fallback arrays are supported both at the top level and under
the root `"."` entry. The resolver selects targets in declared order using the
same conditional and invalid-entry handling as nested exports arrays.
For imports and requires, the active Node conditions include `module-sync`;
earlier active conditions retain precedence over later ones.
ESM relative module paths and selected package exports targets use URL suffix handling
and one percent-decoding pass. CommonJS relative paths and legacy package main
+34 -7
View File
@@ -7,19 +7,46 @@ never executes the selected or recovered application code.
## Caller-supplied engine
The initial adapter is verified on Linux x64 with Wakaru **1.13.0**. Set
`REA_WAKARU_COMMAND` to the absolute path of an executable supplied by the caller.
The adapter uses util-linux `prlimit` (default `/usr/bin/prlimit`; override with
an absolute `REA_JAVASCRIPT_PRLIMIT_COMMAND`). REA does not install either tool.
Engine configuration is checked only when recovery is requested; other REA
capabilities remain available without it.
REA accepts Wakaru **^1.13.0** on Linux x64. The report parser is verified with
Wakaru **1.14.0**. Another release in that range is accepted, the observed
version is reported, and a limitation records that the parser was not verified
against that release. Wakaru changes `--version`, `--json` and `provenance.json`
only by addition within a major version
([compatibility policy](https://github.com/pionxzh/wakaru/blob/v1.14.0/docs/cli.md#machine-readable-output-compatibility)),
so the parser keeps unknown report fields and reported module statuses.
Set `REA_WAKARU_COMMAND` to the absolute path of an executable supplied by the
caller. The adapter uses util-linux `prlimit` (default `/usr/bin/prlimit`;
override with an absolute `REA_JAVASCRIPT_PRLIMIT_COMMAND`). REA does not install
either tool. Engine configuration is checked only when recovery is requested;
other REA capabilities remain available without it.
Unmodified upstream source is retained in `third_party/wakaru`, pinned to
`6070266d24b32951fa2fe1d2dad5b4313bd5c81b` (v1.13.0, Apache-2.0).
`8219bf5016a063d7fb215101a8c45d5959ec733f` (v1.14.0, Apache-2.0).
The result reports the executed binary's exact path, SHA-256 and observed version.
The audited source revision is distinct from `executed_source_revision: null`:
a version string cannot prove which source produced a caller-supplied binary.
### Install Wakaru
Use the official release binary, the same one CI verifies:
```sh
curl -fL https://github.com/pionxzh/wakaru/releases/download/v1.14.0/wakaru-linux-x64.tar.gz | tar -xz wakaru
export REA_WAKARU_COMMAND="$PWD/wakaru"
```
Or install it from npm. Point at the platform binary, not the Node.js shim in
`node_modules/.bin`:
```sh
npm install wakaru@1.14.0
export REA_WAKARU_COMMAND="$(realpath node_modules/@wakaru/cli-linux-x64/wakaru)"
```
Both give the same binary (SHA-256
`664fa06782a61eda7ed15885134b52525fd565dd77607e642062ceb6cd927c38`).
## Recover and analyze
```sh
+36
View File
@@ -0,0 +1,36 @@
# JEB instrumentation and analysis
REA exposes JEB-backed project, unit, and decompilation inspection through the CLI and MCP, served by JEB's own MCP interface. JEB is a bring-your-own engine: REA never installs it, launches it, or opens its project databases itself.
## Bring-your-own engine
Start a JEB client that serves MCP and point REA at it:
- Default endpoint: `http://127.0.0.1:8425/mcp`. Override with `REA_JEB_MCP_URL` (absolute `http`/`https` URL with literal host `127.0.0.1` or `[::1]`; redirects, remote hosts, credentials, query strings, and fragments are rejected rather than silently dropped).
- In the JEB GUI client, start the MCP server from the _File_ menu (or via the VIBRE assistant).
- Headless, use JEB's documented programmatic route (`JebMcpServerInstance` from the JEB API) with the JEB client on your classpath; JEB 5.48's `-c` headless mode does not accept `--mcp` directly.
Verified against JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server` 1.3.0 over streamable HTTP.
## Operations
| MCP tool / CLI command | Purpose |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `inspect_jeb_client` / `inspect-jeb-client` | Engine version, GUI or headless mode, startup time |
| `open_jeb_project` / `open-jeb-project` | Open or create a project from an artifact or `.jdb2` on the engine host; returns input-file SHA-256 digests and top-level units |
| `list_jeb_units` / `list-jeb-units` | Page units by stable path and type (`filter`, `parent-unit-path`, `index`, `count`) |
| `decompile_jeb_item` / `decompile-jeb-item` | Decompile one type or method to engine pseudo-code |
All four are read-only with respect to the target file; only `open_jeb_project` changes engine-side project state, and Evidence records the endpoint, the caller-selected parameters, and the engine-reported digests. Mutation workflows the engine also offers (renames, comments, `save_project`, `close_project`) are intentionally not exposed yet.
**Engine coverage note (verified):** JEB 5.48.0 headless MCP instances do not advertise `open_project` — the target must be selected when the engine client starts (`--infile` on the programmatic launcher, or the GUI's file opening). REA preserves that refusal with the engine's reason instead of failing silently; `open_jeb_project` completes only against engine builds that advertise the tool, such as GUI clients.
## Semantics
- Paths in `open_jeb_project` are resolved by the JEB process, not by REA; REA does not require the artifact to exist locally.
- The engine caps `list_units` pages at 100; a full page is reported as `coverage: "partial"` because more units may exist. An empty remainder is `complete` only when fewer units than requested were returned.
- When `decompile_jeb_item` omits `unit_path`, the engine implicitly selects the project's first code unit; REA reports `unit_path: null` and a limitation instead of guessing the effective unit.
- Engine refusals (`success: false` envelopes) are preserved as unsupported-target errors carrying the engine's own message, for example a nonexistent item address.
- An unreachable endpoint is a provider-availability failure with recovery guidance; REA does not retry or spawn the engine.
Real-engine verification lives in the JEB lane described in [testing.md](testing.md); mock transport tests do not establish real-engine compatibility.
+63 -227
View File
@@ -1,4 +1,4 @@
# Managed-code analysis and planned extensions
# Managed-code analysis
REA inspects .NET PE/CLI artifacts without loading or executing their code.
It can identify an assembly, inspect metadata and CIL, compare members across
@@ -20,12 +20,11 @@ The seven shipped tools are:
Each has a matching CLI command: replace underscores with hyphens and prefix
the name with `rea`, for example `rea inspect-managed-artifact`.
Native-body bridge mapping remains planned; managed runtime execution is not
part of the current tool set.
Native-body bridge mapping and managed runtime execution are outside the
current tool set.
This guide describes the implementation and verification of
[ADR-0003](adr/0003-managed-code-evidence-and-provider-boundary.md). The canonical
tool inventory is the [build-generated catalog](mcp-contracts.md#generated-catalog).
The canonical tool inventory is the
[build-generated catalog](mcp-contracts.md#generated-catalog).
## Shipped scope
@@ -36,10 +35,22 @@ NativeAOT identity from an ordinary native PE. Inputs without admitted CLI
metadata do not become managed assemblies through naming or routing guesses.
Inspect separately obtained components explicitly and preserve their identities.
The broader deployment classification and native-body mapping below are design
goals from ADR-0003, not claims that every row has an implemented parser. A
valid marker can establish a candidate native boundary, not recovered native
semantics or runtime behavior.
A valid implementation marker establishes a candidate native boundary, not
recovered native semantics or runtime behavior.
### Resource admission
The static provider admits regular input files up to 128 MiB before retaining
their bytes. Reads remain bounded if a file grows after admission. Metadata,
CIL decoding, and projected inspection records have a separate conservative
64 MiB representation budget; shared heap strings are cached, but repeated
output occurrences still consume that budget. These are inspection resource
policies, not PE format limits or a hard bound on total V8 heap use.
Input overflow returns a resource constraint. Decode or projection overflow
reports `resource-limit` with unavailable or partial coverage; omitted facts do
not become empty observations. Ambiguous PE section mappings are rejected
rather than interpreted according to section order.
## Analysis objective
@@ -57,40 +68,7 @@ collapsing them:
The ordinary workflow ends at question four. Static analysis never loads or
executes the target.
## Planned deployment classification
The intended extended classifier proceeds from outermost authenticated bytes inward:
```text
source path
-> canonical path, size, SHA-256
-> container inventory
-> PE/native header and architecture
-> CLI header and metadata root
-> deployment/runtime markers
-> per-component and per-method implementation availability
-> managed-only, native-only, composed, degraded, or unsupported route
```
The planned result is a vector rather than one label. For example, a single-file modern
.NET deployment can contain a native host, ordinary CIL assemblies, and
ReadyToRun components. Each component receives its own digest, classification,
coverage, and route while retaining the outer bundle commitment.
| Case | Required positive observations | Claims that remain unavailable or inferred |
| --------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| .NET Framework | Valid CLI metadata plus bounded Framework-specific target/reference evidence | Exact installed CLR and runtime behavior |
| Modern .NET | Valid CLI metadata plus bounded target/reference/runtime-config evidence | Exact runtime selected on another host |
| Unity Mono | Valid managed assembly plus authenticated Unity context when supplied | Engine behavior or native integration not represented by metadata |
| ReadyToRun | Valid managed metadata plus authenticated ReadyToRun header/sections | Native implementation semantics until a selected deep provider analyzes them |
| C++/CLI | Valid CLI metadata plus mixed-mode PE/header evidence | Mapping managed declarations to native implementations without explicit bridge evidence |
| Single-file | Valid authenticated bundle inventory and component extents | Components that are compressed or encoded by an unsupported bundle version |
| Unity IL2CPP | Authenticated native image/metadata pairing and supported metadata version | Canonical CIL and source-equivalent C# |
| NativeAOT | Native image plus bounded NativeAOT evidence | Ordinary CLI metadata/CIL unless independently present |
| Obfuscated assembly | Same positive byte observations as its underlying deployment form | Meaning inferred only from names |
| Malformed/unsupported | Exact admitted regions and failure locations | Completeness, successfully skipped rows, or semantics beyond the admitted parser boundary |
### NativeAOT metadata recovery
## NativeAOT metadata recovery
NativeAOT removes the ordinary CIL method bodies, so a CIL decompiler cannot
reconstruct those bodies as C# source. The executable remains a native target
@@ -110,28 +88,21 @@ lists supported OS/architecture targets and deployment limitations, while its
[native library guide](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/libraries)
describes exported shared-library entry points.
The [Ghidra NativeAOT analyzer](https://github.com/Washi1337/ghidra-nativeaot)
is a useful optional companion for recovering ReadyToRun metadata. It
rehydrates the `DEHYDRATED_DATA` section and annotates method tables, type
relationships, vtable slots, frozen objects, and strings. It does not recover
original C# method bodies. It is a separate Ghidra extension and interactive
metadata browser; REA does not currently install or invoke it through its
headless bridge. Its README describes ReadyToRun header discovery, including
symbol-based and heuristic paths, so a missed header or unsupported binary
should remain an explicit limitation rather than a failed claim about the
binary's contents.
REA supports an optional headless adapter for the Ghidra NativeAOT analyzer.
Supply a locally built `REA_GHIDRA_NATIVEAOT_JAR`; REA does not install the
extension or its toolchain. The verified boundary is .NET 8.0.22 RTR 9.1,
x86-64 ELF and native Windows PE targets analyzed on Linux x64 with Ghidra
12.1.4 and JDK 21. Other layouts, architectures, and hosts are unsupported.
See [NativeAOT recovery](ghidra-nativeaot.md) for build/configuration, recovered
metadata, derived-memory provenance, and the real verification lane.
The upstream analyzer currently gates its own analysis to x86-64. NativeAOT's
broader platform matrix does not establish REA coverage: PE/COFF, ELF, Mach-O,
shared libraries, target architectures, and runtime metadata versions each need
their own provider verification. REA's experimental Windows Ghidra boundary is
limited to admitted native x86 and x86-64 PE applications, so it does not currently
establish coverage for PE DLLs. Mobile NativeAOT targets should remain
experimental until REA has a matching provider and package-level verification.
REA's experimental Windows Ghidra boundary admits native x86 and x86-64 PE
applications and DLLs for static analysis. This does not establish Windows
NativeAOT metadata-recovery coverage.
For REA's native analysis, preserve the same artifact path and digest used by
`inspect_managed_artifact`, and report recovered type data as provider
observations. Linking those types to native function addresses requires verified
For NativeAOT analysis, preserve the selected native artifact's path and digest
and report recovered type data as provider observations. Linking those types
to native function addresses requires verified
provider evidence; names or vtable similarity alone do not prove that a native
function implements a specific managed method.
@@ -143,43 +114,18 @@ matches the normalized artifact SHA-256. A valid Evidence ID alone does not
establish that those two identities agree. Evidence without a subject remains
usable, with no subject digest available to cross-check.
Every planned operation returns a provider result and Evidence with four
commitment groups:
Artifact inspection returns the selected path, byte length and SHA-256, observed
PE/CLI classification, assembly and module identities, and metadata coverage.
Member inspection binds build-local tokens, signatures, row offsets, method
bodies, and decoded relationships to that artifact and MVID. Missing or malformed
facts remain explicit in coverage and per-member status.
### Artifact commitment
CLI `#GUID` heap values retain their exact 16-byte GUID text. REA does not impose
RFC 4122 UUID version or variant bits on MVID, EncId, or EncBaseId because
ECMA-335 metadata does not require those bit patterns. Tokens and RVAs are
build-local coordinates, not durable cross-build identities or native addresses.
- canonical local path, byte length, and SHA-256;
- outer-container identity and digest when inspecting a component;
- component name/path, byte extent, and SHA-256;
- observed PE machine, CLI flags, and conflicts;
- classification vector, supporting observations, and unresolved dimensions.
### Module commitment
- assembly simple name, version, culture, public-key/token state, flags, and
hash algorithm;
- module name, generation, and MVID;
- target framework and runtime/version strings with their exact metadata
locations;
- provider identity, analysis-affecting parameters, and their profile digest.
CLI `#GUID` heap values are committed as their exact 16-byte GUID text. REA
does not impose RFC 4122 UUID version or variant bits on MVID, EncId, or
EncBaseId because ECMA-335 metadata does not require those bit patterns.
### Entity commitment
- table kind and build-local token;
- declaring scope and normalized CLI signature;
- row/heap/body locations expressed as typed file offsets, RVAs, or CIL
offsets;
- exact raw bytes or bounded value digest;
- raw CIL digest plus separately reported method-header, locals-token, and
exception-region observations where available;
- a deterministic decoded-instruction-tuple digest for completely decoded
CIL, with the limitations below.
### Shipped decoded-CIL fingerprint
## Decoded-CIL fingerprint
`inspect_managed_members` exposes two method CIL hashes with different byte
boundaries:
@@ -208,9 +154,7 @@ reproducible decoded-tuple fingerprint, not a canonical semantic CIL identity:
it does not resolve tokens across MVIDs, does not commit full control flow or
exception semantics, and does not replace the raw CIL digest. Cross-build
comparison uses the value only as one unique-only structural tier and reports
ambiguity when that evidence is insufficient. A future normalized-CIL
commitment would need canonical token/literal identities,
complete branch and switch targets, and explicit locals/exception semantics.
ambiguity when that evidence is insufficient.
For example, a decoded `nop; ret` body serializes exactly as
`[["nop","none",null],["ret","none",null]]` and has digest
@@ -218,73 +162,10 @@ For example, a decoded `nop; ret` body serializes exactly as
This vector specifies the tuple order, `null` handling, absence of whitespace,
UTF-8 encoding, and lowercase hexadecimal output.
### Epistemic commitment
## Member comparison
- authority: static bytes, reconstruction, structural inference, independent
validation, native provider, or future runtime observation;
- state: observed, inferred, unknown, or unavailable;
- confidence independent of authority;
- coverage and admitted/dropped counts;
- exact supporting Evidence IDs and actionable limitations.
A semantic label such as `score_submission_gate` can annotate an entity, but it
is never the entity's identity. The same applies to an obfuscated name, token,
RVA, or decompiler-generated local name.
## Planned static capabilities
The caller-visible grouping and exact tool names are decided with the contracts
that implement them. The underlying capability slices are:
1. **Triage and inventory**: container/component classification, assembly and
module identity, references, files, exported types, resources, attributes,
and runtime markers.
2. **Member inventory**: file-backed types, methods, fields, properties, events,
interfaces, nesting, generics, and normalized signatures.
3. **Method inspection**: headers, max stack, locals, CIL instructions,
constants, metadata operands, exception regions, and implementation flags.
4. **Relationships**: declared overrides, interface implementations, member
references, direct CIL callers/callees, field access, construction, and
interop declarations. Dynamic dispatch remains qualified.
5. **Structural search and comparison**: signature/API/constant/flow anchors,
exact and normalized hashes, competing candidates, and explicit
exact/structural/missing/ambiguous states.
6. **Managed/native composition**: P/Invoke, unmanaged exports, COM/mixed-mode
declarations, ReadyToRun/native bodies, single-file hosts, and authenticated
IL2CPP pairs linked to selected Hopper/Ghidra evidence. The shipped
verification workflow checks P/Invoke declarations against supplied native
export or function Evidence; native-body, thunk, and token-to-address bridge
mapping remain unavailable without explicit provider-supported evidence.
7. **Application graph projection**: managed assembly/module/type/method/field,
P/Invoke, and native-implementation declarations enter the same
Evidence-backed application graph vocabulary as JavaScript/Electron
findings while preserving managed static-analysis authority.
Inventory lists preserve deterministic order and include every fact available
from the admitted PE/CLI streams. Malformed ranges and unsupported metadata are
reported as coverage issues instead of being silently omitted. Search exposes
scanned, matched, returned, and dropped counts. An unresolved indirect call or
a failed signature decode is not silently omitted from a completeness claim.
## Obfuscation-resistant method slices
Names are one weak feature among many. A behavior slice records the smallest
bounded set of observations needed to investigate a proposition:
- normalized declaring/member signatures and inheritance/interface shape;
- framework and application API references;
- exact strings, numeric constants, enum-like values, and serialization keys;
- branch, switch, exception, loop, call, and field-flow shape;
- construction and generic-instantiation sites;
- raw CIL and decoded-tuple commitments, plus separate header, locals, and
exception observations;
- callers, callees, shared fields, and competing candidates; and
- limitations from reflection, dynamic dispatch, generated code, protection,
native transitions, or incomplete coverage.
The workflow produces separate observation, inference, validation, and unknown
tables. It may say that a method is a strong candidate for a role; it cannot
turn that role into the method's durable identity.
Names and semantic labels do not establish durable member identity. Comparison
preserves observed differences, structural inferences, and unknowns separately.
Cross-version matching first prefers exact CIL/signature identity. When that
does not match, it pairs an exact declared type, method name, and raw signature
@@ -310,16 +191,14 @@ Tokens are always remapped through observed structure. A caller cannot carry
## Managed/native boundary rules
| Boundary | Managed observation | Native observation | Permitted link |
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| P/Invoke | Module, entry point, charset/calling-convention flags, declaring method | Import/export/symbol/function evidence from the selected deep provider | Exact declared-name/module link or qualified resolution inference |
| COM | Interop attributes, GUIDs, imported interfaces, method signatures | Native registration/vtable evidence when independently available | Identifier/signature inference with explicit environment limitations |
| C++/CLI | Managed declaration and implementation flags | Native body/function evidence | Only a provider-supported bridge observation; never token-as-address |
| ReadyToRun | Component/header and per-method CIL/native availability | Native section/function evidence | Authenticated image mapping with format/profile version |
| Unmanaged export | Export metadata/attribute when present | PE export and native thunk/function | Exact export identity plus provider-qualified address |
| Single-file host | Bundle entry/component identity | Host and native component evidence | Outer bundle plus component digest/extent commitment |
| Unity IL2CPP | Supported metadata entity with authenticated pairing | Generated native function/type evidence | Versioned IL2CPP mapping only; no invented CIL |
| Runtime-resolved native | API/constant/data-flow candidate | Loaded-module/symbol observation from an independently collected runtime source | Static candidate remains inference until separately observed |
`verify_managed_native_boundaries` compares declared P/Invoke module and entry
point identities with supplied native export or function evidence. Name/module
matches establish declaration links; they do not establish that a call executed.
Metadata tokens are not native addresses. Native body mapping for C++/CLI,
ReadyToRun, NativeAOT, and IL2CPP requires separately verified format and provider
support. The managed static tools do not recover those mappings. The optional
[Ghidra NativeAOT extension](ghidra-nativeaot.md) has its own supported boundary.
Declared import inventory supports a bounded positive claim. Its absence does
not exclude dynamic resolution, generated code, protected code, native helpers,
@@ -333,16 +212,12 @@ fixtures and expected semantic facts. An optional real ILSpy lane runs only when
its executable is explicitly supplied; the default lane does not establish
independent pinned-oracle parity. Production inspection needs none of those tools.
- A pinned `System.Reflection.Metadata` differential oracle is planned; it is
not part of the current verifier.
- `ICSharpCode.Decompiler`/`ilspycmd` can supply reconstruction inference.
A BYO reconstruction import records the supplied version
and remains non-canonical. When `REA_ILSPY_CMD_PATH` points to an absolute
runnable `ilspycmd`, `verify:managed` runs a source-owned real ILSpy oracle
and imports its C# output as reconstruction inference against exact static
member Evidence.
- dnlib and Mono.Cecil are potential future differential oracles. Their mutation APIs
are not exposed or included in the production parsing boundary.
- The package contains no .NET runtime, SDK, ILSpy installation, proprietary
assembly, or compiled conformance fixture.
- Setup never installs or upgrades those tools. Doctor may inspect an explicit
@@ -360,29 +235,15 @@ they do not claim that the REA application itself supports Windows. Native
ReadyToRun, C++/CLI, NativeAOT, or IL2CPP coverage is additionally constrained
by the selected Hopper/Ghidra host and format matrix.
## Source-built conformance corpus
## Conformance verification
The current lane uses source-owned byte-built fixtures and malformed-input
regressions, with optional operator-supplied applications and ILSpy verification.
The table below describes the desired expanded corpus; it is not a report that
all compiler-generated forms have been independently verified.
Fixture sources are intentionally small and behavior-focused. Build outputs
are generated outside tracked fixture directories and must not remain after
verification or packaging.
| Corpus slice | Required properties |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| Identity | Assembly/module/version/culture/public key, references, attributes, resources, MVID |
| Signatures | Nested/generic types, arrays, pointers, by-ref, function pointers where supported, varargs |
| CIL | Short/long branches, switch, prefixes, constants, locals, calls, fields, boxing, tokens |
| Exceptions | Catch, finally, fault/filter where the compiler/toolchain supports them |
| Generated structure | Async and iterator state machines, lambdas, closures, properties, events |
| Interop | P/Invoke flags, module/name mapping, managed/unmanaged implementation metadata |
| Architecture | AnyCPU, preferred-32-bit where applicable, x86, x64 |
| Obfuscation resistance | Unicode/meaningless/duplicate-looking names and structure-preserving renames |
| Cross-build comparison | At least two builds with changed MVID/token order/layout and known same/changed behaviors |
| Malformed/adversarial | Truncated/overflowing headers, streams, tables, heaps, signatures, bodies, and EH sections |
Run the deterministic lane with `npm run verify:managed`. See
[testing](testing.md#real-toolchain-verification-lanes) for prerequisites and
coverage. Generated outputs belong outside tracked fixture directories and must
not remain after verification or packaging.
Verification compares semantic facts, not decompiler text. It checks resource
ceilings, deterministic ordering, complete cleanup, CLI/MCP parity, Evidence
@@ -492,32 +353,7 @@ evidence is collected. A direct process capture can retain declared inputs,
outputs, filesystem and protocol activity for a target run; it does not prove
which managed methods executed or how the CLR resolved them.
## Delivery sequence
The managed-code track advances as reviewable pull requests:
1. accepted evidence/provider boundary (this document and ADR);
2. read-only artifact triage and exact identity (shipped);
3. file-backed metadata, signatures, method bodies, raw CIL hashes, and the
decoded-instruction-tuple fingerprint (shipped; complete normalized-CIL
semantics remain planned);
4. obfuscation-resistant slices and cross-version comparison (shipped for
static member observations);
5. decompiler reconstruction import (shipped as analyst inference; REA does
not run ILSpy/dnSpy, and metadata/CIL remain canonical);
6. managed/native composition and truthful deployment degradation (declaration
inventory and native export/function Evidence matching shipped; native-body
bridge mapping remains planned);
7. source-built managed conformance and package/CLI verification (source-owned
PE/CLI corpus shipped through `npm run verify:managed`; optional BYO
`ilspycmd` real-tool oracle shipped through `REA_ILSPY_CMD_PATH`; dnSpy and
pinned Windows checks remain planned); and
8. managed static Evidence projection into the application graph (shipped).
Each implementation PR updates generated product facts only for behavior it
actually ships and states which real-tool checks were performed.
### Method metadata during build comparison
## Method metadata during build comparison
Managed member comparisons report a `metadata` dimension when an observed
MethodDef flags or implementation flags value differs, including accessibility
+138 -16
View File
@@ -25,12 +25,75 @@ health transition leaves that catalog unchanged and does not emit
Advertised input and output schemas contain no reachable recursive references.
Schemas share repeated definitions through schema-local references while
preserving complete fields and validation rules. Input properties retain their
descriptions and literal examples. The SDK advertises an object root for
canonical object unions and retains each branch's requirements and exclusions.
Tests validate the schemas after SDK conversion and compare advertised
validation with actual calls. Individual model APIs can impose additional
nesting limits; complete producer captures can exceed ten structural levels.
preserving complete nested fields and validation rules. Input properties retain
their descriptions and literal examples.
Hosts forward input schemas to the model with every request, so advertised
examples never copy complete producer Evidence. An embedded Evidence record is
shown as its exact `{"kind":"retained-evidence","evidence_id":"ev_..."}`
reference where the tool accepts one. An example that can only carry inline
Evidence stays in the canonical contract and its executable tests, but is not
advertised. Every advertised example is a distinct valid canonical input.
Root object unions are presented as
one object without root `anyOf`, `oneOf`, or `allOf` for model API compatibility.
The projection merges properties, retains shared required fields and
group-specific field dependencies, and describes the accepted input groups.
Canonical runtime validation enforces the exact union, including exclusions
that the advertised projection does not express. Tests validate the schemas
after SDK conversion and check advertised validation and actual calls.
Individual model APIs can impose additional nesting limits; complete producer
captures can exceed ten structural levels.
### Compact input schema profile
Some function-calling providers reject a request while any single tool's
`parameters` schema exceeds a literal serialized size cap; Moonshot clients
such as kimi-cli fail every request while the default catalog is attached
([#1484](https://github.com/morluto/rea/issues/1484)). Setting the server's
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` renders every
advertised input schema within a 13,312-byte budget, measured to sit below
Moonshot's observed cap (community measurements: a 13.7 KB schema is accepted
while a ~15 KB one is rejected). The setting is read at startup; restart the
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. The default
value `full` keeps the complete advertisement unchanged.
The compact profile renders the same tool set, output schemas, annotations,
and canonical server-side validation. It changes only the advertised input
JSON Schema:
- Annotation prose leaves the advertised form: nested property descriptions,
literal examples, defaults, and titles are dropped. The root keeps its
description because it states the accepted input groups.
- Schema-local references are inlined within the budget. Kimi Code expands
references before sending provider requests, so sharing definitions cannot
establish the provider-facing size. Expansion stops at the budget before
allocating an oversized presentation. Unconstrained JSON fields advertise
all JSON value types explicitly so Kimi cannot infer string for Evidence
objects or arrays.
- The few schemas whose validation structure alone exceeds the budget
(`compare_web_captures`, `build_reconstruction_obligation_ledger`,
`evaluate_reconstruction_coverage`, `project_managed_application_graph`,
`compare_application_versions`, `capture_browser_scenario`) are advertised
in a reduced form: property names, reference-resolved types (including union
alternatives), first-level guidance, and the root's required-field constraints,
with nested validation detail elided. The
canonical schema still rejects malformed calls server-side, so callers
following the reduced advertisement receive the canonical typed error
instead of silent acceptance.
Boundary tests pin every advertised compact schema to the budget, keep them
valid JSON Schema that still accepts every canonical example, and hold the
set of six reduced presentations as contracts evolve. Client verification
also checks provider-facing sizes and canonical examples after conversion by
the actual Kimi Code CLI; local captures do not establish Moonshot acceptance.
Self-contained output schemas advertise a content-bound `$id`, including their
declared dialect. SDK validators can reuse compiled schemas across complete
catalog refreshes and equivalent tool outputs; changing the schema changes its
identity. Explicit schema IDs and relative external reference bases are
preserved. This keeps every tool and validation rule in discovery and does not
change the SDK's catalog invalidation or availability checks.
`compare_web_captures` accepts exactly one of two input shapes:
@@ -42,10 +105,11 @@ nesting limits; complete producer captures can exceed ten structural levels.
`normalization` defaults to `{ "rules": [] }`.
The advertised schema includes complete nested capture fields and rejects
incomplete pairs, mixed comparison families, and structurally malformed
captures. Domain validation additionally checks relationships such as event
sequence references and retained counts; JSON Schema does not express those
cross-field invariants.
incomplete pairs and structurally malformed captures. Mixed comparison families
can pass advertised validation; the SDK rejects them against the canonical
input schema before invoking the handler. Domain validation additionally checks
relationships such as event sequence references and retained counts; JSON
Schema does not express those cross-field invariants.
Call `binary_session` with `{}` and read `result.tool_availability` to choose a
callable operation for the current target, provider, host, and negotiated client
@@ -89,6 +153,12 @@ if retention is unavailable or fails, the diagnostic reports that reason.
REA accepts ordinary `tools/call` progress tokens. Updates are monotonic,
rate-bounded to at most one intermediate update per 100 ms, and always allow a
terminal update. Unknown totals are omitted; REA does not fabricate percentages.
`capture_process_scenario` uses that boundary only when the client supplies a
progress token. Notifications set `progress` to the count of collected terminal
frames, process samples, and interaction events, omit `total`, and put the
lifecycle phase, elapsed time, and final cleanup status in `message`. A client
that does not send a progress token receives no progress notifications. The
tool result is unchanged either way.
Provider calls receive the request cancellation signal. Artifact traversal,
hashing, version comparisons, Hopper requests, and process capture
check the same signal. Cancellation is distinct from timeout. A cleanup failure
@@ -181,10 +251,27 @@ the current client, so it is not a fresh-start recovery. On the same connection:
This close/reopen flow was exercised on one real Linux stdio connection after a
controlled startup timeout, followed by a successful overview and function
analysis. It is not a Windows/macOS coverage claim. REA cleans only resources it
owns and never switches to another provider automatically. A provider timeout,
installation failure, or host permission denial needs its own reported recovery;
increasing a client deadline alone does not fix those failures.
analysis. A separate Windows x64 stdio run with Ghidra 12.1.4, JDK 21 and Node
22.19.0 exercised the same connection and caller-selected native PE: the default
60-second client request timed out, close succeeded, and reopening before a
240-second request completed the cold overview in about 163 seconds. The next
overview took about 19 ms. The cold and warm overviews reported two procedures
and two segments; the input digest was unchanged and no owned runtime root or
observed process-family member remained after final close. This was a small
1,024-byte fixture, so the longer request setting remains an example, not a
guarantee for larger targets. No macOS cold-start recovery was exercised.
With a supplied progress token, the Windows run received an operation-start
notification before timeout and start/completion notifications for the
successful retry. It received no intermediate import or auto-analysis progress.
These operation markers do not measure analysis work completed or extend the
client's deadline. Each new provider session still imports the target into a
fresh temporary project.
REA cleans only resources it owns and never switches to another provider
automatically. A provider timeout, installation failure, or host permission
denial needs its own reported recovery; increasing a client deadline alone does
not fix those failures.
## Tool results
@@ -193,7 +280,9 @@ Custom clients upgrading from 6.1 should follow the
Evidence-producing tools return the complete canonical Evidence record in both
text and structured content. Read `structuredContent.normalized_result` for the
operation result and `structuredContent.evidence_id` for its identity. The same
operation result and `structuredContent.evidence_id` for its identity.
`raw_result` holds a provider representation distinct from that result, such
as an upstream tool's original report, and is `null` when there is none. The same
record is retained in the session bundle. `analysis_profile` is always present:
a concrete profile object or `null`; either value participates in semantic
identity. Records omitting this field are rejected. Pass the returned Evidence
@@ -229,8 +318,23 @@ Ordinary responses keep their existing complete result contract.
## Retained application Evidence inputs
`analyze_javascript_application` and `inspect_binary_layout` accept `detail`:
`complete` (default) returns the complete analysis Evidence; `summary` records
that complete Evidence in the session and returns the derived
`inspect_analysis_view` summary Evidence instead. Its
`normalized_result.parent_evidence_id` and `evidence_links` name the retained
analysis, so later views and application workflows read it without repeating
analysis or moving the complete record through the response. A server without
session retention refuses summary detail with `capability_unavailable`.
`inspect_analysis_view` projects a caller-selected view of already completed
`inspect_binary_layout` or `analyze_javascript_application` Evidence. Source is
`inspect_binary_layout`, `analyze_javascript_application`, or `analyze_function`
Evidence. Native views select procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and high-pcode facets without starting a provider. Native offset
and limit default to 0 and 64; pseudocode uses UTF-16 code units and never
splits surrogate pairs, while other pages count rows. Unavailable facts and
provider limitations remain explicit. Source is
an exact same-session retained reference or portable inline Evidence. Views are
a summary, a layout mitigations or linkage facet, one section/symbol/module, or
a stable page with a caller-selected positive `limit`. Module pages include
@@ -339,3 +443,21 @@ Contradictory bytes are quarantined from nested expansion and recorded with
declared and observed hashes, trust, provenance, path, and unpacked state.
Verified siblings continue. Comparisons classify the result as a contradiction
and reconstruction cannot treat it as unchanged.
`analyze_javascript_application` accepts the same policy in MCP and as
`--integrity-policy` on both JavaScript CLI routes. Its result returns the
canonical `integrity_contradictions` records and marks application graph
coverage partial when any mismatch is continued. Contradicted nested ASARs
remain opaque.
`extract_artifact` accepts the same policy in MCP and as `--integrity-policy`
on `rea extract-artifact`. With `record-and-continue` it writes the observed
bytes and returns the `integrity_contradictions` records for the extracted
files. An active ASAR unpacked entry whose companion file is absent cannot be
materialized; extraction fails as `unavailable` with that logical path.
Packaging tools commonly sign or strip `.asar.unpacked` native binaries after
writing the archive header, so their declared hashes no longer match. Electron
does not check unpacked companions against those hashes at runtime. Integrity
failures for such entries name this cause and the operation to rerun with
`record-and-continue`; REA does not exempt unpacked entries silently.
+1 -1
View File
@@ -31,7 +31,7 @@ and carry their typed JSON diagnostic in a text content block; they omit
if (reply.isError === true) {
const text = reply.content.find((part) => part.type === "text");
if (text === undefined) throw new Error("REA error has no text diagnostic");
const diagnostic = JSON.parse(text.text);
const { error: diagnostic } = JSON.parse(text.text);
// Handle diagnostic.code, diagnostic.message and diagnostic.details.
}
```
+21 -3
View File
@@ -96,8 +96,18 @@ complete observation.
So an external superclass resolves from its `_OBJC_CLASS_$_` bind (for
example `NSObject`). The `pointer_fixups` coverage facet names the mechanism.
Class properties, with parsed attributes, and `__objc_catlist` categories are
also decoded. Categories record the extended class, local or external, plus
Class properties preserve each encoded attribute as a raw `{name, value}`
pair, for example `{ name: "N", value: "" }`, and report atomicity on the
property: `N` means `nonatomic`; a complete typed attribute string without
`N` means the Objective-C default `atomic`;
missing or incomplete attribute metadata leaves `atomicity` and any
unestablished read-only value null. `is_meta_class`, `is_root_class`, and
`ivar_count` are also nullable when the selected provider exposes only symbol
names. Class implementation methods have null `is_required` and `is_optional`
fields because those facts apply to protocol declarations; decoded protocol
method lists retain their observed required/optional values. Class properties
and `__objc_catlist` categories are also decoded. Categories record the
extended class, local or external, plus
their methods, protocols and properties; category methods appear as
implementations with a `category`. Swift field-offset globals that are only
initialized at runtime stay unresolved. Generic, resilient, async and
@@ -185,6 +195,14 @@ outside-memory and undecodable addresses have separate outcomes. Effective
memory base/index/displacement roles and per-instruction context mode remain
unavailable; `mode` is the program language variant.
Compact instruction references and call-target references preserve the source
address, operand index, DATA/READ/WRITE classification, primary status, provider
`provenance`, and reference `source` (for Ghidra: `analysis`, `default`, `imported`
or `user_defined`). Primary status reports the provider's chosen reference; it
does not establish literal addressing. Analyzer-inferred indexed targets remain
static references, not observed runtime reads or writes. Older evidence may omit
the additive fields, and null or omitted facts mean unavailable rather than false.
Ghidra distinguishes a return using decoded instruction p-code's `RETURN`
operation. `flow.classification_evidence` preserves the Listing flow type and
the observed return evidence; mnemonic spelling alone is not the classifier.
@@ -369,7 +387,7 @@ the tool fails with a `debugger-attach-denied` reason.
Install a Ghidra 12.1.x release and the 64-bit full JDK it declares, then configure REA to
use them. Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64; each installation requires
the matching native decompiler. Experimental Windows x64 P0 admits native
x86-64 PE applications on local NTFS using bundled Job Object ownership,
x86 and x86-64 PE applications and DLLs on local NTFS using bundled Job Object ownership,
protected runtime DACLs, and handle-based path admission. See [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
On Linux and macOS, `annotate_native_function` atomically edits a function name
+101 -7
View File
@@ -51,6 +51,34 @@ format is TOON. The file contains the complete capture Evidence record.
Choose an output file distinct from the scenario input: shell redirection opens
and truncates the output before REA reads the scenario.
While the capture runs, REA writes live status to stderr as one JSON object per
line. Stdout stays the final Evidence document:
```json
{
"rea_progress": {
"phase": "running",
"completed": 3,
"total": null,
"message": "elapsed_ms=1200 frames=1 samples=2 interactions=0",
"sequence": 4
}
}
```
`phase` is the observed lifecycle stage: `prepare`, `running`, `settling`, or
`cleanup`. `completed` counts collected terminal frames, process samples, and
interaction events. `total` stays null; REA does not invent a unit total or a
percentage. `message` reports elapsed time and those counts. The final line uses
`phase` `cleanup`, sets `terminal` to true, and adds `disposition` (`exited`,
`timeout`, `idle_timeout`, `cancelled`, or `failed`) plus the owned-process,
renderer, and temporary-root cleanup states. Updates use the shared progress
boundary and are limited to one intermediate line per 100 ms; the terminal line
is always emitted. If a receiver is slow, intermediate observations are merged
into the latest status, and stale live observations are discarded before final
cleanup status. Progress never copies child output. Child output remains in the
capture Evidence on stdout.
For example:
```json
@@ -110,6 +138,23 @@ while comparisons and trace assertions use the normalized text. Retaining the
original adds at most `limits.output_bytes` of text, because it comes from the
same admitted PTY chunks rather than a second unbounded stream.
Rendered frame `lines` hold the visible rows after normalization, with trailing
U+0020 spaces removed. Blank rows and internal spaces remain. `columns` records
terminal cell width; normalization and Unicode can make string lengths differ
from that width. `serialized_state` holds terminal serialization after the
selected normalization. Original admitted PTY chunks are available through
`raw_data ?? data`, as described above. Captures commit this line format in their
comparison contract, so a capture whose lines were padded to full width does not
compare as the same contract.
Custom `normalization.patterns` replace literal text with the caller's literal
replacement, including dollar sequences such as `$&` and `$$`. An empty pattern
also matches the first and last string positions. Captures with custom patterns
commit `pattern_normalization_version: "literal-replacements-v1"`. Legacy captures
remain readable. Cross-version comparison is rejected; capture both sides with
the same replacement semantics. Captures without custom patterns keep their
existing comparison contract.
Port normalization recognizes explicit `port`, `tcp_port`, `udp_port`, and
`listen` fields, URL authorities, IP endpoints, and `localhost` endpoints, with
ports from 0 through 65535. A port may end a sentence, as in `port: 8080.`;
@@ -130,7 +175,7 @@ run the same owned-process cleanup path. Settlement reports whether the
sampled process group quiesced or whether cleanup was needed or unverifiable;
sampling cannot prove that every short-lived or detached descendant was seen.
New captures include `truncation_details`, with separate accounting for:
Every capture requires `truncation_details`, with separate accounting for:
- `raw_terminal`: original UTF-8 PTY chunk bytes and observed/retained chunk
counts. A chunk that does not fit `limits.output_bytes` is omitted whole;
@@ -142,22 +187,32 @@ New captures include `truncation_details`, with separate accounting for:
input, so raw omissions also limit rendered coverage.
- `filesystem_before` and `filesystem_after`: file-count/depth limits,
enumeration failures, whole-file hash budget and bytes successfully hashed.
Directory names are read incrementally within the remaining entry capacity.
When a directory exceeds that capacity, the retained subset follows filesystem
enumeration order and is then sorted; it is explicitly incomplete and cannot
establish that an omitted path is absent.
Each retained regular file without a digest has an aliased path, size,
remaining budget and reason: `file_bytes_budget` or
`file_changed_or_short_read`. A file too large for the remaining budget is
remaining budget and reason: `file_bytes_budget`,
`file_changed_or_short_read`, or `file_unavailable`. Its `system_code` is
null unless an OS file operation failed, in which case it preserves the
reported error code. A file too large for the remaining budget is
skipped; a later smaller file can still be hashed. Hash omissions do not
imply incomplete path enumeration.
- `process`: sampling limit and whether sampling ended partially. Coverage
remains `sampled`, including when that limit was not exhausted.
The legacy `truncated` flag summarizes these observations. Comparisons retain
The aggregate `truncated` flag summarizes these observations. Comparisons retain
results for unaffected dimensions and mark affected dimensions unknown; an
incomplete capture cannot locate the first divergence across all dimensions.
Trace assertions use coverage for the sources they select, so an assertion
about complete raw terminal output need not fail because rendered snapshots
were omitted. Older truncated captures without these details retain the
conservative comparison behavior. These diagnostics use the existing scenario
budgets; they do not introduce a separate file-hashing budget.
were omitted. Captures missing `truncation_details` are rejected on import;
preserve them as historical files and recapture for current comparisons.
`limits.file_bytes` is already the cumulative whole-file hashing budget,
independent of `limits.output_bytes`, which bounds retained terminal content.
Each filesystem checkpoint starts with a fresh `file_bytes` budget across all
selected roots; it is not a per-file allowance. File contents are read in
64 KiB chunks for hashing and are not embedded in capture Evidence.
When the host withholds an unrelated process’s ownership token, REA leaves that
process untouched and records its PID and reason in `cleanup.unverified_processes`
@@ -173,6 +228,45 @@ as well. A newly started unreadable process can prevent verified cleanup even
after the selected command exits. REA preserves this uncertainty and leaves
that process untouched.
## Hash a report independently of terminal output
Select the producer's report directory and give `file_bytes` enough room for
the complete files you need, including other files in those roots. For example,
save this scenario and run `rea capture-process ./scenario.json --json > capture.json`:
```json
{
"executable": "node",
"arguments": [
"-e",
"const fs=require('node:fs');fs.mkdirSync('reports',{recursive:true});fs.writeFileSync('reports/final.json',JSON.stringify({status:'complete',data:'X'.repeat(131072)}));console.log('x'.repeat(8192));"
],
"working_directory": ".",
"filesystem_observation_paths": ["./reports"],
"limits": { "output_bytes": 1024, "file_bytes": 262144 }
}
```
The report exceeds the terminal budget but fits the independent 256 KiB hash
budget. Its complete SHA-256 appears in `normalized_result.files_after` at
`root_0:final.json`; check `truncation_details.filesystem_after` for omissions
and actual bytes hashed. The verbose terminal output is truncated without
preventing the report digest. The same scenario object is the MCP
`capture_process_scenario` input. REA never returns a prefix hash as a full-file
digest: an insufficient remaining budget produces a null digest and an
explicit omission reason.
A digest binds the complete bytes observed at that checkpoint, not the
producer's notion of a finished report. A stable periodic or running report
can also have a complete digest. Choose the final file and verify the
producer's documented completion marker, exit outcome and settlement
observations before calling it final. `after_settlement` names a filesystem
checkpoint, not a guarantee that an application finished successfully or
that an unobserved writer will never change the file. REA checks opened-file
identity/state around hashing and reports observed changes or unavailable
files; cancellation stops the hash. If an external sealer produces a manifest,
keep its completion claims and digest separate from REA's checkpoint facts.
## Compare two captures
Compare saved capture Evidence with:
-219
View File
@@ -1,219 +0,0 @@
# Static-analysis provider evaluation
This guide describes repository main. Check the [released package boundary](installation.md#released-package-and-main) when using npm.
Ghidra read-only analysis is available on Linux x64/arm64 and macOS x64/arm64.
Install a Ghidra 12.1.x release and the 64-bit full JDK that release declares,
then configure REA to use them. Current 12.1 releases require JDK 21 or newer
and set no maximum. The bridge is verified with Ghidra 12.1.4 and JDK 21.
Each installation needs the matching native decompiler.
REA imports one target into a temporary project and exposes 25 read-only
operations after analysis completes. They cover inventories, search,
decompilation, assembly, function metadata, resolved calls, references, control
flow, instructions, and recovered types. Results identify the provider version,
analysis settings, target digest, and any unavailable or incomplete facts.
On Linux and macOS, `annotate_native_function` additionally edits names and entry
comments atomically, verifies readback, and returns refreshed function analysis.
Changes live only in the session database and leave executable bytes unchanged.
Ghidra does not expose GUI controls; Windows P0 remains read-only.
Windows x64 P0 supports native x86 and x86-64 PE applications on local NTFS with
bundled Job Object ownership, protected runtime DACLs, and handle-based path
admission. Real ordinary-user verification covers all 25 read-only operations
through the packaged CLI and MCP, target integrity, and cleanup. This remains
an experimental boundary; see [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
[ADR-0001](adr/0001-provider-selection-and-analysis-profiles.md) fixes the
provider registry, deterministic selection, target binding, analysis profile,
snapshot migration, and compatibility semantics that implementation must
follow.
## Approved Ghidra v1 boundary
- Keep the existing provider-neutral CLI and MCP tool names.
- Bind one deep-analysis provider to a target for the target's lifetime; never
fail over silently between Hopper and Ghidra.
- Use an existing Ghidra installation and a compatible Java runtime. Setup must
not install or upgrade Ghidra or Java.
- Run Ghidra headlessly in an owned process with a private temporary project,
startup and cleanup deadlines, caller cancellation, and complete replies.
- Prefer a packaged Java bridge loaded through Ghidra's script path. PyGhidra
remains useful for prototypes but is not a mandatory production dependency.
- Treat authenticated `ping` and `shutdown` as lifecycle proof only. Inventory,
xref, CFG, and decompilation claims require separately admitted operation
contracts and real-provider conformance.
- Implement read-only inventories, assembly, decompilation, function metadata,
calls, references, containment, and complete inventory search first.
- Report GUI cursor/navigation and persistent mutation operations as unavailable
until their semantics and project ownership are explicitly designed.
- Verify real claims on Linux with at least two distinct source-owned binaries.
Verify the Windows host claim with the deterministic source-owned x86 and x86-64 PE
fixtures and all admitted operations; compare normalized semantic facts rather
than provider-specific pseudocode text.
## Shipped foundation boundary
`GHIDRA_INSTALL_DIR` must identify an extracted Ghidra 12.1.x release. Optional
`JAVA_HOME` must identify a 64-bit full JDK inside that installation's
`application.java.min` and `application.java.max` (JDK 21 or newer, with no
maximum, when the release leaves those at the 12.1 defaults). Otherwise doctor
probes `java`/`javac` or `java.exe`/`javac.exe` from `PATH`. Supported Linux and macOS
hosts accept compatible ELF, PE, and Mach-O executable targets. Host admission
and target compatibility are separate checks. Windows x64 P0 admits only native,
non-managed, non-DLL x86 and x86-64 PE applications on fixed local NTFS, with the packaged
native authority available before launch.
The launcher creates one ephemeral runtime root with project,
home/cache/config/data/temp, logs, descriptor, endpoint, target snapshot, and
ownership manifest.
It passes `-readOnly` and `-deleteProject`, and uses Ghidra's default analysis
and resource settings; inherited Java option injection variables are cleared.
On Linux, the mode-0600 descriptor carries the random token without
exposing it in argv or environment and the Java bridge binds a mode-restricted
Unix socket. macOS uses the same local transport. The bridge reports actual
Ghidra/language/compiler/analysis/import-digest metadata and accepts only
authenticated `ping`, `shutdown`, thirteen read-only inventory/load-image methods,
and twelve function-analysis methods. Linux/macOS also admits atomic function
annotation changes in the ephemeral database. Close, cancellation, timeout, malformed protocol,
or process exit stops the owned process resources, closes the socket, and
removes the runtime root.
The experimental Windows transport uses authenticated IPv4 loopback with a
token-free endpoint record. The bundled native authority establishes Job Object
ownership, protected runtime DACLs, and handle-based path admission before
launch. If the bundle or an admission constraint is unavailable, the provider
remains unavailable; a `taskkill` fallback does not establish that authority.
The provider catalog lists 25 read-only Ghidra operations and the Linux/macOS
session annotation operation. GUI cursor/navigation and persistent mutations
remain unavailable; Windows P0 admits no database mutation. The router therefore
reports them unavailable instead of borrowing Hopper semantics or inferring
capability from a successful import.
## Admitted inventory semantics
| Concern | Ghidra contract |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Program identity | One `analyzeHeadless` import produces exactly one Program; `list_documents` therefore returns exactly one name. |
| Addresses | Default memory uses lowercase `0x` hexadecimal. Non-default and external spaces use `<percent-encoded-space>:0x<hex>` and remain round-trippable. The handshake commits image base and default address-space name. |
| Symbols | `list_names` includes address-bearing memory and external symbols, including dynamic symbols, while excluding variable and no-address namespace records. Each item reports primary, dynamic, external, symbol type, and source facts. |
| Procedures | Both non-external and external functions are listed. A local thunk remains distinct from its resolved target; exact and qualified name lookup fails on ambiguity rather than guessing. |
| Strings | Only Ghidra-defined string `Data` is observed. Items report charset, byte length, and whether a required null terminator is missing. The API cannot distinguish a present terminator from fixed/Pascal layouts when no terminator is missing, so that state is named `present_or_not_required`. |
| Memory | Memory-block end addresses are exclusive. Read/write/execute, initialization, overlay, address space, and image base are direct Ghidra observations. |
| Inventory | Procedure, symbol, and string listings plus searches return the complete matching collection in one response; callers do not provide offsets or result-count limits. |
| Search | Literal and Java-regex searches scan the complete immutable inventory and return all matching entries inline. Search waits for a reply or caller cancellation; there are no caller-supplied offsets or result-count limits. |
| Analysis state | The socket is exposed only after default auto-analysis completes. Established operations wait for their reply or caller cancellation; there is no fixed response-size ceiling. |
## Admitted function-analysis semantics
| Concern | Ghidra contract |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Decompiler lifetime | One persistent `DecompInterface` is opened for the imported Program and disposed during bridge shutdown. Native decompilation has no fixed per-function deadline. External functions or functions without bodies return `null`; cancellation and native failure remain distinct. |
| Serialization | A FIFO sends one Program request at a time. Caller cancellation removes queued work promptly and is passed to active socket waits. This is an adapter safety commitment, not a claim that every Ghidra API is thread-safe. |
| Function identity | Every function result carries the entry address and Ghidra FunctionManager classification for external, thunk, and resolved thunk target. These are observations, not proof that unresolved targetless calls have been recovered. |
| Assembly and pseudocode | Assembly is complete Ghidra Listing text; pseudocode is Ghidra decompiler output. Neither is original source, and cross-provider comparison never treats Hopper and Ghidra text as equal or unequal semantic facts. |
| Instruction fast path | `read_function_instructions` returns every raw Listing instruction for the requested function without invoking the decompiler or whole-program name/string inventories. |
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
| CFG | Dossiers use `BasicBlockModel` and retain only non-call successors inside the function body. CFG topology is address-normalized for comparison; provider-specific block construction remains a declared difference. |
| P-code value flow | Function dossiers include up to 3,000 high-p-code operations, at most 64 inputs per operation, and 12,000 def-use edges. Results identify memory reads/writes, branches, and calls by p-code opcode, and mark decompiler-dead operations. Large results report truncation, an omitted-operation lower bound, and known omitted-input/edge counts. The dossier is an intra-function graph; `trace_native_values` composes derived parameter/argument and return/output dependencies across resolved calls. It does not resolve memory aliasing, call side effects, runtime behavior, persistent state, or business meaning. |
| Result extent | Function instruction scans and native API boundary observations remain complete. P-code flow is the explicit bounded exception; its count fields distinguish exact retained counts from lower-bound or known-omitted counts. Caller cancellation and provider failures remain distinct. |
`npm run verify:ghidra` compiles the versioned C oracle into debug and stripped
host-native targets (x86-64/AArch64 ELF on Linux or Mach-O on macOS), plus a native
DWARF 4 type-layout object. It proves the admitted operations, external functions, resolved thunks, exports, stripped-name
behavior, direct and targetless indirect calls, typed references, strings/xrefs,
multi-block CFG, bounded p-code def-use/effect links, semantic enhanced workflows, cancellation, startup deadlines,
serialized concurrency, malformed-target rejection, profile identity, and
process/project cleanup against real Ghidra 12.1.4. Unit fixtures separately
cover startup deadlines, process exit, queued cancellation, and malformed wire
output.
`npm run verify:ghidra:cross-format` adds AArch64 ELF, x86-64 PE, and x86-64
Mach-O target coverage. It requires `clang`, LLD, and `lld-link`; set
`REA_CLANG`, `REA_LLD`, or `REA_LLD_LINK` to select them. The verifier checks
these tools before compilation. Keeping this matrix separate lets Linux
host/provider acceptance run with only the host compiler.
`npm run verify:ghidra:windows` and its `-- --x86` variant check the source-owned native x86 and x86-64 PE
fixture, all 25 read-only operations, target/snapshot/import SHA-256 linkage,
and project, endpoint, process, and runtime cleanup. The independent native
lane checks DACLs, handle admission, cancellation, and Job Object lifecycle.
`npm run verify:ghidra:windows:package` packs and installs REA into an isolated
prefix, then checks ordinary-user CLI/MCP operations against canonical contracts.
All lanes require matching native controls; package startup alone establishes
only package compatibility.
## Shared provider-process foundation
`src/process/` now provides the mechanisms that a long-lived Hopper or Ghidra
adapter shares: POSIX run-token-authenticated process-group ownership,
ephemeral temporary runtime roots, one absolute startup deadline, correlated
request cancellation and lifecycle-deadline cleanup, bounded stdout and stderr retention with
exact byte counts, process-exit diagnostics, and bounded TERM-to-KILL shutdown.
Reusable fixtures exercise exit, timeout, cancellation, graceful termination,
forced termination, double-close, spawn failure, and resource release. Windows
Ghidra uses its native Job Object, private runtime, and path-admission boundary;
generic process-tree termination alone cannot establish provider availability.
The foundation does not define a bridge schema, socket framing, health payload,
analysis model, or shutdown acknowledgement. Hopper keeps its authenticated
NDJSON-over-Unix-socket protocol in `src/hopper/`; Ghidra has a separate strict
NDJSON protocol implemented by the packaged Java `HeadlessScript` and reuses
only the generic process mechanisms.
## Shortlist
| Provider | License / automation surface | What it brings | REA fit and blockers |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Ghidra](https://github.com/NationalSecurityAgency/ghidra) | Apache-2.0 source license; `analyzeHeadless`, Java APIs, and PyGhidra | Static analysis, multiple processors and formats, scripting, and project/database workflows | 25 read-only operations shipped on Linux/macOS with installation checks, temporary projects, a serial API queue, and real ELF/PE/Mach-O conformance. Experimental Windows x64 P0 supports native x86 and x86-64 PE on local NTFS with bundled native controls and ordinary-user CLI/MCP verification; Linux/macOS additionally support atomic session function annotations; Windows mutation and all Ghidra GUI operations are unavailable. |
| [Rizin](https://github.com/rizinorg/rizin) / [rz-pipe](https://github.com/rizinorg/rz-pipe) | Rizin repository contains LGPL-3.0 and GPL-3.0 components; `rizin`, `rz-bin`, and language bridges through `rzpipe` | Portable CLI analysis, disassembly/debugging, many architectures and file formats, JSON command output | Good candidate for a process-backed Linux provider and fast metadata fallback. License/component inventory must be preserved; command output needs version-pinned parsers and semantic conformance before evidence is trusted. |
| [LIEF](https://github.com/lief-project/LIEF) | Apache-2.0; C++, Python, and other bindings | Deterministic parsing and modification of ELF, PE, Mach-O, COFF, and related executable formats; headers, sections, symbols, relocations, and functions | Best near-term complement, not a decompiler replacement. It can cover format metadata and artifact evidence without a long-lived analysis process; function semantics, pseudocode, CFG, and cross-reference parity remain out of scope unless separately demonstrated. |
| [Binary Ninja](https://docs.binary.ninja/dev/index.html) | API/documentation components are MIT, while the analysis product is licensed by edition; commercial, Ultimate, or Headless license is required for headless automation | Python/Core/C++/Rust APIs, headless loading, IL layers, function analysis, plugins, and configurable analysis | Strong technical fit for a native provider, especially function dossiers. Commercial licensing, license-secret handling, native runtime packaging, and multithreaded lifecycle rules are material deployment blockers. |
## Recommended order
1. Use the implemented explicit provider registry and target binding without
changing Hopper behavior.
2. Maintain the admitted Ghidra function boundary through the shared
conformance corpus and add formats or semantics only after real proof.
3. Connect Electron/native-add-on application findings to the selected native
analysis provider without introducing provider-prefixed tools.
4. Evaluate LIEF or Rizin later as complementary metadata/disassembly providers,
and Binary Ninja as an optional licensed provider, using the same admission
gate.
## Required admission gate
Before implementation, an adapter proposal must provide:
- a capability matrix covering supported, unsupported, and degraded results;
- provider identity, version, analysis profile, target digest, authority,
limitations, and deterministic locations in every Evidence record;
- bounded subprocess or library lifetime, cancellation, timeouts, and cleanup;
- actionable local diagnostics that retain paths, digests, mismatch locations,
and provider metadata while redacting credentials, authorization headers,
license secrets, and other genuine secrets;
- the same source-owned fixture corpus across architectures and formats;
- repeatable checks for function identity, addresses, strings, names, xrefs,
CFG, and pseudocode wherever those capabilities are claimed.
These gates turn the accepted direction into verified capabilities rather than
prematurely claiming equivalence or redistribution support.
## Primary-source notes
- Ghidra 12.1.4 documents headless batch mode and its Java runtime requirements
in its [release-specific Getting Started guide](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/GhidraDocs/GettingStarted.md);
the [official release](https://github.com/NationalSecurityAgency/ghidra/releases/tag/Ghidra_12.1.4_build)
supplies the corresponding distribution and checksums.
- Rizin lists supported formats, architectures, tools, and `rzpipe` bridges in
its [repository README](https://github.com/rizinorg/rizin); `rz-pipe` documents
JSON command transport and pipe backends.
- LIEF's [format tutorial](https://lief.re/doc/stable/tutorials/01_play_with_formats.html)
and [Python API](https://lief.re/doc/latest/api/binary_abstraction/python.html)
document parsing and format-agnostic binary access.
- Binary Ninja documents its [headless automation model](https://docs.binary.ninja/dev/batch.html),
[edition licenses](https://docs.binary.ninja/about/license.html), and the
[MIT license for API/documentation components](https://docs.binary.ninja/about/open-source.html).
+27 -117
View File
@@ -1,125 +1,35 @@
# REA roadmap
## Tool direction
The [platform tracker](https://github.com/morluto/rea/issues/32),
[process/Hopper tracker](https://github.com/morluto/rea/issues/48), and
[browser tracker](https://github.com/morluto/rea/issues/39) track capability and
verification work. Available tools and setup are documented in the
[investigation guides](https://rea.tools/guides/),
[installation guide](installation.md), and
[generated catalog](mcp-contracts.md#generated-catalog).
REA provides inspection, capture, and comparison tools that return evidence
directly. Agents choose commands, paths, browser actions, scripts, and local
fixture servers, then compose experiments from those results. CLI and MCP must
expose equivalent behavior and preserve observations, inferences, and unknowns.
## Priorities
[#555](https://github.com/morluto/rea/pull/555) removed REA permission grants,
scope ceilings, elicitation, and repeated approval fields.
[#572](https://github.com/morluto/rea/pull/572) removed the replay engines,
Node characterization prepare/execute flow, and plan-only managed runtime
correlation tool. Those systems are retired roadmap items. Existing evidence
authority labels remain readable as provenance; they do not imply a current
replay executor.
- Expand native architecture, type, and indirect-call verification.
- Connect static findings and runtime observations across application layers.
- Improve obfuscated managed-code comparisons and verified native links.
- Extend process, protocol, filesystem, reconnect, and build-comparison coverage.
- Evaluate additional providers and targets when an analyst workflow demonstrates
a capability gap.
Local operations use the current user's OS permissions. Input and protocol
validation, provider prerequisites, target identity, cancellation, and owned
resource cleanup remain part of each tool's contract. Setup still discloses
installation changes and requires approval before writing or installing.
## Admission criteria
## Planned work
New capabilities must return useful evidence through shared CLI/MCP workflows,
preserve observations and unknowns, and declare actual authority and lifecycle
constraints. Agents compose experiments using ordinary commands, scripts, and
fixture servers; custom orchestration needs a demonstrated requirement.
The [website guides](https://rea.tools/guides/) and
[generated catalog](product-catalog.json) describe available workflows.
Current development priorities are:
Provider and platform claims require their corresponding
[real verification lanes](testing.md#real-toolchain-verification-lanes).
See [tool design](tool-design.md) for choosing a tool boundary and
[Ghidra semantics](ghidra-provider.md) for the existing deep-provider contract.
- Keep generated metadata and narrative documentation aligned with tools,
providers, setup options and releases.
- Expand native architecture, type and indirect-call verification across
Hopper and Ghidra.
- Connect additional static extractors and runtime observations to
cross-layer feature traces.
- Improve obfuscated .NET comparisons and links between managed findings
and verified native analysis.
- Extend process, protocol, filesystem, reconnect and build-comparison
coverage, plus browser and Electron scenario actions.
- Evaluate native runtime observation through LLDB, Frida, system logs and
API tracing, and additional tools and targets such as Binary Ninja, Rizin,
LIEF, Windows-native workflows, mobile applications and firmware.
Provider additions and platform support require the corresponding real
verification lanes; see [testing](testing.md) and
[provider evaluation](provider-evaluation.md).
## Remaining evidence and provider work
The [platform roadmap](https://github.com/morluto/rea/issues/32),
[process and Hopper fidelity tracker](https://github.com/morluto/rea/issues/48),
and [browser tracker](https://github.com/morluto/rea/issues/39) track remaining
capabilities and proof. Their scope follows direct tools and agent-composed
experiments; custom replay languages and grant systems are not completion gates.
[Inline Evidence composition](https://github.com/morluto/rea/pull/585) now returns
the complete record accepted by comparison tools. Managed inspection uses an
explicit PE/CLI target independently of the native provider selection. Comparisons
preserve unknowns when observation is incomplete, and PTY diagnostics retain the
actual loader or startup failure. Browser cleanup reports incomplete teardown
alongside the primary failure; transient documents invalidate only the affected
frame's WebMCP registrations. Real-provider and platform claims still require
their corresponding verification lanes.
## Shipped behavior
REA setup lets you select agent integration and optional Hopper installation.
It installs the bundled workflow, configures detected agents, and can save
verified paths for an existing Ghidra installation. It configures Claude Code,
Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity,
GitHub Copilot CLI, Command Code, VS Code, and Grok Build using each client's configuration format. Grok Bot is detected locally, but its connector is added from the Grok Bot chat because the signed-in account store is not a data-directory file.
Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64 with Ghidra 12.1.x and the
64-bit full JDK that installation declares. Current 12.1 releases require JDK 21
or newer and set no maximum; the bridge is verified with Ghidra 12.1.4 and JDK 21.
Each installation requires the matching native decompiler. The
adapter exposes thirteen inventory operations and twelve function-analysis
operations, for 25 read-only operations total. Linux and macOS additionally support
atomic function-name and entry-comment edits with refreshed analysis; metadata
is discarded on close and executable bytes stay unchanged. Approved setup saves verified
installation paths in agent configurations without installing or changing
Ghidra or Java.
Real-provider verification uses host-native debug and stripped fixtures plus
a native type-layout object. A separate lane covers AArch64 ELF, PE, and
Mach-O cross-target fixtures. See [testing](testing.md) for the prerequisites
and exact commands.
Experimental Windows x64 P0 now supplies bundled Job Object ownership,
protected runtime DACLs, and handle-based admission for native x86 and x86-64 PE
applications on local NTFS. Real ordinary-user CLI/MCP verification covers
all 25 read-only operations and cleanup. The [Windows P0 guide](windows-ghidra-p0.md)
describes this boundary and unverified broader coverage.
## Ghidra maintenance boundary
Extend formats or semantics only with normalized provider-neutral contracts and
real source-owned conformance. Hopper and Ghidra pseudocode or assembly text is
not expected to match; unresolved targetless flow remains unknown. Automatic
Ghidra acquisition, if ever added, remains a separately planned and approved
related-tool change; setup must never install Java.
Maintain Windows P0 with independent DACL readback, handle-based admission,
private authenticated IPC, and Job Object assignment before provider execution.
Process capture, Hopper, and broad filesystem-sensitive workflows remain
separate Windows projects; P0 does not imply their parity.
## Capability-selective setup
Setup already lets users select agent integration and Hopper installation.
Once REA supports installing additional analysis tools, it can expand these
choices to match the work a user wants to do. It may ask whether the operator wants to investigate
native binaries, websites, mobile applications, firmware, or runtime protocols,
then propose only the tools needed for the selected work.
That future installer must preserve the current safety boundary:
- detect and reuse existing tools;
- disclose every source, destination, license, command, and system effect;
- prefer user-local installation;
- install only explicitly selected toolchains;
- require tool-specific authorization for unattended system changes;
- verify each installed tool before reporting readiness.
No placeholder tool choices or speculative installer registry are implemented
until another supported toolchain makes the abstraction concrete.
Setup remains additive, reuses existing tools, and requires approval for disclosed
configuration and Hopper installation changes. Additional installer choices need
an implemented toolchain and explicit scope; setup does not install or upgrade
unrelated runtimes or dependencies.
+288 -159
View File
@@ -1,76 +1,36 @@
# Testing REA
Prefer evidence in this order: full end-to-end workflows through the public
CLI or MCP with real production providers and no mocked dependencies,
integration across production data/API boundaries, then golden regressions
from real captured inputs. Keep a focused module test only for a distinct
failure or semantic case that stronger workflows cannot reliably reproduce.
A test's path, compiled imports, or suite name does not establish its depth.
Use this guide when choosing coverage, pruning tests, or running a verification
lane. For commands, jump to [developer commands](#developer-commands); for engine
prerequisites, use [real-toolchain lanes](#real-toolchain-verification-lanes).
Delete tests that only mirror getters, serialization helpers, enum mappings,
fixture helpers, prescribed call sequences, arbitrary counts or snapshots,
or cache object identity without a caller-visible contract. Do not retain a
weaker test merely because it is fast when a stronger workflow already proves
the same claim. Keep format-specific malformed representations and actual
capacity, cleanup, permission and target-identity regressions.
Prefer representative workflows over a Cartesian matrix when rows cross the
same boundary. Retain combinations that exercise a distinct interaction, such as
filtering within a full-output envelope. Keep distinct command handlers,
producer representations, failure reasons, and lifecycle states covered.
Consolidate their shared setup without hiding the inputs or expected evidence.
Prefer real public CLI/MCP workflows, then production-boundary integration,
then goldens captured from real producers. Keep module tests for distinct
failures or semantics that stronger workflows cannot reliably reproduce.
Paths, compiled imports, and suite names do not establish test depth.
Tests are grouped into Vitest projects so ownership, allowed dependencies and
runtime cost are visible from their paths. Before pruning a distinct boundary
regression, identify the replacement scenario and its assertions; passing
success journeys do not replace malformed input, cancellation, permission or
cleanup coverage. Trivial helper checks do not need a replacement. If only
tests consume a production module, trace CLI/MCP and verifier imports,
including imports of compiled files, and remove abandoned scaffolding with its
tests when it has no runtime consumer.
Prune tests that mirror implementation details or duplicate a stronger claim.
Before deleting a distinct regression, identify the replacement scenario and
assertions. Preserve malformed formats, cancellation, cleanup, permissions,
capacity, target identity, and combinations with distinct interactions.
Trivial helper assertions need no replacement. Remove abandoned production
scaffolding only after checking runtime and verifier consumers, including
compiled imports.
When a test expects a `Result` to succeed, throw its error before asserting the
returned value. An `.ok` assertion immediately before the same throwing guard
adds no coverage and hides the typed failure. A removed parser matrix can leave
one golden malformed-input case and a real filesystem lifecycle that proves
configure, update, readback, and removal; an add-only journey does not cover the
whole lifecycle.
Use representative scenarios rather than Cartesian matrices of equivalent
cases. Share setup without hiding inputs or expected evidence. For successful
`Result` values, throw the typed error before asserting the value; a preceding
`.ok` assertion adds no coverage. Protocol fixtures must reject unmodeled
commands and preserve actual producer reply shapes.
Protocol fixtures must model the commands they support and their producer reply
shapes. Reject unmodeled commands instead of returning a generic success; an
empty result is appropriate only for a supported command with no result fields.
Report unavailable authority as a named skip. Await owned cleanup before a
verifier reports success. Native process inspectors are released at Vitest
worker teardown; fork termination does not run Node exit hooks, and per-file
teardown would retire inspectors still needed by other files.
Keep transport-only in-memory MCP sessions in the MCP boundary lane and direct
filesystem workflows in the filesystem boundary lane. Real process-tree capture
belongs in the serial process boundary lane, including captures invoked through
MCP. Report unavailable capture authority as a named skip rather than returning
from the test without assertions. Reserve acceptance paths for journeys
through the compiled public CLI or MCP runtime. Calling a compiled private
workflow or injecting a provider still establishes its narrower integration
claim, even if a directory name calls it acceptance.
Emit a verifier's final success report only after awaited cleanup. Observe final
process lineage after closing its owned resources.
Owned JavaScript semantic graphs capture and schema-parse caller input before
returning an iterator. Whole-graph hashing, batched integrity checks and sealing
run through the application cancellation driver; only full completion grants
the private immutable-graph proof. Regression coverage checks canonical IDs,
validation diagnostics, nested caller mutations across yields, cancellation
before result validation and subsequent SDK requests. Single-file parsing,
schema cloning and canonical sorting remain synchronous phases; measure them
separately when assessing cancellation latency on real applications.
The Vitest runner releases cached native process inspectors during awaited
worker teardown. Fork termination does not run Node's normal exit hooks; a
per-file teardown would instead retire shared inspectors before later files
can use them.
Measure slow files before removing capacity regressions. Optimize repeated
process startup, fixture construction, and production algorithms when they
dominate runtime. Keep at least one input beyond each formerly failing size or
depth; smaller fixtures do not establish that truncation or stack exhaustion
has been fixed. Record the toolchain, coverage mode, and cache conditions when
comparing durations.
Measure slow cases before pruning capacity coverage. Retain inputs beyond the
formerly failing size/depth and distinguish cold runs, warm builds, coverage,
and toolchain conditions when comparing timings.
## Behavioral depths
@@ -93,12 +53,6 @@ registries but do not cross production filesystem, process, socket, or browser b
Boundary tests cross one production boundary. Only acceptance tests assemble
the complete runtime or invoke the compiled product surface.
Binary session, registry, lazy-client and snapshot module cases live under
`src/application/binary/`. Their composition cases stay in
`tests/composition/analysis-sessions/`; snapshot persistence and actual SDK calls
stay in the filesystem and MCP boundary lanes. The shared injected session fixture
serves several capabilities and remains under `tests/fixtures/`.
Focused immutable builders and recording ports shared by one test family live
beside their production owner as `src/**/*.fixture.ts`. They are typechecked
with the suite and excluded from package builds; broader runtime and provider
@@ -134,6 +88,161 @@ entrypoint and include its verifier/fixture files in their cache inputs.
## End-to-end, integration and golden evidence
The optional `verify:qwen-client`, `verify:pi-client`, and `verify:hermes-client`
lanes require an installed native client. Select its executable with
`REA_VERIFY_QWEN_COMMAND`, `REA_VERIFY_PI_COMMAND`, or `REA_VERIFY_HERMES_COMMAND`.
They configure disposable profiles through the public REA CLI, preserve caller
settings and backups, and exercise real stdio MCP calls and skill loading. The
`call` mode checks complete catalog discovery and actual JavaScript Evidence;
pass `-- chat` to check plain chat with REA enabled. Qwen also reads the full
result that its client offloads, and Pi exercises default codemode execution.
Use `REA_VERIFY_RUNTIME_ROOT` to select a production-only installed REA package.
Receipts retain client versions, result digests, host coverage and owned-process
cleanup. These POSIX lanes use a deterministic loopback model, so they do not
prove live model-provider or native Windows compatibility. Qwen and Pi use
caller-configured skill directories to isolate the fixture account from the OS
home; this does not prove their default home-directory discovery.
Set `REA_VERIFY_HERMES_STICKY_PROFILE=1` to exercise native Hermes selection of
a named sticky profile with `HERMES_HOME` still pointing to its root.
`verify:gemini-client` requires an installed Gemini CLI (verified with
`@google/gemini-cli@0.63.0`); select it with `REA_VERIFY_GEMINI_COMMAND`.
The optional POSIX lane uses native `GEMINI_CLI_HOME` discovery in an isolated
Git project, checks setup plans, backups and idempotence, activates the installed
personal skill, validates all forwarded input JSON Schemas against their declared
dialect, forwards the complete REA catalog and checks full JavaScript
Evidence for a Unicode path. Use `-- chat` for ordinary chat with REA enabled,
or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed REA package.
The local fixture exercises the real Gemini API adapter, including its
`untrusted_context` tool-result envelope. Token counts are synthetic; live
Google API and native Windows compatibility remain unverified. The lane disables
the client's memory-based relaunch to preserve the caller's Node heap budget.
`verify:opencode-client` requires an installed OpenCode (verified with
`opencode-ai@1.18.35`); select it with `REA_VERIFY_OPENCODE_COMMAND`.
The optional POSIX lane configures isolated XDG roots and `OPENCODE_CONFIG_DIR`,
checks setup plans, backups, preserved JSONC comments and idempotence, activates
the installed skill, validates all forwarded input schemas and verifies complete
JavaScript Evidence for a Unicode path. JSONC is the default fixture; set
`REA_VERIFY_OPENCODE_CONFIG_FORMAT=json` for JSON. Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native core runs with external plugins disabled through `OPENCODE_PURE`;
the local OpenAI-compatible fixture has a caller-declared one-million-token
context and synthetic usage. Skills use an explicit isolated `skills.paths`
directory, so default OS-home discovery remains unverified. Live model APIs and
native Windows are also unverified.
`verify:claude-client` requires installed Claude Code (verified with
`@anthropic-ai/claude-code@2.1.296`); select it with `REA_VERIFY_CLAUDE_COMMAND`.
The optional POSIX lane uses native `CLAUDE_CONFIG_DIR` discovery, an independent
Git workspace, user settings and default built-in tools. It preserves caller
preferences and backups, checks idempotent setup, waits through the native
`WaitForMcpServers` tool when discovery is pending, and validates the complete
catalog and forwarded input schemas. Call mode loads the personal skill through
native `Skill`, checks its full body and verifies named-schema JavaScript Evidence
for a Unicode path. Use `-- chat` for ordinary chat with REA enabled, or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The local
Anthropic Messages/SSE fixture preserves native resource-hint envelopes in its
request artifacts. Usage is synthetic; live Anthropic API, native Windows and
bare-mode personal-skill activation remain unverified by this lane.
`verify:copilot-client` requires installed GitHub Copilot CLI (verified with
`@github/copilot@1.0.95`); select it with `REA_VERIFY_COPILOT_COMMAND`.
The optional POSIX lane uses native `COPILOT_HOME` discovery, an independent
Git workspace, guarded setup plans, preserved registrations, backups and
idempotence. Native `skill add` registers the isolated installed skill; call
mode loads its full body, validates all forwarded input schemas and checks
named-schema JavaScript Evidence for a Unicode path. When Copilot spills a
large MCP result, the model requests native `view` with `forceReadLargeFiles`
and validates the complete returned Evidence rather than its preview.
Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native offline BYOK adapter uses a loopback OpenAI completions/SSE fixture
and `gpt-5.4` model metadata; model inference and token usage are synthetic.
Set `REA_VERIFY_COPILOT_MODEL` to examine another model configuration. In the
verified client, `gpt-4.1` blocks the complete catalog before HTTP with
`compaction_static_context_blocked`, even when requesting a larger BYOK prompt
capacity. The effective capacity is unknown; this lane does not establish a
fix for that client/model limit. It preserves the complete catalog and schemas.
Live model APIs, native Windows and default OS-home skill discovery remain
unverified.
`verify:grok-client` requires installed Grok Build (verified with the official
Linux x64 1.0.50 binary); select it with `REA_VERIFY_GROK_COMMAND`. This optional
POSIX lane isolates `GROK_HOME`, an independent Git workspace and additional
skill roots, disables foreign configuration discovery, guards setup writes,
preserves unrelated registrations/backups and checks idempotence. Call mode
loads the full skill through native `read_file`, queries all REA names and input
schemas through native `search_tool`, and calls analysis through `use_tool`.
If discovery reports `partial`, the native agent diagnoses REA registration and
retries discovery. No startup-timeout override or fixed readiness delay is used.
A larger Unicode-path fixture exercises native result offloading: the full
retained Evidence is validated against its named schema, then native terminal
queries recover the selected export facts, subject and full artifact digest in
the next model request. This verifies useful artifact recovery without claiming
that every offloaded graph fact enters model context. Native line-number and
truncation envelopes remain in the request artifacts. Use `-- chat` for ordinary
chat, or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The loopback OpenAI completions/SSE custom model declares a one-million-token
context and synthetic usage. Live xAI APIs, native Windows and default OS-home
skill discovery remain unverified.
`verify:commandcode-client` requires installed Command Code (verified with npm
1.79.2); select it with `REA_VERIFY_COMMANDCODE_COMMAND`. Auth, MCP tokens and
sessions use the actual OS home, so provision a disposable POSIX account rather
than overriding `HOME`. Set `REA_VERIFY_COMMANDCODE_ACCOUNT_HOME` to that account's
actual home and create `.rea-client-verification` there with exactly
`Disposable REA client verification account` followed by a newline. The lane
owns that account's `.commandcode` configuration and shared REA skill. Build the
runtime as the checkout owner, then run `node scripts/verify-commandcode-client.mjs`
as the disposable account; the npm shortcut also needs a writable checkout.
The verifier does not create accounts or install clients. It guards setup
targets, preserves an unrelated registration and backups, checks idempotence,
and verifies native default shared-skill discovery and complete activation.
Default deferred-schema delivery stays enabled: the native prompt advertises
every REA tool, exact-name `search_tools` returns every input schema, and a native
shell query recovers the saved catalog's count and digest when the client spills
it. Actual analysis of a Unicode-path fixture delivers full named-schema Evidence
to the next model request. Use `-- chat` for ordinary chat or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The loopback
OpenAI completions/SSE model is a keyless BYOK endpoint declaring a million-token
context with synthetic usage. A synthetic account-key value satisfies the
client's print-mode gate; native local-only mode refuses hosted API calls.
Updates, telemetry and cron are disabled. Hosted authentication, live models
and Windows remain unverified.
`verify:omp-client` requires installed OMP (verified with the official Linux x64
18.8.7 binary); select it with `REA_VERIFY_OMP_COMMAND`. This optional POSIX lane
isolates the default agent, global config and XDG roots, guards setup targets,
preserves unrelated registrations and backups, and checks idempotence. It
compares native rejection of an invalid profile with REA's refusal to plan
fallback writes. OMP's default `xd://` interface mounts the complete REA catalog
as devices: call mode reads the complete installed skill and tool documentation,
then dispatches analysis through native `write`. It checks full named-schema
JavaScript Evidence with a Unicode path in the next model request. Device
metadata and documentation are distinct from forwarding all JSON schemas as
model functions. Native print-mode MCP readiness uses its defaults.
Use `-- chat` for ordinary chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only
installed package. The loopback OpenAI completions/SSE model fixture declares a
one-million-token context and synthetic usage. Live model APIs, native Windows,
named-profile native execution and default OS-home skill discovery are
unverified; skill discovery uses an explicit isolated custom directory.
`verify:deepseek-client` requires an installed DeepSeek Harness (`dsh`;
verified with `@deepseek-ai/dsh@0.2.0-rc.2`) and Git. Set
`REA_VERIFY_DEEPSEEK_COMMAND` to select its executable. This optional POSIX lane
installs the skill through `rea setup --skill`, writes the native Cordis MCP
patch into an isolated `DSH_HOME`, and uses `DSH_AGENTS_HOME` for native personal
skill discovery. A separate Git root prevents inherited project skills from
masking a missing installation. The default `call` mode checks skill loading,
complete catalog discovery, the actual forwarded input schemas and regexes,
and full JavaScript Evidence for a Unicode path. Use `-- chat` for ordinary
chat with REA enabled, or `REA_VERIFY_RUNTIME_ROOT` for an installed package.
The fixture uses Harness's custom OpenAI adapter and the one-million-token
context capacity declared by its default DeepSeek Flash model; it does not
establish live DeepSeek API or native Windows coverage. Receipts include
request artifacts, result digests and owned-process lineage.
Full E2E tests invoke the production command dispatcher and real providers,
without fake launchers, runners or responses. `verify:keyed-archive` writes an
actual Foundation binary archive, runs the CLI and a separate stdio MCP
@@ -165,29 +274,6 @@ an empty versioned scan or a suffix that only repeats the original path.
It runs in macOS CI.
Apple artifact verifiers live in `scripts/verify/apple/`, with the macOS bundle
builder under `scripts/fixtures/apple/` and NIB byte fixtures beside the decoder
in `src/artifacts/apple/`. The npm entrypoints are unchanged. Format-specific
Swift/XIB/asset sources and goldens retain their locations; real Apple workflows
resolve them from the verifier file URL and run in the macOS CI lane.
Portable native semantics and their tests live in `src/domain/native/`; shared
analyst workflows and service-lane tests live in `src/application/native/`.
Named native contracts live in `src/contracts/native/`. Provider protocol and
host UI tests retain their adapter/boundary lanes, and real verifier command
names remain unchanged.
The existing Apple CI job also runs the host Swift-demangling CLI/MCP regression
suites, including option-like symbols, carriage returns and multiline rejection.
Process semantics/tests live in `src/domain/process/`; PTY capture implementation
and forked helper tests live in `src/process/capture/`. Evidence projection and
file workflows live in `src/application/process/`; producer-backed Evidence/host
cases run in the serial `tests/boundary/process/` lane. Installed-package probes
load the compiled capture capability owner, including the missing-optional-module
case. Real capture tests preserve actual descendant and cleanup checks.
The existing Apple job also exercises the relocated filesystem snapshot identity,
cancellation and descriptor cleanup regressions on macOS.
Prepare the native inspector before cases that measure producer output or exit
behavior; keep startup deadlines and cancellation in distinct cases. Run real
process-capture verification separately from package or build checks. On macOS,
@@ -198,8 +284,7 @@ MCP SDK transport tests with recording providers remain integration tests.
They are useful for schema drift and failure projection but do not prove that
Hopper, Ghidra or another substituted engine works. `verify:package` proves
packaging/install behavior and fake-provider integration; use the corresponding
real-provider lanes for engine claims. Packed-bridge checks verify shipped files
and Python syntax without deleted mock fixtures or source-spelling assertions.
real-provider lanes for engine claims. Packed-bridge checks verify shipped files and Python syntax.
Real Apple dispatch and Interface
Builder verifiers currently prove format integration through production readers.
@@ -274,13 +359,18 @@ Do not call handcrafted utility output or synthetic binary builders real-data
goldens. Keep unsupported binary layouts and malformed boundaries as targeted
regressions until a real fixture establishes equivalent coverage.
`verify:browser` exercises source-map failure isolation and expanded-output limits through the compiled CLI and stdio MCP with real Chrome. It also submits five 2 MiB source-map annotations, checks retained script identities and explicit map omissions, and closes its owned fixture target. These public workflows replace redundant metadata-admission assertions; replacement and document-reset boundaries remain focused producer regressions.
`verify:browser` exercises source-map failure isolation and expanded-output limits through the compiled CLI and stdio MCP with real Chrome. It also submits five 2 MiB source-map annotations, checks retained script identities and explicit map omissions, and closes its owned fixture target. Replacement and document-reset behavior has separate producer-boundary coverage.
`verify:browser` also captures a source-owned noise canvas as a real PNG above
8 MiB through the CLI and stdio MCP, with complete byte/digest parity and real PNG
decoding. Its SDK client explicitly permits the larger inline JSON response;
this lane does not establish large image-comparison request transport coverage.
The scenario checks read locale, timezone, device scale and viewport dimensions
from actual page JavaScript through CLI and stdio MCP DOM captures. They also
verify that attached-page emulation is released after success, initialization
failure, action failure and cancellation while the external target stays open.
`verify:browser:network` is a focused real-browser lane for transaction identity,
selected request/response bytes, binary and compressed responses, duplicate
headers, credential and declared-secret redaction, redirects, streaming cutoff,
@@ -394,9 +484,7 @@ Instruction inspection and containing-function lookup also agree across
hexadecimal case, leading zeros, and encoded default address-space spellings.
The same source-acquisition workflow exercises missing and directory-replaced
inputs, plus real read-permission denial on a non-root host. Root runs report
that permission-denial check as unverified. A focused filesystem integration
check retains selected-platform routing and exclusive creation; two copy/digest
checks duplicated by the real workflow have been removed.
that permission-denial check as unverified. Filesystem integration separately checks selected-platform routing and exclusive creation.
Namespace annotation probes compile a separate host C fixture with C++ ABI
symbols, avoiding a C++ runtime prerequisite. Real Ghidra demangling supplies
duplicate leaf names in two top-level namespaces and a nested namespace. The
@@ -411,8 +499,7 @@ Successful-result and oversized-error delivery constraints must identify their
successfully retained Evidence records;
export must recover every source byte, complete annotation and original error
diagnostic, with CLI parity
and an unchanged executable. The focused formatter check retains only the
separate case where recording was not acknowledged.
and an unchanged executable. Formatter integration separately checks unacknowledged Evidence recording.
Long ordinary procedure names and encoded address-space selectors must produce
normal validation errors without exhausting Java's regex stack or losing the
private bridge connection. Each rejection is followed by a real provider lookup;
@@ -452,14 +539,9 @@ the CLI and stdio MCP, including special filenames, unresolved discovery
locations, and independently resolved loaded scripts. Double-quote filenames
are tested on POSIX only because Windows does not support them.
Inspector adapters live in `src/inspector/`, with loopback fixtures under
`tests/fixtures/inspector/` and forked producer boundaries under
`tests/boundary/inspector/`. The real lane is owned by
`scripts/verify/inspector/runtime-observation.mjs` and
`tests/conformance/inspector/`. Browser and Inspector deliberately share the
existing browser CDP transport/value and file-location helpers. Node fixture
success proves this Inspector workflow on the tested host; it does not prove
Electron GUI behavior or another engine.
Node Inspector verification does not establish Electron GUI or other engine
behavior. Browser and Inspector share CDP transport/value and file-location
helpers; their producer workflows remain distinct.
## Android APK analysis
@@ -478,23 +560,79 @@ kept under ignored `_reference/`. No Gradle build, Android SDK, emulator or
application execution is required. The lane compares real CLI/MCP package,
class search, class inventory, method decompilation and incoming references.
See [Android analysis](android-analysis.md) for boundaries and resource budgets.
`verify:jeb` requires a caller-started JEB client serving MCP at
`REA_JEB_MCP_URL` (default `http://127.0.0.1:8425/mcp`) with a project
already open, and verifies real CLI client inspection, unit listing coverage,
and method decompilation. The script records the engine's exact response to
`open_jeb_project`; JEB 5.48.0 headless instances do not advertise that tool.
REA does not install or launch JEB; see [JEB analysis](jeb-analysis.md) for
the bring-your-own boundary. Verified against JEB 5.48.0 serving
`jeb-mcp-server` 1.3.0 at four scales: a compiled Java class fixture, a
locally built signed probe APK with a launcher activity (manifest, v1/v2/v3
certificates, dex bytecode, filtered and paginated listing), the published
Signal 8.30.3 universal release APK (109 MB, R8-processed Kotlin/Compose,
four signature schemes, native arm64 ELF units) with MainActivity method
decompilation through both CLI and MCP, and the official Flutter Gallery
2.9.2 release APK (112 MB): per-ABI `libapp.so` Dart AOT snapshot images
analyzed as native code (75k methods on arm64) and decompiled through both
CLI and MCP with explicit unit selection, plus the thin Java wrapper and
decoded manifest. The dedicated Dart snapshot processor and `run_script`
remain GUI-only surfaces in JEB 5.48.0 headless.
Authenticated IPA and macOS application inventory projection is documented in
[Apple application analysis](apple-application-analysis.md).
The lane and owned-process cancellation helper live in `scripts/verify/android/`.
The explicit downloader and fixed manifest live in `scripts/fixtures/android/`;
their default remains repository-root `_reference/apk-integration/`. Producer
fixtures live in `tests/fixtures/android/`, boundary cases in
`tests/boundary/android/`, and inventory projection composition cases in
`tests/composition/android/`. Real engine success and synthetic protocol success
are separate proof levels.
Synthetic producer regressions run independently:
```sh
npm run test:focused -- tests/boundary/process/jadxIntegration.test.ts tests/boundary/process/androidAnalysisMcp.test.ts
```
## Apktool resource decoding
`npm run verify:apktool -- --apk PATH` exercises both Apktool operations
against a real launcher (`REA_APKTOOL_COMMAND` or PATH) and one APK. No
download or build step is involved. Record: apktool 2.7.0-dirty (Debian
packaging) on Linux with OpenJDK 25, against a signed aapt2-built probe APK
carrying two resource locales — launcher version, on-disk digest agreement
with the reported target identity, apktool.yml metadata projection
(1.2.3, SDK 24–34), manifest package agreement, and both the default and
`de` string tables projected through the locale option. Parser goldens in
`src/apktool/ApktoolDecodeOutput.test.ts` come from the same decode. See
[Apktool resource analysis](apktool-resource-analysis.md) for boundaries and
budgets.
## ADB device acquisition
`npm run verify:adb` exercises every ADB operation against a live device or
emulator through the caller's adb binary (`REA_ADB_PATH` or PATH). No SDK
installation or emulator management is involved; the device-mutating tools
run only in the explicit lifecycle section (`--install-apk` drives a
lane-owned install → resolve → start → observe → force-stop → uninstall
probe). `--pull` acquires a real package and re-digests the pulled files on
disk against the returned SHA-256 values; `--serial` selects a device when
several are attached.
Record: adb 34.0.5-debian on Linux against an Android 14 (API 34) x86_64
emulator. The lane covered the complete observation surface — 337-process
listing, 287 binder services including AIDL `/`-suffixed names, 92 features
including hex GL versions, display size/density, window focus (legitimately
null on headless devices), `settings get global adb_enabled`, bounded
logcat, directory listings — plus a real two-APK split set
(`base.apk` plus `split_probe.apk`, built and installed through
`install-multiple`) pulled with byte-exact digests, a push/pull roundtrip
verified by the device's own sha256sum, a 1.3 MB screen capture with PNG
dimensions, `dumpsys package` projection, and the full lifecycle: unique
resolution before launch, launcher-activity start through
`cmd package resolve-activity` with `am start -W`, the started app visible
in the process listing, force-stop, uninstall, and zero matches after
removal. System-package pulls whose APKs keep non-`base.apk` names report
the `unknown` role with the file-name basis, verified with
`com.android.settings` (single 73.9 MB APK). Parser goldens for
`adb devices -l`, `getprop`, `pm list packages -f`, and `pm path` come from
the same device. See [ADB device analysis](adb-device-analysis.md) for
boundaries and budgets.
## Optional NativeAOT Ghidra analysis
This lane is separate from the default native lane. `build:fixtures:nativeaot`
@@ -593,6 +731,17 @@ not make native host acceptance unavailable.
## Native platform baseline in CI
Pull requests that change only root `README*.md` files, `docs/`, `AGENTS.md`,
or `CONTRIBUTING.md` run formatting and generated-document validation without
the source-test shards or native package lanes. Classification compares the PR
head with its merge base, so later base-branch changes do not expand that scope.
The required static and coverage aggregate jobs remain present and fail if
classification fails. Mixed changes, unknown paths and CI configuration changes
retain full checks. Main pushes retain the full baseline, including after
documentation merges; newer commits cancel superseded CI for the same PR or
main branch. Release publication has its own concurrency group and retains its
package verification and public-registry canary.
CI exercises the pinned Node.js runtime on native hosted runners:
| Host | Runner | Baseline checks |
@@ -603,18 +752,14 @@ CI exercises the pinned Node.js runtime on native hosted runners:
| macOS 15 x64 | `macos-15-intel` | Installed package and real Node Inspector CLI/MCP |
| Windows x64 | `windows-latest` | Curated capabilities, native controls, installed package and real Node Inspector CLI/MCP |
Package and Inspector matrices assert the actual Node platform/architecture
before verification and record those values with the Node version. Each matrix
Package lanes assert the actual Node platform/architecture before verification
and record those values with the Node version. The four-host package matrix
runs at most two jobs concurrently with explicit timeouts and Node heap/thread
limits. Package checks cover installation, CLI/MCP discovery, target-free
limits; Windows retains its curated capability lane. Package checks cover
installation, CLI/MCP discovery, target-free
analysis, configuration backups/recovery, Evidence and owned lifecycle; Inspector
checks execute source-owned loopback targets and special filename cases.
macOS uses one OS version with one native baseline job per architecture. Each job
runs package and Inspector checks after a single dependency installation. The
separate Inspector matrix covers Linux and Windows; Apple artifact checks retain
their own macOS 15 arm64 job for Xcode-dependent workflows.
These native baseline checks complement the Linux source-test shards and the
separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA,
browser and managed-tool claims require their corresponding verification lanes.
@@ -684,23 +829,15 @@ broad changes or diagnosing CI, rather than after every edit. Package/install
changes additionally need package verification; provider changes need actual
provider evidence.
Each Vitest project uses up to two workers, bounded by available host parallelism.
Default-group projects can run together. Only `process-boundary` runs in the
later sequence group and serializes its files because process-tree observations
share host sampling resources. Tests that launch the real process harness belong
in `tests/boundary/process/`, including CLI command and environment tests.
Acceptance and process-global files retain isolated
forks but are not serialized; isolation does not imply serial scheduling. CI uses
the same per-project worker bound.
The pure domain/contracts and recording-port service projects share one worker
module context because their tests own no mutable runtime resources. MCP
boundary files also share the immutable server module graph while creating and
closing independent in-memory sessions. Adapter, composition, acceptance,
process-global, and other boundary projects retain per-file isolation.
Build and documentation writers use checkout-local locks for their respective
output files. `npm test` delegates its build to the build lock; the Vitest suite
does not hold a test-command lock. `check:pr` runs its test task before starting
generated-document validation.
Vitest projects use up to two workers, bounded by host parallelism.
`process-boundary` runs later with serial files because process-tree sampling
shares host resources. Acceptance and process-global cases use isolated forks
without serial scheduling. Pure domain/service and MCP boundary projects share
immutable module graphs; each MCP session still owns its resources. Other
projects retain per-file isolation. See `vitest.config.ts` for current settings.
Build/documentation writers hold checkout-local output locks. Tests do not
hold a broad command lock; `check:pr` finishes tests before document validation.
Vitest and Node persistent compile caches are deliberately not enabled by
default. To evaluate repeated local runs, opt in for both cold and warm
@@ -716,13 +853,9 @@ instrumentation remains equivalent.
## Coverage and timing
CI owns coverage. The aggregate floors are 65% statements, 60% branches, 60%
functions, and 68% lines. `src/domain/**` must reach 80% statements, 75%
branches, 75% functions, and 80% lines. `src/contracts/**` must reach 85%
statements, 80% branches, 80% functions, and 85% lines. Thresholds are
glob-specific rather than per-file and are never updated automatically.
Coverage does not replace named boundary, acceptance, or real-provider scenario
matrices.
CI owns coverage; aggregate and domain/contract thresholds are maintained in
`vitest.config.ts`. They are glob-specific and never updated automatically.
Coverage does not replace named boundary or real-provider scenarios.
CI runs four native Vitest shards without retries. Each shard emits a blob
report; the merge job produces aggregate coverage plus JUnit and JSON timing
@@ -796,22 +929,18 @@ unknown chunks, depth limits and extracted child digests. The optional
Neither optional toolchain is a base-lane prerequisite. See
[firmware analysis](firmware-analysis.md) for limits and unverified formats.
The real entrypoint is `scripts/verify/firmware/analysis.mjs`; the fixture runner
and unchanged Python producer belong together in `scripts/fixtures/firmware/`.
Producer fixtures and boundaries remain in `tests/fixtures/firmware/` and
`tests/boundary/firmware/`. Source-fixture generation proves the runner and
independent oracle; actual Binwalk/Unblob CLI/MCP proof requires selected tools.
### JavaScript source recovery
Build once with `npm run build:cached`, then run `npm run verify:javascript:recovery`.
This focused lane requires Linux x64, util-linux `prlimit`,
`REA_WAKARU_COMMAND` pointing to the official Wakaru 1.13.0 Linux x64 binary,
`REA_WAKARU_COMMAND` pointing to the official Wakaru 1.14.0 Linux x64 binary,
and `REA_JAVASCRIPT_FIXTURE_TOOLS` pointing to an isolated npm prefix containing
esbuild 0.25.10 and webpack 5.101.3. No global installation is required.
The lane compiles source-owned fixtures, exercises CLI and stdio MCP, verifies
published bytes and provenance, feeds recovered modules into existing analysis,
and compares a finite set of known fixture results. It does not establish
and compares a finite set of known fixture results. The provider also accepts
other ^1.13.0 releases and reports them as unverified; this lane proves the
audited release. It does not establish
arbitrary recovered-application equivalence. CI installs these prerequisites only
in `.github/workflows/real-javascript-recovery.yml`; the existing `real-browser`
lane uses real Chrome for browser capture and website workflows.
+75 -94
View File
@@ -1,106 +1,87 @@
# MCP tool design
Design tools around analyst tasks. A provider API is an implementation detail;
expose it directly when it gives agents a useful, reusable capability that
cannot be expressed through an existing contract. Do not impose caller-facing
limits merely to make work fit an assumed agent budget. Keep real input-format,
protocol, authority, and resource-safety constraints, and report their effects.
## Choose the tool shape
| Shape | Use it for | Contract should return |
| --------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `inspect` | Facts about one explicit target, address, object, or resource | Relevant fields, source locations, and facet-level availability |
| `search` / `list` | Finding candidate targets or entities | Stable ordering and useful result context; expose pagination when the result format or caller's query needs it |
| `trace` | Relationships across code, metadata, UI resources, or observations | Typed edges, supporting evidence, and unresolved paths; identify any genuine traversal boundary |
| `compare` | Two explicitly identified artifacts, versions, or evidence sets | Paired identity, comparable coverage, and deltas with evidence |
| `workflow` | A distinct analyst outcome that benefits from composition inside REA | A useful inline result, contributing evidence, and partial/unavailable facets |
| `observe` / `capture` | A question that requires runtime behavior | Required authority, launch/attach behavior, real operational constraints, lifecycle, and cleanup status |
These are task shapes, not required prefixes. Name a tool for the action and
object agents reason about; keep the name distinct from nearby alternatives.
## Prefer primitives; compose workflows
Start with a primitive when one call can report a reusable fact about one
identified object or relationship, such as an instruction decode, a type
layout, a reference, a dispatch target, or a resource graph. The same primitive
should be useful across different applications or analyst questions. A
format-specific decoder can still be a primitive when it describes a reusable
format rather than one application's product behavior.
Add a workflow when repeated analysis shows that callers need the same
multi-source result and REA can join the evidence without hiding important
choices or uncertainty. A useful check is whether the workflow remains
meaningful for different applications that share the relevant evidence types.
If its purpose depends on one application's business rules or product concepts,
keep that interpretation outside the general tool contract and expose the
underlying evidence through reusable primitives.
## Decide whether to add a tool
1. State the user intent and the smallest result that answers it.
2. Inspect the canonical tool contracts, current provider capabilities, and
representative CLI/MCP traces. Record the nearest competing tool.
3. Extend an existing contract when the intent and result are the same. Add a
batch or composed workflow when it materially improves a demonstrated task;
do not force agents through extra calls or collapse distinct tasks into one
tool. Add a tool when it answers a distinct analyst question or has a
materially different authority or result contract.
4. Keep public tool names and result semantics provider-neutral. Put engine-
specific parsing and protocol handling in adapters. Advertise exact support
per provider; do not create parallel tools just because engines differ.
5. Keep prompts optional and concise. They may point out useful tools, but must
not prescribe a call sequence when the task can be answered directly.
Design around the analyst question. Inspect the current canonical contracts,
provider capabilities, and nearest existing tool before changing the surface.
Extend a tool when intent and result contract match; add one for a distinct
outcome or materially different authority. Public names and semantics remain
provider-neutral, with exact coverage reported per provider.
Avoid opaque mode flags and mega-tools that combine unrelated discovery,
execution, and mutation. Prefer a useful direct tool call over a tool sequence
or model-authored loop when one call can answer the question.
Keep the catalog complete; report capability/session availability instead of
truncating schemas. Serialized bytes alone do not establish agent usability.
## Choose the tool shape
| Shape | Use it for | Result |
| --------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| `inspect` | Facts about one target, object, or resource | Relevant fields, locations, and facet availability |
| `search` / `list` | Candidate discovery | Stable ordering and context; pagination when the query or format needs it |
| `trace` | Relationships across evidence | Typed edges, supporting facts, and unresolved paths |
| `compare` | Explicitly paired artifacts or observations | Identity, comparable coverage, and supported deltas |
| `workflow` | A recurring outcome needing composition | Inline answer, contributing evidence, and partial facets |
| `observe` / `capture` | Runtime behavior | Authority, launch/attach effects, lifecycle, and cleanup status |
These are task shapes, not mandatory prefixes. Name tools for the action and
object callers reason about. Avoid unrelated discovery/execution/mutation modes
inside one tool.
## Prefer primitives; compose workflows
A primitive reports a reusable fact about an identified object or relationship.
A format-specific decoder qualifies; one application's business interpretation
belongs outside the general contract. Expose provider APIs when they add a
useful capability that existing tools cannot express.
Compose a workflow when repeated use demonstrates a multi-source outcome REA
can join without hiding caller choices or uncertainty. Batch homogeneous reads
when that removes repeated work while preserving per-item outcomes. Keep prompts
optional and avoid prescribing call sequences that a direct tool can replace.
Agents can compose experiments with ordinary commands, scripts, and local
fixture servers. Custom orchestration languages, replay engines, or separate
prepare/execute plans need an observed requirement those primitives cannot
satisfy. A plan without execution does not establish runtime behavior.
## Define the contract
- Use strict object inputs with explicit required fields and enums. Add numeric
bounds only when the format, protocol, authority, or a measured resource
constraint requires them.
- Return complete results by default. Make real pagination, truncation, partial
failure, cancellation, and unavailable states explicit. Missing evidence is
unknown, not empty or false.
- Return task-oriented results inline with artifact identity, provider/version,
addresses or resource paths, Evidence references, confidence, and relevant
limitations. Do not require agents to fetch a resource or dereference an
opaque Evidence link to understand a tool result.
- Separate observed facts from derived and inferred edges. Cite the evidence
supporting every important relationship; preserve unresolved edges.
- Declare read-only, mutation, process, filesystem, network, and UI effects
truthfully in the contract and enforce the target and lifecycle named in the
request.
- Keep provider-specific types out of provider-neutral domain and application
layers. Normalize supported provider results without implying equal coverage.
- Use strict inputs with explicit target identity and required fields. Preserve
meaningful target, action, capture, and output choices; remove ignored options
and repeated permission declarations.
- Return complete evidence inline, with artifact/provider identity, source
locations, Evidence references, and relevant confidence and limitations.
Missing coverage is unknown, not absence. Avoid extra lookups solely to
understand the answer or its provenance.
- Keep observed, derived, and inferred relationships distinct. Preserve
unresolved edges and partial provider facts instead of requiring every
provider to supply the same metadata.
- Declare process, filesystem, network, UI, and mutation effects truthfully;
enforce the requested target and lifecycle.
- Add limits only for real format, protocol, authority, or measured resource
constraints. Report pagination, truncation, cancellation, and partial failure.
An assumed agent budget is insufficient justification for a limit.
## Implement and evaluate
- Put shared user workflows in the application layer; keep MCP translation in
the server adapter and CLI behavior aligned with the same workflow. Share
Evidence provenance, unknown projection, and eligible snapshot binding through
application/session owners. Matching result payloads alone do not establish
equivalent retention or replay behavior.
- Derive each facet's coverage from examined records, unsupported representations,
and exhaustiveness. Keep issues structured until presentation; do not select a
facet by matching diagnostic prose or infer completeness from an empty failure
list. Preserve available observations independently of cleanup success.
- Measure the resource consumed before choosing a limit. Value alternatives,
retained records, trace-frame products, output bytes, and temporary-file growth
need different accounting. Enforce a justified budget before the costly step
and report its effect; an input-byte or graph-node cap does not bound every stage.
- Update the canonical contract inventory, output schemas, examples, generated
catalog, and relevant docs together.
- Verify valid, malformed, boundary, unavailable, cancellation, and partial
results at the owning boundaries. Use real-provider checks for claims that
depend on external analysis engines.
- Evaluate representative broad and direct task prompts on the intended MCP
host when tool selection is the question. Record the host, model-facing tool
catalog, selected tool, arguments, errors, retries, and task outcome.
Schema validity or word-overlap heuristics do not prove discoverability.
Put provider protocols/parsing in adapters and shared CLI/MCP workflows in the
application layer. Share Evidence provenance, unknown projection, and session
retention semantics; matching payloads alone do not establish parity.
See [mcp-contracts.md](mcp-contracts.md) for shipped runtime behavior and
[testing.md](testing.md) for test boundaries and verification lanes.
Measure the resource before choosing a budget and enforce it before the costly
step. Account for value alternatives, trace-frame products, retained records,
serialization expansion, and temporary-file growth separately. Derive facet
completeness from examined records and exhaustiveness, rather than diagnostic
prose or an empty failure list. Preserve observations independently of cleanup
success.
Update canonical contracts, output schemas, examples, generated artifacts, and
relevant docs together. Verify converted advertised schemas and success,
malformed, unavailable, cancellation, and partial outcomes through affected
consumers. Real-engine claims require the matching provider lane; see
[testing.md](testing.md).
When discoverability changes, evaluate representative broad, direct, and negative
tasks on the intended host. Record host/model/catalog, selected tools, arguments,
errors, retries, and task outcomes. Schema validity and keyword heuristics do not
establish successful tool selection. See [mcp-contracts.md](mcp-contracts.md) for
shipped runtime behavior.
+2 -2
View File
@@ -56,7 +56,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
46,src/application/Uninstall.ts:removeManagedPath symlink,Managed cache/state/skill path is a symbolic link,Refused to follow symlink {path}.,Exposes local path and does not explain manual safety check,"REA did not remove this item because its managed path is a symbolic link. Verify the link target before removing it manually.",implemented,focused assertion passed
47,src/application/Uninstall.ts:removeManagedPath failure,Managed item removal fails,{path} could not be removed.,Exposes local path and gives no recovery,"This item could not be removed. Check file permissions, then rerun uninstall.",implemented,verified by injected managed-path removal failure test
48,src/application/DoctorDiagnostics.ts:node,Runtime version is outside supported ranges,"Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",Low risk; exact dependency recovery,Keep current copy,unchanged,verified by doctor unit test
49,src/application/Doctor.ts:host,Host OS/distribution is unsupported,"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS.",Low risk; clearly states supported choices,Keep current copy,unchanged,verified by doctor unit tests
49,src/application/Doctor.ts:host,Host OS/distribution is unsupported,"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS.",Low risk; clearly states supported choices,Keep current copy,unchanged,verified by doctor unit tests
50,src/application/Doctor.ts:analysis engine,Optional deep-analysis executable cannot be found,"Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH.",Low risk in setup-specific diagnostic; exact recovery paths,Keep current copy,unchanged,verified by doctor unit tests
51,src/application/Doctor.ts:target,Optional target path fails shared validation,Supply a readable local app or program path.,Low risk; tells caller valid target class,Keep current copy,unchanged,verified by doctor unit test
52,src/application/Setup.ts:approval,Setup plan lacks approval,"Review the setup plan, then rerun interactively or with --yes.",Low risk; exact authorization recovery,Keep current copy,unchanged,verified by setup unit tests
@@ -67,7 +67,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
57,src/application/Setup.ts:unsupported platform,Platform is neither macOS nor Linux,REA supports Hopper on macOS and selected 64-bit Linux distributions.,Low risk; states support boundary,Keep current copy,unchanged,verified by setup unit test
58,src/application/SetupHost.ts:unsupported Node,Runtime version cannot run setup,"Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ and rerun setup.",Low risk; exact dependency and retry,Keep current copy,unchanged,verified by setup host tests
59,src/application/Setup.ts:unsupported macOS,macOS version is missing or older than 12,Upgrade to macOS 12 or newer.,Low risk; exact support floor,Keep current copy,unchanged,verified by setup host tests
60,src/application/Setup.ts:unsupported Linux,Linux distribution is outside supported set,"REA supports Hopper on Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS.",Low risk; exact supported alternatives,Keep current copy,unchanged,verified by setup unit test
60,src/application/Setup.ts:unsupported Linux,Linux distribution is outside supported set,"REA supports Hopper on Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS.",Low risk; exact supported alternatives,Keep current copy,unchanged,verified by setup unit test
61,src/application/process/ProcessCli.ts:readJson read,Process scenario or evidence file cannot be read,Raw filesystem exception through CLI framework,Can expose local paths/codes and no recovery,"Process input file could not be read. Check that the path exists and is readable.",implemented,verified by focused CLI test
62,src/application/process/ProcessCli.ts:readJson size,Process scenario or evidence file exceeds 64 MiB,Process JSON input exceeds byte limit,Does not state limit or recovery,"Process input file is too large. Reduce it below 64 MiB, then try again.",implemented,verified by focused sparse-file CLI test
63,src/application/process/ProcessCli.ts:readJson parse,Process scenario or evidence file is malformed JSON,Raw JSON parser exception through CLI framework,Can expose parser implementation and lacks recovery,"Process input file is not valid JSON. Repair the file, then try again.",implemented,verified by focused CLI test
1 harm_rank location trigger current_copy user_risk proposed_replacement implementation_status verification_result
56 46 src/application/Uninstall.ts:removeManagedPath symlink Managed cache/state/skill path is a symbolic link Refused to follow symlink {path}. Exposes local path and does not explain manual safety check REA did not remove this item because its managed path is a symbolic link. Verify the link target before removing it manually. implemented focused assertion passed
57 47 src/application/Uninstall.ts:removeManagedPath failure Managed item removal fails {path} could not be removed. Exposes local path and gives no recovery This item could not be removed. Check file permissions, then rerun uninstall. implemented verified by injected managed-path removal failure test
58 48 src/application/DoctorDiagnostics.ts:node Runtime version is outside supported ranges Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+. Low risk; exact dependency recovery Keep current copy unchanged verified by doctor unit test
59 49 src/application/Doctor.ts:host Host OS/distribution is unsupported REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS. REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS. Low risk; clearly states supported choices Keep current copy unchanged verified by doctor unit tests
60 50 src/application/Doctor.ts:analysis engine Optional deep-analysis executable cannot be found Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH. Low risk in setup-specific diagnostic; exact recovery paths Keep current copy unchanged verified by doctor unit tests
61 51 src/application/Doctor.ts:target Optional target path fails shared validation Supply a readable local app or program path. Low risk; tells caller valid target class Keep current copy unchanged verified by doctor unit test
62 52 src/application/Setup.ts:approval Setup plan lacks approval Review the setup plan, then rerun interactively or with --yes. Low risk; exact authorization recovery Keep current copy unchanged verified by setup unit tests
67 57 src/application/Setup.ts:unsupported platform Platform is neither macOS nor Linux REA supports Hopper on macOS and selected 64-bit Linux distributions. Low risk; states support boundary Keep current copy unchanged verified by setup unit test
68 58 src/application/SetupHost.ts:unsupported Node Runtime version cannot run setup Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ and rerun setup. Low risk; exact dependency and retry Keep current copy unchanged verified by setup host tests
69 59 src/application/Setup.ts:unsupported macOS macOS version is missing or older than 12 Upgrade to macOS 12 or newer. Low risk; exact support floor Keep current copy unchanged verified by setup host tests
70 60 src/application/Setup.ts:unsupported Linux Linux distribution is outside supported set REA supports Hopper on Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS. REA supports Hopper on Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS. Low risk; exact supported alternatives Keep current copy unchanged verified by setup unit test
71 61 src/application/process/ProcessCli.ts:readJson read Process scenario or evidence file cannot be read Raw filesystem exception through CLI framework Can expose local paths/codes and no recovery Process input file could not be read. Check that the path exists and is readable. implemented verified by focused CLI test
72 62 src/application/process/ProcessCli.ts:readJson size Process scenario or evidence file exceeds 64 MiB Process JSON input exceeds byte limit Does not state limit or recovery Process input file is too large. Reduce it below 64 MiB, then try again. implemented verified by focused sparse-file CLI test
73 63 src/application/process/ProcessCli.ts:readJson parse Process scenario or evidence file is malformed JSON Raw JSON parser exception through CLI framework Can expose parser implementation and lacks recovery Process input file is not valid JSON. Repair the file, then try again. implemented verified by focused CLI test
+4
View File
@@ -12,6 +12,10 @@ For passive inspection, select `include_script_sources: true` (CLI:
`capture.network.response_body: true`. Save either the complete Evidence record
or its normalized result as UTF-8 JSON. MCP `structuredContent` contains the complete Evidence record.
The capture must be a regular file. A symlink to a regular file is accepted;
directories, named pipes and device files are rejected before reading capture
bytes or creating output.
```sh
rea export-web-scripts /analysis/capture.json /analysis/exported-scripts --json
rea analyze-javascript-application /analysis/exported-scripts/files --json
+13 -2
View File
@@ -17,7 +17,7 @@ additional permission flag or degraded mode is required.
- Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+;
- an operator-installed Ghidra 12.1.x distribution (verified with 12.1.4);
- a 64-bit full JDK inside that installation's declared Java range (JDK 21 or newer, with no maximum, for current 12.1 releases);
- an explicit native, non-managed, non-DLL x86 or x86-64 PE application; and
- an explicit native, non-managed x86 or x86-64 PE application or DLL; and
- the 25 read-only Ghidra inventory, memory, and function-analysis operations.
Loaded memory reads and file offsets preserve Ghidra's observed source mappings.
@@ -38,6 +38,13 @@ REA selects its packaged bridge scripts by explicit path. Same-named files or
directories in the caller's working directory do not select a different
script or require users to clean that directory before analysis.
Native DLL analysis preserves the PE shared-library role in the analysis profile.
REA imports an immutable copy for static analysis; it does not load the library
into the analyst process or execute its entry routine. The source-owned DLL
fixtures have no entry routine or imports and expose two exported functions.
The same native snapshot, path-admission and cleanup requirements apply to EXEs
and DLLs.
## Configuration
```powershell
@@ -100,7 +107,7 @@ and artifact SHA-256 before loading the package-owned addon. Native failure
reasons remain distinct from a valid installation and an unsupported target.
PE header classification and SHA-256 come from the same open file. The Windows
provider admits native x86 and x86-64 PE applications and rejects unsupported roles,
provider admits native x86 and x86-64 PE applications and DLLs and rejects unsupported roles,
architectures, managed images, and malformed headers. The original selected
source coordinate is preserved for native admission.
@@ -159,7 +166,11 @@ artifact and manifest.
npm run verify:windows-native
npm run verify:ghidra:windows
npm run verify:ghidra:windows -- --x86
npm run verify:ghidra:windows -- --dll
npm run verify:ghidra:windows -- --x86 --dll
npm run verify:ghidra:windows:package -- --x86
npm run verify:ghidra:windows:package -- --dll
npm run verify:ghidra:windows:package -- --x86 --dll
npm run verify:ghidra:windows:package -- C:\fixtures\installed-rea C:\fixtures\sample.exe
```
+26 -4
View File
@@ -1,12 +1,12 @@
{
"name": "rea-agents",
"version": "6.2.0",
"version": "6.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "rea-agents",
"version": "6.2.0",
"version": "6.3.0",
"license": "MIT",
"dependencies": {
"@babel/parser": "8.0.4",
@@ -38,8 +38,10 @@
"plist": "5.0.0",
"semver": "7.8.5",
"smol-toml": "1.9.0",
"stream-json": "3.7.0",
"write-file-atomic": "7.0.0",
"ws": "8.21.0",
"yaml": "2.9.0",
"zod": "4.4.3"
},
"bin": {
@@ -63,8 +65,7 @@
"turbo": "2.11.7",
"typescript": "7.0.2",
"vitepress": "1.6.4",
"vitest": "5.0.3",
"yaml": "2.9.0"
"vitest": "5.0.3"
},
"engines": {
"node": "^22.19.0 || ^24.11.0 || >=26.0.0"
@@ -7070,6 +7071,27 @@
"dev": true,
"license": "MIT"
},
"node_modules/stream-chain": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-4.2.6.tgz",
"integrity": "sha512-1zeJ8CrtJfmiba26ui8jXkq/xLRFvhzkdH02D5QLO9Cnovgeb28IJxg88DdraWnjnkbOol/++uIAybJbJhk7ig==",
"license": "BSD-3-Clause",
"funding": {
"url": "https://github.com/sponsors/uhop"
}
},
"node_modules/stream-json": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/stream-json/-/stream-json-3.7.0.tgz",
"integrity": "sha512-rCSBdcBP/bPk6T8QFcxAj1MSzAuc5i49cYW6IE7sYObNEPccBJIUiL6fU9c9BWt40aJK0siVynLX7lWaW8alXw==",
"license": "BSD-3-Clause",
"dependencies": {
"stream-chain": "^4.2.5"
},
"funding": {
"url": "https://github.com/sponsors/uhop"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+25 -6
View File
@@ -1,7 +1,7 @@
{
"name": "rea-agents",
"mcpName": "io.github.morluto/rea",
"version": "6.2.0",
"version": "6.3.0",
"description": "Reverse engineer anything from your terminal or agent with one CLI and MCP server.",
"license": "MIT",
"repository": {
@@ -50,6 +50,7 @@
"bridge/ghidra/ReaGhidraBridge.java",
"bridge/ghidra/ReaGhidraExtensions.java",
"bridge/ghidra/ReaGhidraPrepareCom.java",
"bridge/ghidra/ReaGhidraNoReturnFix.java",
"bridge/android/ReaJadxBridge.java",
"bridge/mitmproxy/capture.py",
"scripts/rea.mjs",
@@ -88,7 +89,7 @@
"prebuild": "npm run deps:check",
"build": "node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills --force",
"precheck": "npm run deps:check",
"check": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint format:check knip metadata:check",
"check": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint format:check knip metadata:check && npm run verify:architecture-guards",
"precheck:fast": "npm run deps:check",
"check:fast": "turbo run typecheck lint --output-logs=errors-only",
"precheck:changed": "npm run deps:check",
@@ -98,7 +99,7 @@
"precheck:pr": "npm run deps:check",
"check:pr": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint format:check knip metadata:check test:run && npm run docs:check && npm run jscpd && npm run scan:todos",
"precheck:ci": "npm run deps:check",
"check:ci": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint format:check knip metadata:check jscpd scan:todos",
"check:ci": "node scripts/run-exclusive.mjs artifacts turbo run typecheck lint format:check knip metadata:check jscpd scan:todos && npm run verify:architecture-guards",
"build:cached": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills",
"format": "oxfmt .",
"format:check": "oxfmt --check .",
@@ -144,7 +145,12 @@
"verify:native-ui": "npm run build:cached && node scripts/verify-native-ui.mjs",
"verify:keyed-archive": "npm run build:cached && node scripts/verify/apple/keyed-archive.mjs",
"verify:macos-bundle": "npm run build:cached && node scripts/verify/apple/macos-bundle.mjs",
"verify:legacy-simulator": "npm run build:cached && node scripts/verify/apple/legacy-simulator.mjs",
"verify:architecture-guards": "node scripts/verify/architecture-guards.mjs",
"verify:apktool": "npm run build:cached && node scripts/verify-apktool.mjs",
"verify:adb": "npm run build:cached && node scripts/verify-adb.mjs",
"verify:ghidra": "npm run build:cached && node scripts/verify-real-ghidra.mjs",
"verify:ghidra:mips": "npm run build:cached && node scripts/verify-real-ghidra-mips.mjs",
"verify:ghidra:swift": "npm run build:cached && node scripts/verify-real-ghidra-swift.mjs",
"verify:ida": "npm run build:cached && node scripts/verify-real-ida.mjs",
"verify:ghidra:switch": "npm run build:cached && node scripts/verify-real-ghidra-switch.mjs",
@@ -167,6 +173,7 @@
"verify:firmware": "npm run build:cached && node scripts/verify/firmware/analysis.mjs",
"fixtures:firmware": "node scripts/fixtures/firmware/generate.mjs",
"verify:android": "npm run build:cached && node scripts/verify/android/analysis.mjs",
"verify:jeb": "npm run build:cached && node scripts/verify-jeb.mjs",
"fixtures:android": "node scripts/fixtures/android/fetch.mjs",
"verify:agent": "npm run build:cached && node scripts/verify-agent-experience.mjs",
"verify:hopper:linux": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper-linux.mjs",
@@ -177,6 +184,17 @@
"verify:readiness": "npm run build:cached && npm run verify:fixtures && node scripts/verify-reconstruction-readiness.mjs",
"verify:package": "npm run build:cached && node scripts/verify-package.mjs",
"verify:package:windows": "npm run build:cached && node scripts/verify-windows-package.mjs",
"verify:qwen-client": "npm run build:cached && node scripts/verify-qwen-client.mjs",
"verify:gemini-client": "npm run build:cached && node scripts/verify-gemini-client.mjs",
"verify:opencode-client": "npm run build:cached && node scripts/verify-opencode-client.mjs",
"verify:grok-client": "npm run build:cached && node scripts/verify-grok-client.mjs",
"verify:commandcode-client": "npm run build:cached && node scripts/verify-commandcode-client.mjs",
"verify:omp-client": "npm run build:cached && node scripts/verify-omp-client.mjs",
"verify:copilot-client": "npm run build:cached && node scripts/verify-copilot-client.mjs",
"verify:claude-client": "npm run build:cached && node scripts/verify-claude-client.mjs",
"verify:pi-client": "npm run build:cached && node scripts/verify-native-agent-client.mjs pi",
"verify:hermes-client": "npm run build:cached && node scripts/verify-native-agent-client.mjs hermes",
"verify:deepseek-client": "npm run build:cached && node scripts/verify-deepseek-client.mjs",
"probe:windows-capabilities": "npm run build:cached && node scripts/windows-capabilities.mjs",
"verify:published": "node scripts/verify-published-package.mjs",
"config:print": "node scripts/print-mcp-config.mjs",
@@ -263,10 +281,12 @@
"plist": "5.0.0",
"semver": "7.8.5",
"smol-toml": "1.9.0",
"stream-json": "3.7.0",
"write-file-atomic": "7.0.0",
"ws": "8.21.0",
"zod": "4.4.3",
"evmole": "0.9.3"
"evmole": "0.9.3",
"yaml": "2.9.0"
},
"overrides": {
"vitepress": {
@@ -290,7 +310,6 @@
"turbo": "2.11.7",
"typescript": "7.0.2",
"vitepress": "1.6.4",
"vitest": "5.0.3",
"yaml": "2.9.0"
"vitest": "5.0.3"
}
}
+135
View File
@@ -0,0 +1,135 @@
"""Optionally audit external website links; network failures stay distinct from missing targets."""
import argparse
from concurrent.futures import ThreadPoolExecutor
from functools import lru_cache
from html.parser import HTMLParser
import json
from pathlib import Path
import re
import subprocess
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import quote, unquote, urlsplit
from urllib.request import Request, urlopen
from website import authored_markdown
@lru_cache(maxsize=None)
def github_api(endpoint):
"""Read GitHub evidence through the caller's gh installation and authentication."""
result = subprocess.run(["gh", "api", endpoint], capture_output=True, text=True, timeout=20)
if result.returncode:
raise ValueError(result.stderr.strip())
return json.loads(result.stdout)
def github_target(url):
"""Resolve repository URLs, including branch names containing slashes."""
parts = [unquote(part) for part in url.path.strip("/").split("/")]
if len(parts) < 2:
return None
repo = f"repos/{parts[0]}/{parts[1]}"
if url.hostname == "raw.githubusercontent.com" and len(parts) >= 4:
return f"{repo}/contents/{'/'.join(parts[3:])}?ref={quote(parts[2], safe='')}"
if len(parts) == 2:
return repo
kind = parts[2]
if kind in ("blob", "tree") and len(parts) >= 4:
ref = parts[3]
# GitHub uses the longest matching branch name before the source path.
if not re.fullmatch(r"[0-9a-f]{40}", ref):
references = github_api(f"{repo}/git/matching-refs/heads/{quote(ref, safe='')}")
references += github_api(f"{repo}/git/matching-refs/tags/{quote(ref, safe='')}")
suffix = "/".join(parts[3:])
matches = [item["ref"].split("/", 2)[2] for item in references]
matches = [name for name in matches if suffix == name or suffix.startswith(name + "/")]
if matches:
ref = max(matches, key=len)
path = "/".join(parts[3:])[len(ref):].lstrip("/")
return f"{repo}/contents/{quote(path, safe='/')}?ref={quote(ref, safe='')}"
if kind in ("issues", "pull") and len(parts) == 4 and parts[3].isdigit():
return f"{repo}/{'pulls' if kind == 'pull' else 'issues'}/{parts[3]}"
if kind == "commit" and len(parts) == 4:
return f"{repo}/commits/{parts[3]}"
if kind == "releases" and len(parts) >= 5 and parts[3] in ("tag", "download"):
return f"{repo}/releases/tags/{quote(parts[4], safe='')}"
return None
def audit_url(item):
"""Classify confirmed missing links separately from blocked or unsupported probes."""
value, sources = item
result = {"url": value, "sources": sorted(set(sources))}
url = urlsplit(value)
try:
if url.hostname in ("github.com", "raw.githubusercontent.com"):
endpoint = github_target(url)
if endpoint is None:
return dict(result, status="unknown", reason="GitHub UI route; check in a browser")
data = github_api(endpoint)
parts = url.path.strip("/").split("/")
if len(parts) >= 6 and parts[2:4] == ["releases", "download"]:
if unquote(parts[5]) not in [asset["name"] for asset in data.get("assets", [])]:
return dict(result, status="broken", reason="Release asset is missing")
return dict(result, status="ok", via="gh api", endpoint=endpoint)
request = Request(value.split("#", 1)[0], headers={
"User-Agent": "REA-Website-Verifier/1.0 (+https://github.com/morluto/rea)",
})
with urlopen(request, timeout=15) as response:
return dict(result, status="ok", http_status=response.status, final_url=response.url)
except HTTPError as error:
return dict(result, status="broken" if error.code in (404, 410) else "unknown", reason=str(error))
except ValueError as error:
return dict(result, status="broken" if "HTTP 404" in str(error) else "unknown", reason=str(error))
except (OSError, URLError, TimeoutError, subprocess.TimeoutExpired) as error:
return dict(result, status="unknown", reason=str(error))
def external_links(root):
"""Discover authored external links, excluding locally checked site and preview URLs."""
references = {}
def add(value, source):
url = urlsplit(value)
if url.scheme in ("http", "https") and url.hostname not in ("rea.tools", "localhost", "127.0.0.1", "::1"):
references.setdefault(value, []).append(str(source.relative_to(root)))
class Links(HTMLParser):
def handle_starttag(self, tag, attrs):
for key, value in attrs:
if key in ("href", "src") and value:
add(value, path)
for path in sorted((root / "website/public").rglob("*.html")):
Links().feed(path.read_text(encoding="utf-8"))
for path in authored_markdown(root):
for value in re.findall(r"(?:\]\(|<)(https?://[^\s<>\)]+)", path.read_text(encoding="utf-8")):
add(value, path)
return references
def main():
"""Run an explicit network audit without making PR checks depend on third-party uptime."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--report", type=Path, help="Write the complete JSON report outside public assets")
args = parser.parse_args()
root = Path(__file__).resolve().parent.parent
with ThreadPoolExecutor(max_workers=4) as pool:
results = list(pool.map(audit_url, external_links(root).items()))
if args.report:
if args.report.resolve().is_relative_to(root / "website/public"):
parser.error("Keep audit reports outside website/public.")
args.report.write_text(json.dumps(results, indent=2) + "\n", encoding="utf-8")
counts = {status: sum(item["status"] == status for item in results) for status in ("ok", "broken", "unknown")}
print(f"External links: {counts['ok']} reachable, {counts['broken']} missing, {counts['unknown']} need manual verification.")
print("GitHub checks establish target existence; external fragment IDs are not checked.")
for item in results:
if item["status"] != "ok":
print(f"{item['status']}: {item['url']} — {item['reason']}")
return 1 if counts["broken"] else 0
if __name__ == "__main__":
sys.exit(main())
+133 -60
View File
@@ -3,68 +3,141 @@ import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
// Source-owned static fixtures: no compiler, target loading or execution.
for (const architecture of ["x86_64", "x86"]) {
const x86 = architecture === "x86";
const output = resolve(
root,
"build",
"fixtures",
x86 ? "rea-ghidra-windows-x86.exe" : "rea-ghidra-windows.exe",
);
const bytes = Buffer.alloc(1024);
const peOffset = 0x80;
const optionalHeader = peOffset + 24;
const optionalHeaderSize = x86 ? 0xe0 : 0xf0;
const sectionTable = optionalHeader + optionalHeaderSize;
for (const dll of [false, true]) {
const x86 = architecture === "x86";
const output = resolve(
root,
"build",
"fixtures",
`rea-ghidra-windows${x86 ? "-x86" : ""}.${dll ? "dll" : "exe"}`,
);
const bytes = Buffer.alloc(dll ? 1024 : 1536);
const peOffset = 0x80;
const optionalHeader = peOffset + 24;
const optionalHeaderSize = x86 ? 0xe0 : 0xf0;
const sectionTable = optionalHeader + optionalHeaderSize;
const directories = optionalHeader + (x86 ? 96 : 112);
bytes.write("MZ", 0, "ascii");
bytes.writeUInt32LE(peOffset, 0x3c);
bytes.write("PE\0\0", peOffset, "binary");
bytes.writeUInt16LE(x86 ? 0x14c : 0x8664, peOffset + 4);
bytes.writeUInt16LE(1, peOffset + 6);
bytes.writeUInt16LE(optionalHeaderSize, peOffset + 20);
bytes.writeUInt16LE(x86 ? 0x102 : 0x22, peOffset + 22);
bytes.write("MZ", 0, "ascii");
bytes.writeUInt32LE(peOffset, 0x3c);
bytes.write("PE\0\0", peOffset, "binary");
bytes.writeUInt16LE(x86 ? 0x14c : 0x8664, peOffset + 4);
bytes.writeUInt16LE(dll ? 1 : 2, peOffset + 6);
bytes.writeUInt16LE(optionalHeaderSize, peOffset + 20);
bytes.writeUInt16LE(
(x86 ? 0x102 : 0x22) | (dll ? 0x2000 : 0),
peOffset + 22,
);
bytes.writeUInt16LE(x86 ? 0x10b : 0x20b, optionalHeader);
bytes.writeUInt32LE(0x200, optionalHeader + 4);
bytes.writeUInt32LE(0x1000, optionalHeader + 16);
bytes.writeUInt32LE(0x1000, optionalHeader + 20);
if (x86) bytes.writeUInt32LE(0x400000, optionalHeader + 28);
else bytes.writeBigUInt64LE(0x1_4000_0000n, optionalHeader + 24);
bytes.writeUInt32LE(0x1000, optionalHeader + 32);
bytes.writeUInt32LE(0x200, optionalHeader + 36);
bytes.writeUInt16LE(6, optionalHeader + 40);
bytes.writeUInt16LE(6, optionalHeader + 48);
bytes.writeUInt32LE(0x2000, optionalHeader + 56);
bytes.writeUInt32LE(0x200, optionalHeader + 60);
bytes.writeUInt16LE(3, optionalHeader + 68);
bytes.writeUInt16LE(x86 ? 0x8140 : 0x8160, optionalHeader + 70);
if (x86) {
bytes.writeUInt32LE(0x10_0000, optionalHeader + 72);
bytes.writeUInt32LE(0x1000, optionalHeader + 76);
bytes.writeUInt32LE(0x10_0000, optionalHeader + 80);
bytes.writeUInt32LE(0x1000, optionalHeader + 84);
bytes.writeUInt32LE(16, optionalHeader + 92);
} else {
bytes.writeBigUInt64LE(0x10_0000n, optionalHeader + 72);
bytes.writeBigUInt64LE(0x1000n, optionalHeader + 80);
bytes.writeBigUInt64LE(0x10_0000n, optionalHeader + 88);
bytes.writeBigUInt64LE(0x1000n, optionalHeader + 96);
bytes.writeUInt32LE(16, optionalHeader + 108);
bytes.writeUInt16LE(x86 ? 0x10b : 0x20b, optionalHeader);
bytes.writeUInt32LE(0x200, optionalHeader + 4);
if (!dll) bytes.writeUInt32LE(0x200, optionalHeader + 8);
bytes.writeUInt32LE(dll ? 0 : 0x1000, optionalHeader + 16);
bytes.writeUInt32LE(0x1000, optionalHeader + 20);
if (x86) bytes.writeUInt32LE(0x400000, optionalHeader + 28);
else bytes.writeBigUInt64LE(0x1_4000_0000n, optionalHeader + 24);
bytes.writeUInt32LE(0x1000, optionalHeader + 32);
bytes.writeUInt32LE(0x200, optionalHeader + 36);
bytes.writeUInt16LE(6, optionalHeader + 40);
bytes.writeUInt16LE(6, optionalHeader + 48);
bytes.writeUInt32LE(dll ? 0x2000 : 0x3000, optionalHeader + 56);
bytes.writeUInt32LE(0x200, optionalHeader + 60);
bytes.writeUInt16LE(3, optionalHeader + 68);
bytes.writeUInt16LE(x86 ? 0x8140 : 0x8160, optionalHeader + 70);
if (x86) {
bytes.writeUInt32LE(0x10_0000, optionalHeader + 72);
bytes.writeUInt32LE(0x1000, optionalHeader + 76);
bytes.writeUInt32LE(0x10_0000, optionalHeader + 80);
bytes.writeUInt32LE(0x1000, optionalHeader + 84);
bytes.writeUInt32LE(16, optionalHeader + 92);
} else {
bytes.writeBigUInt64LE(0x10_0000n, optionalHeader + 72);
bytes.writeBigUInt64LE(0x1000n, optionalHeader + 80);
bytes.writeBigUInt64LE(0x10_0000n, optionalHeader + 88);
bytes.writeBigUInt64LE(0x1000n, optionalHeader + 96);
bytes.writeUInt32LE(16, optionalHeader + 108);
}
bytes.write(".text", sectionTable, "ascii");
bytes.writeUInt32LE(dll ? 0x180 : 0x50, sectionTable + 8);
bytes.writeUInt32LE(0x1000, sectionTable + 12);
bytes.writeUInt32LE(0x200, sectionTable + 16);
bytes.writeUInt32LE(0x200, sectionTable + 20);
bytes.writeUInt32LE(0x6000_0020, sectionTable + 36);
// EXE entry returns zero. DLL caller adds one to the callee's 42.
bytes.set(
dll
? [0xe8, 0x0b, 0, 0, 0, 0x83, 0xc0, 1, 0xc3]
: [0xe8, 0x0b, 0, 0, 0, 0xe8, 0x16, 0, 0, 0, 0x31, 0xc0, 0xc3],
0x200,
);
bytes.set([0xb8, 0x2a, 0, 0, 0, 0xc3], 0x210);
if (!dll) {
const dataSection = sectionTable + 40;
bytes.write(".data", dataSection, "ascii");
bytes.writeUInt32LE(0x20, dataSection + 8);
bytes.writeUInt32LE(0x2000, dataSection + 12);
bytes.writeUInt32LE(0x200, dataSection + 16);
bytes.writeUInt32LE(0x400, dataSection + 20);
bytes.writeUInt32LE(0xc000_0040, dataSection + 36);
bytes.writeUInt32LE(0x1122_3344, 0x400);
const referenceInstructions = x86
? [
"ba00204000", // MOV EDX, address: DATA only.
"a100204000", // MOV EAX, [address]: READ.
"a304204000", // MOV [address], EAX: WRITE.
"ba10204000", // Indexed base, unknown ECX.
"85db", // TEST EBX, EBX: two candidate bases.
"7405", // JZ over the alternate base.
"ba18204000", // MOV EDX, alternate base.
"c6040a01", // MOV byte [EDX + ECX], 1.
"ffd7", // CALL EDI: unknown target.
"c3",
]
: [
"488d15d90f0000", // LEA RDX, [RIP + displacement]: DATA.
"8b05d30f0000", // MOV EAX, [RIP + displacement]: READ.
"8905d10f0000", // MOV [RIP + displacement], EAX: WRITE.
"488d15d60f0000", // Indexed base, unknown RCX.
"85db", // TEST EBX, EBX: two candidate bases.
"7407", // JZ over the alternate base.
"488d15d30f0000", // LEA RDX, alternate base.
"c6040a01", // MOV byte [RDX + RCX], 1.
"41ffd0", // CALL R8: unknown target.
"c3",
];
bytes.set(Buffer.from(referenceInstructions.join(""), "hex"), 0x220);
}
if (dll) {
// Export both functions; an entry-point-free library is discovered by exports.
bytes.writeUInt32LE(0x1040, directories);
bytes.writeUInt32LE(0x130, directories + 4);
const exports = 0x240;
bytes.writeUInt32LE(0x1100, exports + 12);
bytes.writeUInt32LE(1, exports + 16);
bytes.writeUInt32LE(2, exports + 20);
bytes.writeUInt32LE(2, exports + 24);
bytes.writeUInt32LE(0x1080, exports + 28);
bytes.writeUInt32LE(0x1088, exports + 32);
bytes.writeUInt32LE(0x1090, exports + 36);
bytes.writeUInt32LE(0x1000, 0x280);
bytes.writeUInt32LE(0x1010, 0x284);
bytes.writeUInt32LE(0x1120, 0x288);
bytes.writeUInt32LE(0x1140, 0x28c);
bytes.writeUInt16LE(0, 0x290);
bytes.writeUInt16LE(1, 0x292);
bytes.write("rea-fixture.dll\0", 0x300, "binary");
bytes.write("fixture_caller\0", 0x320, "binary");
bytes.write("fixture_return42\0", 0x340, "binary");
}
await mkdir(dirname(output), { recursive: true });
await writeFile(output, bytes);
if (!x86 && !dll) process.stdout.write(`${output}\n`);
}
bytes.write(".text", sectionTable, "ascii");
bytes.writeUInt32LE(0x16, sectionTable + 8);
bytes.writeUInt32LE(0x1000, sectionTable + 12);
bytes.writeUInt32LE(0x200, sectionTable + 16);
bytes.writeUInt32LE(0x200, sectionTable + 20);
bytes.writeUInt32LE(0x6000_0020, sectionTable + 36);
// entry calls the second function, returns zero; second returns 42.
bytes.set([0xe8, 0x0b, 0, 0, 0, 0x31, 0xc0, 0xc3], 0x200);
bytes.set([0xb8, 0x2a, 0, 0, 0, 0xc3], 0x210);
await mkdir(dirname(output), { recursive: true });
await writeFile(output, bytes);
if (!x86) process.stdout.write(`${output}\n`);
}
@@ -11,6 +11,30 @@ export async function startBrowserVerifierSite() {
response.destroy();
return;
}
const requestUrl = new URL(request.url ?? "/", "http://127.0.0.1");
if (requestUrl.pathname === "/scenario-environment") {
const requestedRun = requestUrl.searchParams.get("run");
const run = ["A", "B", "C"].includes(requestedRun)
? requestedRun
: "default";
response.setHeader("content-type", "text/html");
response.end(`<!doctype html><html><body data-run="${run}"><pre id="environment"></pre>
<button id="refresh-environment">Refresh environment</button><script>
const refresh = () => document.querySelector('#environment').textContent = JSON.stringify({
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
locale: Intl.DateTimeFormat().resolvedOptions().locale,
dpr: devicePixelRatio, width: innerWidth, height: innerHeight
});
document.querySelector('#refresh-environment').onclick = refresh;
window.releaseScenario = () => {
const release = document.createElement('span');
release.id = 'release-' + document.body.dataset.run;
document.body.append(release);
};
refresh();
</script></body></html>`);
return;
}
if (request.url === "/slow-json") {
response.setHeader("content-type", "application/json");
response.write('{"pending":');
@@ -0,0 +1,35 @@
import { functionDossierSchema } from "../../../dist/domain/hopperValues.js";
/** Validated synthetic native observations shared by managed verification lanes. */
export const functionDossier = (name) =>
functionDossierSchema.parse({
procedure: {
address: "0x401000",
name,
classification: {
external: false,
thunk: false,
thunk_target: null,
provenance: "synthetic-provider",
},
body: {
available: false,
reason: "Synthetic provider does not supply function body ranges.",
},
signature: null,
locals: [],
},
pseudocode: "",
assembly: [],
comments: [],
callers: [],
callees: [],
incoming_references: [],
outgoing_references: [],
referenced_strings: [],
referenced_names: [],
basic_blocks: [],
native_api: null,
native_value_flow: null,
limitations: [],
});
+1 -1
View File
@@ -17,7 +17,7 @@ const lock = JSON.parse(
await readFile(join(root, "package-lock.json"), "utf8"),
);
const skill = await readFile(
join(root, "skill-src/reverse-engineer-anything/SKILL.md"),
join(root, ".agents/skills/reverse-engineer-anything/SKILL.md"),
"utf8",
);
const skillVersion = /^\s{2}version:\s*"([^"]+)"\s*$/mu.exec(skill)?.[1];
+16 -7
View File
@@ -10,26 +10,35 @@ for (const argument of arguments_)
throw new Error(`Unknown skill metadata option: ${argument}`);
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
const sourceRoot = join(root, "skill-src/reverse-engineer-anything");
const sourceRoot = join(root, ".agents/skills/reverse-engineer-anything");
const outputRoot = join(root, "skills/reverse-engineer-anything");
const check = arguments_.has("--check");
const current = (
await readFile(join(sourceRoot, "SKILL.md"), "utf8")
).replaceAll("\r\n", "\n");
const cacheBust = String(Date.now());
const { CATALOG_IDENTITY } = await import(
`${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${String(Date.now())}`
`${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${cacheBust}`
);
const { PRODUCT_IDENTITY } = await import(
`${pathToFileURL(join(root, "dist/identity.js")).href}?${cacheBust}`
);
if (/^\s{2}(?:tool_count|catalog_digest):/mu.test(current))
throw new Error(
"Catalog metadata belongs in the generated skill, not skill-src",
"Catalog metadata belongs in the generated skill, not the authored source",
);
const versionLine = /^ {2}version: "[^"\r\n]+"$/mu;
if (!versionLine.test(current))
throw new Error("Missing authored skill version");
const source = current.replace(
versionLine,
`$&\n tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
);
// A shipped skill must run the version it ships with, not whatever `@latest` resolves to.
const latestSpecifier = PRODUCT_IDENTITY.packageSpecifier;
const pinnedSpecifier = PRODUCT_IDENTITY.registrationPackageSpecifier;
const source = current
.replace(
versionLine,
`$&\n tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
)
.replaceAll(latestSpecifier, pinnedSpecifier);
const paths = await filePaths(sourceRoot);
// Rebuild this owned output directory so removed references cannot survive a build.
if (!check) await rm(outputRoot, { recursive: true, force: true });
@@ -0,0 +1,364 @@
import assert from "node:assert/strict";
import { setTimeout as delay } from "node:timers/promises";
import { fileURLToPath } from "node:url";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { CdpConnection } from "../../dist/browser/CdpConnection.js";
import { createBrowserScenarioProvider } from "../../dist/composition/browserScenario.js";
import { browserScenarioSchema } from "../../dist/domain/browserScenario.js";
import { runScenarioCli } from "./browser-scenario-verifier.mjs";
import { requireMcpEvidenceResult } from "./mcp-verifier-results.mjs";
const expected = {
timezone: "Pacific/Honolulu",
locale: "fr-FR",
dpr: 2,
width: 900,
height: 600,
};
const alternate = {
timezone: "UTC",
locale: "en-US",
dpr: 1,
width: 700,
height: 500,
};
const expression = `JSON.stringify({
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
locale: Intl.DateTimeFormat().resolvedOptions().locale,
dpr: devicePixelRatio, width: innerWidth, height: innerHeight
})`;
const environmentScenario = ({ endpoint, targetId, origin, values, run }) =>
browserScenarioSchema.parse({
browser: { mode: "connect", cdp_endpoint: endpoint, target_id: targetId },
start_url: {
url: `${origin}/scenario-environment${run === undefined ? "" : `?run=${run}`}`,
},
environment: {
locale: values.locale,
timezone: values.timezone,
viewport: {
width: values.width,
height: values.height,
device_scale_factor: values.dpr,
},
},
actions:
run === undefined
? [
{
step_id: "refresh",
action: "click",
locator: { kind: "css", selector: "#refresh-environment" },
},
]
: [
{
step_id: `gate_${run}`,
action: "wait_for",
locator: { kind: "css", selector: `#release-${run}` },
state: "attached",
timeout_ms: 30_000,
},
{
step_id: `refresh_${run}`,
action: "click",
locator: { kind: "css", selector: "#refresh-environment" },
},
],
capture: { after_each_step: ["dom"], at_end: ["dom"] },
});
const assertCapture = (capture, values = expected) => {
assert.equal(capture.browser.cleanup, "disconnected-external");
for (const step of capture.steps) {
assert.equal(step.artifacts.dom.state, "captured");
const text = step.artifacts.dom.value.text;
const observed = /<pre id="environment">([^<]+)<\/pre>/u.exec(text);
assert.ok(observed, "DOM omitted the page's actual environment values");
assert.deepEqual(JSON.parse(observed[1]), values);
}
};
/** Verify actual attached-page emulation and restoration across scenario outcomes. */
export async function verifyScenarioEnvironment(endpoint, targetId, origin) {
const targets = await (await fetch(`${endpoint}/json/list`)).json();
const target = targets.find(({ id }) => id === targetId);
assert.ok(target, "External fixture target is missing");
const connection = await CdpConnection.connect(
target.webSocketDebuggerUrl,
"capture_browser_scenario",
);
const readEnvironment = async () => {
const value = await connection.send("Runtime.evaluate", {
expression,
returnByValue: true,
});
assert.equal(value.result.type, "string");
return JSON.parse(value.result.value);
};
const baseline = await readEnvironment();
const scenario = environmentScenario({
endpoint,
targetId,
origin,
values: expected,
});
const assertRestored = async () => {
assert.deepEqual(await readEnvironment(), baseline);
const remaining = await (await fetch(`${endpoint}/json/list`)).json();
assert.ok(remaining.some(({ id }) => id === targetId));
};
try {
assertCapture((await runScenarioCli(scenario)).normalized_result);
await assertRestored();
const transport = new StdioClientTransport({
command: process.execPath,
args: [fileURLToPath(new URL("../rea.mjs", import.meta.url)), "mcp"],
env: process.env,
stderr: "pipe",
});
const client = new Client({
name: "browser-environment-e2e",
version: "1",
});
try {
await client.connect(transport);
const definition = (await client.listTools()).tools.find(
({ name }) => name === "capture_browser_scenario",
);
assert.ok(definition, "Scenario tool is absent from the current catalog");
assertCapture(
requireMcpEvidenceResult(
await client.callTool(
{ name: "capture_browser_scenario", arguments: scenario },
{ toolDefinition: definition },
),
"capture_browser_scenario",
),
);
await verifyConcurrentMcpCapture({
client,
definition,
connection,
endpoint,
targetId,
origin,
readEnvironment,
assertRestored,
});
} finally {
await client.close();
await transport.close();
}
await assertRestored();
const provider = createBrowserScenarioProvider(process.env);
const initializationFailure = await provider.captureScenario({
...scenario,
environment: { ...scenario.environment, timezone: "REA/Invalid" },
});
assert.equal(initializationFailure.ok, false);
await assertRestored();
const waiting = browserScenarioSchema.parse({
...scenario,
actions: [
{
step_id: "missing",
action: "wait_for",
locator: { kind: "css", selector: "#missing-environment-element" },
state: "visible",
timeout_ms: 100,
},
],
});
const actionFailure = await provider.captureScenario(waiting);
assert.equal(actionFailure.ok, true);
assertCapture(actionFailure.value);
assert.equal(actionFailure.value.steps.at(-1).status, "failed");
await assertRestored();
await verifyCancelledEnvironment(
provider,
connection,
waiting,
readEnvironment,
);
await assertRestored();
return {
mocked: false,
cli: true,
stdio_mcp: true,
observed: expected,
restored: baseline,
initialization_failure_cleanup: true,
action_failure_cleanup: true,
cancellation_cleanup: true,
external_target_preserved: true,
};
} finally {
await connection.close();
}
}
const verifyConcurrentMcpCapture = async ({
client,
definition,
connection,
endpoint,
targetId,
origin,
readEnvironment,
assertRestored,
}) => {
const firstScenario = environmentScenario({
endpoint,
targetId,
origin,
values: expected,
run: "A",
});
const secondScenario = environmentScenario({
endpoint,
targetId,
origin,
values: alternate,
run: "B",
});
const firstCancellation = new AbortController();
const secondCancellation = new AbortController();
const cancellation = new AbortController();
const pendingCalls = [];
const callTool = (arguments_, signal) => {
const pending = client.callTool(
{ name: "capture_browser_scenario", arguments: arguments_ },
{ signal, timeout: 60_000, toolDefinition: definition },
);
void pending.catch(() => {});
pendingCalls.push(pending);
return pending;
};
try {
const first = callTool(firstScenario, firstCancellation.signal);
await waitForEnvironment(readEnvironment, connection, expected, "A");
const second = callTool(secondScenario, secondCancellation.signal);
await client.ping();
assert.deepEqual(await readEnvironment(), expected);
assert.equal(await readScenarioRun(connection), "A");
const cancelled = callTool(
environmentScenario({
endpoint,
targetId,
origin,
values: alternate,
run: "C",
}),
cancellation.signal,
);
await client.ping();
cancellation.abort(new Error("cancel queued browser scenario"));
await assert.rejects(cancelled, /cancel queued browser scenario/u);
assert.deepEqual(await readEnvironment(), expected);
assert.equal(await readScenarioRun(connection), "A");
await releaseScenario(connection);
assertCapture(
requireMcpEvidenceResult(await first, "capture_browser_scenario"),
expected,
);
await waitForEnvironment(readEnvironment, connection, alternate, "B");
await releaseScenario(connection);
assertCapture(
requireMcpEvidenceResult(await second, "capture_browser_scenario"),
alternate,
);
await client.ping();
await assertRestored();
} finally {
firstCancellation.abort();
secondCancellation.abort();
cancellation.abort();
await releaseScenario(connection).catch(() => undefined);
await Promise.allSettled(pendingCalls);
}
};
const waitForEnvironment = async (
readEnvironment,
connection,
expectedValues,
run,
) => {
const deadline = Date.now() + 10_000;
while (Date.now() < deadline) {
if (
JSON.stringify(await readEnvironment()) ===
JSON.stringify(expectedValues) &&
(await readScenarioRun(connection)) === run
)
return;
await delay(25);
}
throw new Error(`Scenario ${run} never reached its page-controlled gate`);
};
const readScenarioRun = async (connection) => {
const value = await connection.send("Runtime.evaluate", {
expression: "document.body.dataset.run ?? null",
returnByValue: true,
});
return value.result.value;
};
const releaseScenario = async (connection) => {
await connection.send("Runtime.evaluate", {
expression: "window.releaseScenario()",
returnByValue: true,
});
};
async function verifyCancelledEnvironment(
provider,
connection,
scenario,
readEnvironment,
) {
const controller = new AbortController();
const priorNavigation = await connection.send("Runtime.evaluate", {
expression: "performance.timeOrigin",
returnByValue: true,
});
const pending = provider.captureScenario(
{ ...scenario, actions: [{ ...scenario.actions[0], timeout_ms: 30_000 }] },
{ signal: controller.signal },
);
try {
const deadline = Date.now() + 10_000;
while (true) {
const navigation = await connection.send("Runtime.evaluate", {
expression: "performance.timeOrigin",
returnByValue: true,
});
if (
navigation.result.value !== priorNavigation.result.value &&
JSON.stringify(await readEnvironment()) === JSON.stringify(expected)
)
break;
assert.ok(Date.now() < deadline, "Scenario never applied emulation");
await delay(25);
}
await delay(100);
} finally {
controller.abort();
}
const cancelled = await pending;
assert.ok(
!cancelled.ok ||
cancelled.value.steps.some(({ status }) => status === "cancelled"),
"Cancellation unexpectedly completed every action",
);
}
+12 -3
View File
@@ -209,10 +209,16 @@ export function assertSensitiveShapes(result) {
(item) =>
item.url.includes("/api") &&
item.body_shapes.request?.properties.some(
({ path }) => path === "/token",
({ path }) =>
path.length === 1 &&
path[0].kind === "property" &&
path[0].name === "token",
) &&
item.body_shapes.response?.properties.some(
({ path }) => path === "/secret",
({ path }) =>
path.length === 1 &&
path[0].kind === "property" &&
path[0].name === "secret",
),
);
if (request === undefined)
@@ -244,7 +250,10 @@ export function assertSensitiveShapes(result) {
(event) =>
event.payload_shape?.format === "json" &&
event.payload_shape.json_shape?.properties.some(
({ path }) => path === "/token",
({ path }) =>
path.length === 1 &&
path[0].kind === "property" &&
path[0].name === "token",
),
)
)
+37 -1
View File
@@ -47,6 +47,21 @@ export const toolFamilyCatalog = (sources) => {
surface: "android-provider",
contracts: sources.androidContracts.ANDROID_TOOL_CONTRACTS,
},
{
id: "apktool",
surface: "apktool-provider",
contracts: sources.apktoolContracts.APKTOOL_TOOL_CONTRACTS,
},
{
id: "jeb",
surface: "jeb-provider",
contracts: sources.jebContracts.JEB_TOOL_CONTRACTS,
},
{
id: "adb",
surface: "adb-provider",
contracts: sources.adbContracts.ADB_TOOL_CONTRACTS,
},
{
id: "browser",
surface: "browser-provider",
@@ -153,7 +168,16 @@ export const providerCatalog = (sources) => {
{
identity: sources.pwntoolsProvider.PWNTOOLS_PROVIDER_IDENTITY,
contracts:
sources.binaryDiagnosticsContracts.BINARY_DIAGNOSTICS_TOOL_CONTRACTS,
sources.binaryDiagnosticsContracts.BINARY_DIAGNOSTICS_TOOL_CONTRACTS.filter(
({ name }) => name !== "inspect_pe_resources",
),
},
{
identity: sources.artifactProviders.PE_RESOURCES_PROVIDER,
contracts:
sources.binaryDiagnosticsContracts.BINARY_DIAGNOSTICS_TOOL_CONTRACTS.filter(
({ name }) => name === "inspect_pe_resources",
),
},
{
identity: sources.evmProvider.EVMOLE_PROVIDER_IDENTITY,
@@ -188,6 +212,18 @@ export const providerCatalog = (sources) => {
identity: sources.androidProvider.JADX_PROVIDER_IDENTITY,
contracts: sources.androidContracts.ANDROID_TOOL_CONTRACTS,
},
{
identity: sources.apktoolProvider.APKTOOL_PROVIDER_IDENTITY,
contracts: sources.apktoolContracts.APKTOOL_TOOL_CONTRACTS,
},
{
identity: sources.jebProvider.JEB_PROVIDER_IDENTITY,
contracts: sources.jebContracts.JEB_TOOL_CONTRACTS,
},
{
identity: sources.adbProvider.ADB_PROVIDER_IDENTITY,
contracts: sources.adbContracts.ADB_TOOL_CONTRACTS,
},
{
identity: sources.webNetworkCaptureProvider.HAR_CAPTURE_PROVIDER_IDENTITY,
contracts:
+12
View File
@@ -0,0 +1,12 @@
export function createCliInventory(cli: unknown): {
readonly primary: readonly string[];
readonly aliases: readonly {
readonly name: string;
readonly target: string;
}[];
};
export function cliCommandOptionNames(
cli: unknown,
name: string,
): readonly string[];
export function cliCommandDescriptionIssues(cli: unknown): readonly string[];
+6
View File
@@ -53,6 +53,12 @@ const SOURCE_PATHS = {
firmwareProvider: "dist/firmware/FirmwareRelease.js",
androidContracts: "dist/contracts/android/androidToolContracts.js",
androidProvider: "dist/android/JadxRelease.js",
apktoolContracts: "dist/contracts/apktool/apktoolToolContracts.js",
apktoolProvider: "dist/apktool/ApktoolProvider.js",
jebContracts: "dist/contracts/jeb/jebToolContracts.js",
jebProvider: "dist/jeb/JebProvider.js",
adbContracts: "dist/contracts/adb/adbToolContracts.js",
adbProvider: "dist/adb/AdbProvider.js",
managedWorkflowContracts:
"dist/contracts/managed/managedWorkflowToolContracts.js",
browserContracts: "dist/contracts/browserToolContracts.js",
@@ -51,11 +51,10 @@ export async function verifyLegacyGhidraReferenceSnapshot(
legacyParameters,
);
assert.notEqual(legacyProfile.digest, observed.analysis_profile.digest);
const parsed = await parseBinaryTarget(
target.path,
process.cwd(),
process.arch,
);
const parsed = await parseBinaryTarget(target.path, {
cwd: process.cwd(),
hostArchitecture: process.arch,
});
if (!parsed.ok) throw parsed.error;
const nativeTarget = parsed.value;
const result = structuredClone(observed.normalized_result);
+3
View File
@@ -16,6 +16,9 @@ import { verifyGhidraBoundaries } from "./real-ghidra-boundaries.mjs";
const defaultEntrypoint = fileURLToPath(new URL("../rea.mjs", import.meta.url));
const environment = () => ({
PATH: process.env.PATH ?? "/usr/bin:/bin",
...(process.env.NODE_OPTIONS === undefined
? {}
: { NODE_OPTIONS: process.env.NODE_OPTIONS }),
REA_LOG_LEVEL: "silent",
REA_ANALYSIS_PROVIDER: "ghidra",
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-deep-provider/hopper",
-19
View File
@@ -26,10 +26,6 @@ export interface ProductCatalog {
readonly format: string;
readonly configuration: string;
}[];
readonly schemas: readonly {
readonly id: string;
readonly version: string | number;
}[];
readonly cli: {
readonly primary_count: number;
readonly commands: readonly string[];
@@ -45,21 +41,6 @@ export interface ProductCatalog {
}
export function createProductCatalog(root: string): Promise<ProductCatalog>;
export function providerCatalogDigest(
providers: ProductCatalog["providers"],
): string;
export function createCliInventory(cli: unknown): {
readonly primary: readonly string[];
readonly aliases: readonly {
readonly name: string;
readonly target: string;
}[];
};
export function cliCommandOptionNames(
cli: unknown,
name: string,
): readonly string[];
export function cliCommandDescriptionIssues(cli: unknown): readonly string[];
export function serializeProductCatalog(
catalog: ProductCatalog,
): Promise<string>;
+2 -15
View File
@@ -1,22 +1,9 @@
import { formatGeneratedFile } from "./format-generated-file.mjs";
import { assertSameNames, digest, loadSources } from "./catalog-core.mjs";
import {
createCliInventory,
cliCommandDescriptionIssues,
cliCommandOptionNames,
} from "./catalog-cli.mjs";
import { createCliInventory } from "./catalog-cli.mjs";
import { providerCatalog, toolFamilyCatalog } from "./catalog-builders.mjs";
export {
createCliInventory,
cliCommandDescriptionIssues,
cliCommandOptionNames,
};
/** Return the stable digest for the source-derived provider projection. */
export const providerCatalogDigest = (providers) => digest(providers);
/** Project current runtime contracts into deterministic, machine-readable facts. */
export const createProductCatalog = async (root) => {
const sources = await loadSources(root);
@@ -59,7 +46,7 @@ export const createProductCatalog = async (root) => {
counts: sources.catalogIdentity.CATALOG_IDENTITY.counts,
digests: {
// Full runtime schema digests belong to server identity, not this facts projection.
providers_sha256: providerCatalogDigest(providers),
providers_sha256: digest(providers),
},
},
};
+5 -1
View File
@@ -40,7 +40,11 @@ export async function verifyGhidraBoundaries(
ajv.validateSchema(tool[key]),
`${tool.name} ${key}: ${JSON.stringify(ajv.errors)}`,
);
validators.set(tool.name, ajv.compile(tool.outputSchema));
validators.set(
tool.name,
(tool.outputSchema?.$id && ajv.getSchema(tool.outputSchema.$id)) ||
ajv.compile(tool.outputSchema),
);
}
let successfulCalls = 0;
let rejectedCalls = 0;
@@ -0,0 +1,170 @@
import assert from "node:assert/strict";
/** Verify actual reference facts on the source-owned Windows PE fixture. */
export async function verifyGhidraCompactReferences(call, x86, cli) {
const base = x86 ? 0x400000n : 0x1_4000_0000n;
const address = (offset) => `0x${(base + BigInt(offset)).toString(16)}`;
const cases = [
["data", 0x1020, 0x2000],
["read", x86 ? 0x1025 : 0x1027, 0x2000],
["write", x86 ? 0x102a : 0x102d, 0x2004],
];
const full = await call("procedure_references", {
procedure: address(0x1020),
});
const inspected = {};
for (const [kind, offset, target] of cases) {
const instruction = await call("inspect_native_instruction", {
address: address(offset),
});
inspected[kind] = instruction;
const reference = instruction.references.find(
(item) => item.target_address === address(target),
);
assert.ok(reference, `Missing ${kind} fixture reference`);
assertReference(reference, instruction.address, full.references);
assert.equal(reference.data, true);
assert.equal(reference.read, kind === "read");
assert.equal(reference.write, kind === "write");
}
const indexed = await call("inspect_native_instruction", {
address: address(x86 ? 0x103d : 0x1045),
});
for (const reference of indexed.references)
assertReference(reference, indexed.address, full.references);
assert.ok(
indexed.references.some(
(reference) =>
reference.primary === false && reference.source === "analysis",
),
"Indexed fixture lacks a non-primary analyzer reference",
);
const { direct, targets } = await verifyDirectCall(
call,
address(0x1000),
address(0x1010),
);
const indirectAddress = address(x86 ? 0x1041 : 0x1049);
const indirect = await call("inspect_native_instruction", {
address: indirectAddress,
});
const unresolved = await call("resolve_native_call_targets", {
address: indirectAddress,
});
assert.equal(indirect.flow.kind, "call");
assert.deepEqual(indirect.references, []);
assert.equal(unresolved.status, "unresolved");
assert.deepEqual(unresolved.targets, []);
const returned = await verifyEmptyReferences(
call,
address(x86 ? 0x1043 : 0x104c),
);
if (cli !== undefined) {
for (const instruction of [inspected.write, indexed, direct, returned])
assert.deepEqual(
await cli("inspect-native-instruction", instruction.address),
instruction,
);
assert.deepEqual(
await cli("resolve-native-call-targets", direct.address),
targets,
);
assert.deepEqual(
await cli("resolve-native-call-targets", indirectAddress),
unresolved,
);
}
return {
data_read_write: true,
source_primary_provenance: true,
full_reference_parity: true,
direct_call_reference_parity: true,
indexed_reference_count: indexed.references.length,
indexed_non_primary_count: indexed.references.filter(
(reference) => reference.primary === false,
).length,
indexed_non_primary_analyzer_reference: true,
indexed_reference_kinds: indexed.references.map(
({ type, read, write, primary, source }) => ({
type,
read,
write,
primary,
source,
}),
),
targetless_indirect: true,
empty_and_unavailable: true,
cli_mcp_parity: cli !== undefined,
};
}
async function verifyDirectCall(call, entry, callee) {
const direct = await call("inspect_native_instruction", { address: entry });
const targets = await call("resolve_native_call_targets", { address: entry });
assert.equal(targets.status, "direct");
assert.equal(targets.targets[0].address, callee);
assert.deepEqual(
targets.targets[0].references,
direct.references.filter((item) => item.call),
);
const full = await call("procedure_references", { procedure: entry });
for (const reference of direct.references)
assertReference(reference, entry, full.references);
return { direct, targets };
}
async function verifyEmptyReferences(call, address) {
const returned = await call("inspect_native_instruction", { address });
assert.equal(returned.flow.kind, "return");
assert.deepEqual(returned.references, []);
assert.equal(
(await call("resolve_native_call_targets", { address })).status,
"not-call",
);
const outside = await call("inspect_native_instruction", { address: "0x0" });
assert.equal(outside.status, "outside-memory");
assert.deepEqual(outside.references, []);
assert.equal(
(await call("resolve_native_call_targets", { address: "0x0" })).status,
"unavailable",
);
return returned;
}
function assertReference(reference, source, full) {
assert.equal(reference.source_address, source);
assert.equal(reference.provenance, "ghidra-reference-manager");
assert.equal(typeof reference.primary, "boolean");
assert.equal(typeof reference.source, "string");
assert.ok(reference.source.length > 0);
const edge = full.find(
(item) =>
item.source_address === source &&
item.target_address === reference.target_address &&
item.kind.operand_index === reference.operand_index,
);
assert.ok(edge, "Compact reference lacks its matching full reference");
for (const field of [
"type",
"call",
"jump",
"indirect",
"computed",
"operand_index",
"data",
"read",
"write",
"primary",
"provenance",
])
assert.equal(
reference[field],
edge.kind[field],
`Reference ${field} differs from its full representation`,
);
}
+5 -1
View File
@@ -42,7 +42,11 @@ export async function verifyHopperBoundaryContracts(
ajv.validateSchema(tool.outputSchema),
`${tool.name} output schema`,
);
validators.set(tool.name, ajv.compile(tool.outputSchema));
validators.set(
tool.name,
(tool.outputSchema?.$id && ajv.getSchema(tool.outputSchema.$id)) ||
ajv.compile(tool.outputSchema),
);
}
let successfulCalls = 0;
let rejectedCalls = 0;
+39 -6
View File
@@ -58,6 +58,12 @@ async function verifyNavigation(
procedure: address,
});
const info = await call("procedure_info", { procedure: address });
assert.equal(info.classification, null);
assert.equal(info.body.available, false);
assert.match(
info.body.reason,
/public Python API does not expose complete function body ranges/u,
);
assert.ok(info.locals.length > 0, "fixture omitted real stack locals");
for (const local of info.locals) {
assert.equal(typeof local.name, "string");
@@ -68,19 +74,46 @@ async function verifyNavigation(
}
const dossier = await call("analyze_function", { procedure: address });
assert.deepEqual(dossier.procedure.locals, info.locals);
assert.equal(dossier.procedure.classification, null);
assert.equal(dossier.procedure.body.available, false);
assert.match(
dossier.procedure.body.reason,
/public Python API does not expose complete function body ranges/u,
);
assert.equal(dossier.native_api, null);
assert.equal(dossier.native_value_flow, null);
assert.ok(
Array.isArray(dossier.limitations) && dossier.limitations.length > 0,
"function dossier omitted Hopper's unsupported-facet limitations",
);
const coordinates = instructions.instructions.map(
(line) => /^0x[0-9a-f]+/u.exec(line)?.[0],
);
assert.equal(coordinates[0], address);
assert.ok(coordinates[1], "fixture omitted a second instruction");
const interior = `0x${(BigInt(address) + 1n).toString(16)}`;
assert.equal(await call("goto_address", { address: interior }), address);
assert.equal(await call("current_address"), address);
// The host toolchain controls the prologue encoding: without endbr64-style
// padding the first instruction is one byte, so address + 1 is itself an
// instruction boundary. Probe from inside the first multi-byte instruction
// so the interior coordinate is never an analyzed-object boundary.
let anchor = 0;
while (anchor + 1 < coordinates.length) {
if (BigInt(coordinates[anchor + 1]) - BigInt(coordinates[anchor]) > 1n)
break;
anchor += 1;
}
assert.ok(
anchor + 1 < coordinates.length,
"fixture omitted a multi-byte instruction for interior navigation",
);
const containing = coordinates[anchor];
const interior = `0x${(BigInt(containing) + 1n).toString(16)}`;
assert.equal(await call("goto_address", { address: interior }), containing);
assert.equal(await call("current_address"), containing);
assert.equal(
await call("next_address", { address: interior }),
coordinates[1],
coordinates[anchor + 1],
);
assert.equal(await call("prev_address", { address: interior }), address);
assert.equal(await call("prev_address", { address: interior }), containing);
for (const unmapped of ["0x0", "0xfffffffffffffffe"]) {
for (const operation of ["goto_address", "next_address", "prev_address"])
await invalid(
@@ -88,7 +121,7 @@ async function verifyNavigation(
{ address: unmapped },
/Address is outside every segment/u,
);
assert.equal(await call("current_address"), address);
assert.equal(await call("current_address"), containing);
for (const operation of [
"set_address_name",
"set_bookmark",
+25 -3
View File
@@ -11,15 +11,28 @@ export const requireTruthfulMemoryRegions = (segments) => {
...(Array.isArray(segment.sections) ? segment.sections : []),
]);
for (const region of regions) {
if (
typeof region?.name !== "string" ||
region.name.length === 0 ||
typeof region.start !== "string" ||
typeof region.end !== "string"
) {
throw new Error(
"list_segments omitted observed region identity or bounds",
);
}
for (const permission of ["readable", "writable", "executable"]) {
if (![true, false, null].includes(region?.[permission])) {
throw new Error(`list_segments omitted tri-state ${permission}`);
if (region[permission] !== null) {
throw new Error(
`list_segments invented or omitted unknown ${permission}`,
);
}
}
if (
region.provenance !== "hopper-public-python-api" ||
region.permissions?.available !== false ||
typeof region.permissions.reason !== "string"
typeof region.permissions.reason !== "string" ||
region.permissions.reason.length === 0
) {
throw new Error("list_segments omitted permission provenance");
}
@@ -141,6 +154,15 @@ export async function verifyRealHopperFixture({
"procedure_references",
);
assert.deepEqual(entryDossier.unresolved_calls, observed.unresolved_calls);
assert.equal(
observed.reference_kinds_available,
false,
"Hopper's partial CallReference observations do not expose detailed reference kinds",
);
assert.ok(
Array.isArray(observed.unresolved_calls),
"procedure_references omitted its observed unresolved CallReference results",
);
for (const call of calls) {
assert.equal(call.call.provider_type, 2);
assert.equal(
-29
View File
@@ -69,32 +69,3 @@ export const pathExists = async (path) => {
throw cause;
}
};
/** Synthetic function dossier for managed/native verification fixtures. */
export const functionDossier = (name) => {
return {
procedure: {
address: "0x401000",
name,
classification: {
external: false,
thunk: false,
thunk_target: null,
provenance: "synthetic-provider",
},
signature: null,
locals: [],
},
pseudocode: "",
assembly: [],
comments: [],
callers: [],
callees: [],
incoming_references: [],
outgoing_references: [],
referenced_strings: [],
referenced_names: [],
basic_blocks: [],
limitations: [],
};
};

Some files were not shown because too many files have changed in this diff Show More