Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c4d871803 | ||
|
|
9750486e78 | ||
|
|
4232399079 | ||
|
|
26e155987f | ||
|
|
69a2faa120 | ||
|
|
bffe8a52a1 | ||
|
|
4ed33efb0c | ||
|
|
75e0d620bf | ||
|
|
4c680d099c | ||
|
|
046ec56d16 | ||
|
|
e9b21aadc5 | ||
|
|
f62a2baad8 | ||
|
|
c8269ca497 | ||
|
|
cb26e8ca63 | ||
|
|
d23dc5d188 | ||
|
|
e97f47b0b7 | ||
|
|
f3ed1657f8 | ||
|
|
ab720b4216 | ||
|
|
bb17e90f27 | ||
|
|
627c085cee | ||
|
|
5938581b37 | ||
|
|
fdf5a33fe2 | ||
|
|
be698d4761 | ||
|
|
760d9f6019 | ||
|
|
42c16ba631 | ||
|
|
76afdd35ae | ||
|
|
ed86f9c3bb | ||
|
|
475f09d5ca | ||
|
|
f2fa951c00 | ||
|
|
9140deae63 | ||
|
|
efab65c2f9 | ||
|
|
07eb044f77 | ||
|
|
238914974d | ||
|
|
1ff275fbf7 | ||
|
|
6bcd243ca4 | ||
|
|
aba487eec0 | ||
|
|
ae54b96c6f | ||
|
|
599099f656 | ||
|
|
9548953b47 | ||
|
|
d24ad4f55d | ||
|
|
4b045e8f2f | ||
|
|
10b83a9b62 | ||
|
|
38719a6fa9 | ||
|
|
58fb824105 | ||
|
|
835904e4ee | ||
|
|
5ea2c280b8 | ||
|
|
aced9fa9b4 | ||
|
|
149b43ee61 | ||
|
|
22b88300d0 | ||
|
|
162bd56c9e | ||
|
|
a891bb80ae | ||
|
|
f196ebf806 | ||
|
|
c7ae27807f | ||
|
|
2acdd54130 | ||
|
|
f4f7c75c66 | ||
|
|
a5bfd04401 | ||
|
|
ce4e48ccae | ||
|
|
6a96f4fa4a | ||
|
|
0354759370 | ||
|
|
8dfc6832a4 | ||
|
|
7fe5e5ff5e | ||
|
|
03ed0c63d9 | ||
|
|
a834ed1cab | ||
|
|
425776174c | ||
|
|
31fc9762a3 | ||
|
|
faf219e90b | ||
|
|
3f168af2e8 | ||
|
|
92f32981da | ||
|
|
9b3a633298 | ||
|
|
955c7c80ec | ||
|
|
fcebd79ed8 | ||
|
|
85bc8c8977 | ||
|
|
1ca7d38764 | ||
|
|
ed79bf9361 | ||
|
|
08b8e62914 | ||
|
|
9a13c4f420 | ||
|
|
bc9efc9279 | ||
|
|
ab30df08f7 | ||
|
|
403fef0d40 | ||
|
|
de37dfbcc9 | ||
|
|
535926ca2b | ||
|
|
84c30609e1 | ||
|
|
8b57dc630e | ||
|
|
12f6e0974c | ||
|
|
900f21b982 | ||
|
|
97194c4b48 | ||
|
|
a1967fbbdb | ||
|
|
422ca5a8f8 | ||
|
|
397aa62f2e | ||
|
|
41cf869949 | ||
|
|
c94bd27e85 | ||
|
|
d9189aebc4 | ||
|
|
72e75e9a48 | ||
|
|
e9abf39848 | ||
|
|
cc7cc8155a | ||
|
|
8c6cddcffb | ||
|
|
798450638e | ||
|
|
731109b7d7 | ||
|
|
399e2226ca | ||
|
|
1184819cb9 | ||
|
|
bff03bfc97 | ||
|
|
4f212c6a30 | ||
|
|
69f99c5198 | ||
|
|
b4ba96a9a5 | ||
|
|
7e57b8c212 | ||
|
|
dba8a31978 | ||
|
|
de088fcec6 | ||
|
|
48ff37f6ea | ||
|
|
791524c2fa | ||
|
|
c6a2576aba | ||
|
|
3d84215bb2 | ||
|
|
02e049744f | ||
|
|
d361c53c50 | ||
|
|
347b6e4d95 | ||
|
|
2e86294c86 | ||
|
|
73320bb2c9 | ||
|
|
2250e67bc2 | ||
|
|
cd1878f3fe | ||
|
|
be2811e414 | ||
|
|
0402012a95 | ||
|
|
9895f1870c | ||
|
|
dd02d8ff69 | ||
|
|
b22b0ef22a | ||
|
|
89006609f1 | ||
|
|
cab78de506 | ||
|
|
d01ee7b19a | ||
|
|
ddde7276c4 | ||
|
|
48c203f356 | ||
|
|
18451e4797 | ||
|
|
df5c48ffda | ||
|
|
9dfa44f776 | ||
|
|
3fb26985c4 | ||
|
|
af3f025688 | ||
|
|
43c7255dbd | ||
|
|
a45ee81167 | ||
|
|
f2fa7f648d | ||
|
|
d9660eb032 | ||
|
|
de9a8898dc | ||
|
|
e3a6ce40f5 | ||
|
|
3ce311757d | ||
|
|
c350343c33 | ||
|
|
2c3568c375 | ||
|
|
c298d54e88 | ||
|
|
b09c6b0752 | ||
|
|
689f738c95 | ||
|
|
8328a9559f | ||
|
|
77be87db99 | ||
|
|
0c49878b9a | ||
|
|
abf7d300b3 | ||
|
|
0f3a15de0d | ||
|
|
781760a195 | ||
|
|
977c9727e6 | ||
|
|
4a041ae753 | ||
|
|
c2068b94d7 | ||
|
|
e00ee310f5 | ||
|
|
72ba1cd92b | ||
|
|
98ec00f406 | ||
|
|
bdf15b9bd5 | ||
|
|
d68d03e88f | ||
|
|
d87e73f2db | ||
|
|
b5c42dfc2a | ||
|
|
b869fa762a | ||
|
|
21a20306b4 | ||
|
|
f774dc420b | ||
|
|
e5965adb29 | ||
|
|
ace47789a8 | ||
|
|
60242ec82d | ||
|
|
1d896e03b7 | ||
|
|
915e56e3e5 | ||
|
|
850abe5e6f | ||
|
|
ddfd060210 | ||
|
|
aa9043f6b6 | ||
|
|
6843dbea9b | ||
|
|
21097b192b | ||
|
|
f9fabdfcb2 | ||
|
|
ead9fdcda9 | ||
|
|
c2caae88f8 | ||
|
|
3ad465a666 | ||
|
|
4ef916da03 | ||
|
|
f508a1a47e | ||
|
|
f2eb27206f | ||
|
|
39aca92239 | ||
|
|
ae24b7879c | ||
|
|
dd198d037f | ||
|
|
8736fe3226 | ||
|
|
0f411508c3 | ||
|
|
fbe77dc479 | ||
|
|
ba6cec31f5 | ||
|
|
1564fc8d9b | ||
|
|
41e10b240c | ||
|
|
d662fa54a6 | ||
|
|
008931a178 | ||
|
|
cd10ee1f8a | ||
|
|
80b7bbc8bd | ||
|
|
f3269feaad | ||
|
|
cad14f3b35 | ||
|
|
7f70797b98 | ||
|
|
9f5dd56e2f | ||
|
|
2bd981b017 | ||
|
|
6021efd371 | ||
|
|
7958e15892 | ||
|
|
e09b06369d | ||
|
|
bd1b2c74ae | ||
|
|
e2463372ea | ||
|
|
315b23403f | ||
|
|
cc18e9ad0d | ||
|
|
2f2b07f750 | ||
|
|
37f24125ad | ||
|
|
263a98c6ce | ||
|
|
6298c84eea | ||
|
|
9df94a62cd | ||
|
|
2968d1e932 | ||
|
|
fb9f35cf7b | ||
|
|
584120e802 | ||
|
|
254f9d9ea2 | ||
|
|
044c9705ea | ||
|
|
3da7454ed8 | ||
|
|
f975f98ef4 | ||
|
|
85e38ac199 | ||
|
|
33f384120a | ||
|
|
7eaa7920a7 | ||
|
|
9c8f404421 | ||
|
|
959ab0c10b | ||
|
|
06822aed63 | ||
|
|
96ad94f69e | ||
|
|
676d29f9ee | ||
|
|
87745af52a | ||
|
|
b6519aa410 | ||
|
|
8defd220a9 | ||
|
|
3ae7daa101 | ||
|
|
3d3ee837c4 | ||
|
|
54f5c55f62 | ||
|
|
eea3271a33 | ||
|
|
31de177404 | ||
|
|
45d0c3e299 | ||
|
|
673a659074 | ||
|
|
1d2b26e2d5 | ||
|
|
446333cb7f | ||
|
|
d81d6b6707 | ||
|
|
54646e8dc4 | ||
|
|
8681752c7b | ||
|
|
9adc61243b | ||
|
|
09c2a2d241 | ||
|
|
f1dc595272 | ||
|
|
0ee3a35bd0 | ||
|
|
a417209080 | ||
|
|
06bafdef14 | ||
|
|
3c0b26df67 | ||
|
|
9d4293be27 | ||
|
|
1c07bee5b6 | ||
|
|
e8b2273ab6 | ||
|
|
b7c1d79da3 | ||
|
|
c765b3b413 | ||
|
|
f2dfda4b36 | ||
|
|
e6f252509f | ||
|
|
6ed96f4372 | ||
|
|
2ff85c0e4c | ||
|
|
0ba81bd9e4 | ||
|
|
3e6ac23b50 | ||
|
|
aeeb4b72c1 | ||
|
|
4394e8b592 | ||
|
|
eb721ebbf1 | ||
|
|
d3a33fcfca | ||
|
|
5502a563d5 | ||
|
|
be2a0b98ae | ||
|
|
fcd5192743 | ||
|
|
d442ac752e | ||
|
|
5940600a22 | ||
|
|
c2455152c9 | ||
|
|
4643844ea5 | ||
|
|
2496256cb7 | ||
|
|
cc4f805541 | ||
|
|
27976a8fcb | ||
|
|
67d02f4787 | ||
|
|
662e79330f | ||
|
|
04ba5caf63 | ||
|
|
c010fafe45 | ||
|
|
0de322eb91 | ||
|
|
4f6166e04d | ||
|
|
d421e3eeef | ||
|
|
36f26a1bfe | ||
|
|
a4e4863029 | ||
|
|
64f261bc6f | ||
|
|
48821e82a1 | ||
|
|
d1585fc600 | ||
|
|
4118004348 | ||
|
|
934f538f64 | ||
|
|
002f9df43a | ||
|
|
7f3e32c69b | ||
|
|
4becc220b8 | ||
|
|
9d569c344a | ||
|
|
800454c0ee | ||
|
|
5c5f8e7cc4 | ||
|
|
c6104d5095 | ||
|
|
396dcb2b0f | ||
|
|
4d22c83b07 | ||
|
|
de9d52cb5d | ||
|
|
1be8e9601b | ||
|
|
9a165287ad | ||
|
|
455f816d0b | ||
|
|
46a5f55f74 | ||
|
|
f42ade1dda | ||
|
|
7c88ef14af | ||
|
|
11feab01da | ||
|
|
6323013d83 | ||
|
|
07005b8fe6 | ||
|
|
59553c76be | ||
|
|
c3ad8fc024 | ||
|
|
54a663ddd5 | ||
|
|
e389d6ea4e | ||
|
|
4d88e4f07e | ||
|
|
1a48a82020 | ||
|
|
bf6e49a8f4 | ||
|
|
76500f12b5 | ||
|
|
64fa1db130 | ||
|
|
79805f244a | ||
|
|
f90d40720f |
No files matched your search
@@ -1,8 +1,8 @@
|
||||
---
|
||||
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.
|
||||
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA, and build agent environments (AgentEnv bundles) of web applications from a live instance or a capture. 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: "46"
|
||||
version: "49"
|
||||
---
|
||||
|
||||
# REA
|
||||
@@ -133,6 +133,9 @@ explicit path or endpoint and do not need it.
|
||||
`capture_browser_scenario` with declared actions. See
|
||||
[runtime observation](references/runtime-observation.md) for connect/launch
|
||||
and the focused follow-up browser tools.
|
||||
- Agent environment (AgentEnv bundle) of a web application: read
|
||||
[environments](references/environments.md) before recording; it records with
|
||||
`capture_browser_scenario` and writes the bundle with `export_environment_bundle`.
|
||||
- Fiddler Everywhere traffic or a native `.saz` capture: read the
|
||||
[Fiddler workflow](references/runtime-observation.md#fiddler-everywhere-traffic-debugging).
|
||||
Inspect saved SAZ with `inspect_web_network_capture` and `format: "saz"`;
|
||||
@@ -251,12 +254,46 @@ explicit path or endpoint and do not need it.
|
||||
absence of that table, not proof the image is unsigned in every catalog sense.
|
||||
Signatures are not verified. See the
|
||||
[PE certificate guide](https://github.com/morluto/rea/blob/main/docs/pe-certificates.md).
|
||||
- PE import and delay-load tables: `inspect_pe_imports` with the explicit
|
||||
local PE32/PE32+ file. This built-in target-free inspection requires no
|
||||
Windows SDK. Preserve DLL names, named and ordinal functions, ILT/IAT RVAs,
|
||||
delay-load descriptors, and the pefile import hash of the standard import
|
||||
table. A missing import directory is observed absence of that table, not
|
||||
proof the image never imported APIs through another table. Bound snapshots
|
||||
and loaded IAT contents remain unobserved. See the
|
||||
[PE import guide](https://github.com/morluto/rea/blob/main/docs/pe-imports.md).
|
||||
- PE TLS callbacks and load configuration: `inspect_pe_load_config` with the
|
||||
explicit local PE32/PE32+ file. This built-in target-free inspection requires
|
||||
no Windows SDK. Preserve callback VAs as strings with their RVA, file offset
|
||||
and section, and the size-covered security cookie, SafeSEH, CFG,
|
||||
EH-continuation and XFG fields. Guard-flag mitigation claims are inferred
|
||||
linker declarations, not proof of enforcement. A missing directory is observed
|
||||
absence of that declaration. See the
|
||||
[PE load configuration guide](https://github.com/morluto/rea/blob/main/docs/pe-load-config.md).
|
||||
- ELF note tables: `inspect_elf_notes` with the explicit local ELF32/ELF64
|
||||
file. This built-in target-free inspection requires no disassembler. Preserve
|
||||
PT_NOTE and SHT_NOTE ranges, owners, types, descriptor SHA-256, and GNU
|
||||
build-id or ABI-tag fields. A missing table is observed absence of those
|
||||
declarations, not proof the image never carried notes. See the
|
||||
[ELF notes guide](https://github.com/morluto/rea/blob/main/docs/elf-notes.md).
|
||||
- Apple `.ips` crash reports: `inspect_apple_ips` with the explicit local
|
||||
file. This built-in target-free inspection requires no Xcode, atos, or
|
||||
pwntools. Preserve first-line metadata, `bug_type` as a string, process and
|
||||
exception facts, lossless integer registers, usedImages UUIDs, and
|
||||
documented classification matches. Only `bug_type` `"309"` yields a crash
|
||||
body; other types, including `"288"` stackshots, return no crash result.
|
||||
Opened Mach-O and dSYM UUID joins remain unobserved. See the
|
||||
[Apple IPS guide](https://github.com/morluto/rea/blob/main/docs/apple-ips.md).
|
||||
- Linux kernel module metadata: `inspect_kernel_module` with the explicit local
|
||||
ELF32/ELF64 relocatable file. This built-in target-free inspection requires
|
||||
no Linux host or `modinfo`. Preserve `.modinfo` key order and duplicate keys,
|
||||
`__versions` CRC hex, section file ranges, and the appended signature
|
||||
trailer's PKCS#7 SHA-256. A missing section is observed absence when section
|
||||
names are known, not proof the module never carried that metadata.
|
||||
`struct module` is not decoded. The signature is not validated. gzip, xz, and
|
||||
zstd containers are unsupported; decompress into a separate file with an
|
||||
external codec utility, then inspect the decompressed `ET_REL` image. See the
|
||||
[kernel module guide](https://github.com/morluto/rea/blob/main/docs/kernel-modules.md).
|
||||
- CPython 3.7–3.13 `.pyc` header, nested marshal code objects and bytecode
|
||||
identity: `inspect_python_pyc` with the explicit local file. This built-in
|
||||
target-free inspection requires no Python installation. Preserve magic,
|
||||
@@ -267,8 +304,10 @@ explicit path or endpoint and do not need it.
|
||||
- Erlang BEAM IFF container: `inspect_erlang_beam` with the explicit local
|
||||
`.beam` file. This built-in target-free inspection requires no Erlang
|
||||
installation. Preserve chunk names, atom order, export/import/lambda tables,
|
||||
and the Code header. Missing optional tables stay null. Bytecode is not
|
||||
executed. See the
|
||||
and the Code header. For selected facts, prefer `detail: "summary"` plus a
|
||||
`beam` view (collection, names/indices, fields and paging), retaining the full
|
||||
Evidence. CLI summary requires `--evidence_output`. Missing table counts stay
|
||||
null; decoded empty tables count zero. Bytecode is not executed. See the
|
||||
[Erlang BEAM guide](https://github.com/morluto/rea/blob/main/docs/erlang-beam.md).
|
||||
|
||||
- Explicit local SQLite database snapshot: `inspect_sqlite_database`. Inspect
|
||||
@@ -345,8 +384,9 @@ selected provider. Do not treat those scopes as interchangeable.
|
||||
For a Ghidra startup timeout on a large native target, follow
|
||||
[deadline recovery](references/native-and-artifacts.md#ghidra-startup-deadline-recovery)
|
||||
before abandoning deep analysis or repeating the same cold import. The default
|
||||
330 seconds is configurable; changing the server's environment requires a new
|
||||
REA process.
|
||||
330 seconds can be changed for new startup attempts through
|
||||
`update_analysis_settings` using `ghidra.startup_timeout_ms`. Changing the
|
||||
server's launch environment instead requires a new REA process.
|
||||
|
||||
## Work summary-first
|
||||
|
||||
@@ -354,7 +394,13 @@ 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`.
|
||||
`inspect_analysis_view`. Over MCP, `analyze_function` is summary-first without
|
||||
a flag: its default reply is the summary, and the complete dossier stays
|
||||
retained under `parent_evidence_id` for facet paging. Pass that ID as a
|
||||
`retained-evidence` reference to `compare_functions`, or inside
|
||||
`match_native_functions` `left_observations`/`right_observations`; request
|
||||
`"detail": "complete"` only when the dossier must travel inline, as
|
||||
`build_call_path` requires.
|
||||
Page module identities and select the returned `node_id` before requesting an
|
||||
item; a single file path can represent several graph roles. Do not repeat an
|
||||
identical analysis or rejected call without a changed input or resolved blocker.
|
||||
@@ -447,6 +493,9 @@ as complete while required questions remain open.
|
||||
[references/runtime-observation.md](references/runtime-observation.md)
|
||||
- Evidence paging, comparisons, residual unknowns, and verification:
|
||||
[references/evidence-workflows.md](references/evidence-workflows.md)
|
||||
- Agent environments (AgentEnv bundles) of a web application, recorded from
|
||||
a live instance or a HAR:
|
||||
[references/environments.md](references/environments.md)
|
||||
|
||||
## Finish the task
|
||||
|
||||
|
||||
@@ -28,8 +28,11 @@ stdio. A full JDK, including `jdk.compiler`, is required on every host; Windows
|
||||
verification coverage. Calls use one worker and provider deadlines; optional
|
||||
`REA_JADX_HEAP_MIB` selects the JVM heap and `REA_JADX_OPERATION_TIMEOUT_MS`
|
||||
the per-operation deadline (integer milliseconds from 1 to 2147483647, default
|
||||
120000; a change applies on the next process start; the MCP client's tool
|
||||
timeout must also allow it). The APK is never launched,
|
||||
120000). To change that deadline on a running MCP server, set
|
||||
`jadx.operation_timeout_ms` through `update_analysis_settings`, then retry after
|
||||
work and cleanup settle. Newly accepted operations use the override; accepted
|
||||
work keeps its budget. Changing the launch environment requires a new process.
|
||||
The MCP client's tool timeout must also allow the selected deadline. The APK is never launched,
|
||||
and no emulator is required.
|
||||
|
||||
Manifest entries and decompiled text are static observations, not execution or
|
||||
|
||||
@@ -128,7 +128,7 @@ rea setup --client codex --dry-run --json
|
||||
Use the current supported client's ID: `claude_code`, `claude_desktop`, `codex`,
|
||||
`cursor`, `gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`,
|
||||
`copilot_cli`, `commandcode`, `qwen_code`, `vscode`, `trae`, `grok_build`, `omp`, `pi`,
|
||||
`hermes`, `qoder`, `droid`, `zcode`, `dsh`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
|
||||
`hermes`, `qoder`, `droid`, `zcode`, `dsh`, `freebuff`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
|
||||
scope. `grok_bot` uses a chat registration step rather than local `mcp.json`.
|
||||
For unsupported clients, use version-pinned manual stdio registration or CLI.
|
||||
|
||||
@@ -175,6 +175,17 @@ writing. Managed policy can constrain client settings. Consult the
|
||||
for the installed client's supported settings. This is an optional recovery
|
||||
choice, not a prerequisite for every REA task.
|
||||
|
||||
## Repair an editable REA limit
|
||||
|
||||
If `details.limit` names an editable setting and its bounds, call
|
||||
`update_analysis_settings` directly with a `changes` entry containing `setting`,
|
||||
`action: "set"` and `value`. `inspect_analysis_settings` is optional when those
|
||||
facts are already present. Retry the same input after work and cleanup settle.
|
||||
Runtime defaults affect new work only; explicit per-call arguments take
|
||||
precedence and must be corrected directly when selected. Reset restores launch
|
||||
values. Updates survive target close/open but disappear on REA restart. They do
|
||||
not edit host deadlines, response buffers, registrations or fixed limits.
|
||||
|
||||
## Continue through an installed CLI
|
||||
|
||||
Check the command environment only if the launcher fails:
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# Agent environments from a live application
|
||||
|
||||
Use this when the user asks for an agent environment (an AgentEnv bundle) of a
|
||||
web application: a folder `agent-env` deploys, whose MCP tools answer from what
|
||||
one recording of the application observed and serve the writes that recording
|
||||
confirmed. The workflow records the application once with
|
||||
`capture_browser_scenario`, checks what the environment would serve, records
|
||||
again if a hint names a gap, then writes the bundle with
|
||||
`export_environment_bundle`. For a HAR the user already has, skip to
|
||||
[export](#export-and-hand-off) through `inspect_web_network_capture`, or use
|
||||
`rea environment-build <capture.har> <dir>`.
|
||||
|
||||
## Before recording
|
||||
|
||||
- Record only against an instance the user says is disposable or seeded for
|
||||
this purpose: every write step creates, edits or deletes its data. If the
|
||||
user has not said so, ask before any scenario that writes. REA does not
|
||||
start, seed or reset applications.
|
||||
- Credentials come from environment variables the user names. Declare each as a
|
||||
scenario secret, `{secret_id, environment_variable}`; the variable must be set
|
||||
in the environment REA's MCP server started with. Never ask for a password in
|
||||
chat. Declared secrets are redacted as the capture records.
|
||||
- Map the application first with `inspect_web_page` (and `capture_web_screenshot`
|
||||
when layout matters): the login form's locators, and the API calls behind the
|
||||
pages that list and edit the entities the user asked about.
|
||||
|
||||
## Record a session an environment can learn writes from
|
||||
|
||||
One `capture_browser_scenario` records the whole session. Start from this
|
||||
shape, with the application's own locators, paths and headers:
|
||||
|
||||
```json
|
||||
{
|
||||
"browser": { "mode": "launch", "executable_path": "/usr/bin/chromium" },
|
||||
"start_url": { "url": "http://127.0.0.1:3000/login" },
|
||||
"secrets": [
|
||||
{ "secret_id": "admin_password", "environment_variable": "APP_PASSWORD" }
|
||||
],
|
||||
"capture": {
|
||||
"network": {
|
||||
"request_body": true,
|
||||
"response_body": true,
|
||||
"header_values": true
|
||||
}
|
||||
},
|
||||
"actions": [
|
||||
{
|
||||
"step_id": "user",
|
||||
"action": "fill",
|
||||
"timeout_ms": 15000,
|
||||
"locator": { "kind": "css", "selector": "input[name=username]" },
|
||||
"value": { "source": "literal", "value": "admin" }
|
||||
},
|
||||
{
|
||||
"step_id": "password",
|
||||
"action": "fill",
|
||||
"timeout_ms": 15000,
|
||||
"locator": { "kind": "css", "selector": "input[name=password]" },
|
||||
"value": { "source": "secret", "secret_id": "admin_password" }
|
||||
},
|
||||
{
|
||||
"step_id": "sign-in",
|
||||
"action": "press",
|
||||
"timeout_ms": 15000,
|
||||
"locator": { "kind": "css", "selector": "input[name=password]" },
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"step_id": "signed-in",
|
||||
"action": "wait_for",
|
||||
"timeout_ms": 15000,
|
||||
"locator": { "kind": "css", "selector": "nav a[href='/settings']" },
|
||||
"state": "visible"
|
||||
},
|
||||
{
|
||||
"step_id": "folders-1",
|
||||
"action": "request",
|
||||
"timeout_ms": 15000,
|
||||
"method": "GET",
|
||||
"path": "/api/folders",
|
||||
"expected_status": [200]
|
||||
},
|
||||
{
|
||||
"step_id": "create-folder-1",
|
||||
"action": "request",
|
||||
"timeout_ms": 15000,
|
||||
"method": "POST",
|
||||
"path": "/api/folders",
|
||||
"json": { "title": "Scratch folder 1" },
|
||||
"headers": [
|
||||
{
|
||||
"name": "X-CSRFToken",
|
||||
"value": { "source": "cookie", "name": "csrftoken" }
|
||||
}
|
||||
],
|
||||
"expected_status": [200, 201]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Give every step a `timeout_ms`. A step without one waits until the scenario
|
||||
is cancelled, so a locator that never matches hangs the capture, and the
|
||||
client with it. Match `wait_for` locators to exactly one element.
|
||||
|
||||
1. Sign in through the UI: `fill` the user and password fields (the password
|
||||
as a secret reference), submit, then `wait_for` an element only a signed-in
|
||||
user sees.
|
||||
2. Read with `request` steps: each collection the environment needs, twice
|
||||
before any write, so fields that change on their own show up; one item of
|
||||
each.
|
||||
3. Use `request` steps only when the API lets the caller choose each scratch
|
||||
object's ID or a prior read already established it. Request paths are fixed
|
||||
strings; no action substitutes a value from an earlier response. For
|
||||
server-assigned IDs, create through the UI and open the new object's detail
|
||||
view to record its read, edit and delete through UI actions. If that journey
|
||||
cannot be scripted, leave the write unserved and report the limitation;
|
||||
never guess an ID or create objects with no supported cleanup path.
|
||||
Record two numbered scratch objects per write type,
|
||||
with varied free text. After each write, and before the next one, read the
|
||||
object back by id and then its list: create 1, read 1, list, create 2,
|
||||
read 2, list; never several writes before their reads.
|
||||
4. Leave more than a second between a create and its first edit
|
||||
(`wait_for_timeout` with `duration_ms: 1100`).
|
||||
5. Update both objects and read each back; delete both and read each back
|
||||
(expect 404) and the list.
|
||||
|
||||
About `request` steps:
|
||||
|
||||
- `path` is on the start URL's origin; the page must be on that origin.
|
||||
- Header values are literals, declared secrets, a cookie the browser holds
|
||||
(`{source: "cookie", name}`), or a local storage entry
|
||||
(`{source: "local_storage", key, json_pointer}`), with an optional
|
||||
`prefix` such as `"Bearer "`. Copy the headers the application's own
|
||||
requests send (a CSRF header, a bearer token). Values read from the page
|
||||
are redacted from records made after they are read, not from the login
|
||||
response that returned them, and values shorter than 8 characters are not
|
||||
redacted at all.
|
||||
- Reading a page value makes later bodies costlier to keep: after a CSRF
|
||||
token, bodies over about 47 KiB are kept as `unavailable`. When the API
|
||||
returns larger responses, raise `capture.limits`
|
||||
(`max_network_body_allocation_bytes`, `max_total_event_allocation_bytes`).
|
||||
- Request steps follow no redirects: a redirect fails the step, and
|
||||
`expected_status` cannot name a 3xx status. Use the path the redirect names,
|
||||
such as the one with the trailing slash.
|
||||
- Set `expected_status` on every step, so a refused call fails its step and
|
||||
the later steps report not having run, instead of recording read-backs of
|
||||
nothing.
|
||||
|
||||
Keep it to about 60 to 160 requests. A scenario with no `request` step is
|
||||
recorded exactly as before.
|
||||
|
||||
The capture returns its whole Evidence, every recorded body included, which is
|
||||
often more than a client shows inline. Before checking coverage, confirm that
|
||||
every entry of `normalized_result.steps` has `status: "completed"`; if the
|
||||
client saved the result to a file, search it for `"status":"failed"` and read
|
||||
that step's `error`. A failed sign-in or write cancels every step after it.
|
||||
Use the result's `evidence_id` for coverage and export; do not paste the
|
||||
Evidence back into another tool.
|
||||
|
||||
## Check coverage
|
||||
|
||||
`inspect_analysis_view` with `source: {kind: "retained-evidence",
|
||||
evidence_id}` (the capture's id) and `view: {kind: "environment-coverage",
|
||||
template_rules: ["after-uid-literal", "opaque-token", "sibling-variance",
|
||||
"prefix-variance"]}`. It reports read tools
|
||||
answered from the state or replayed (`reads.recorded_reasons`), the served write
|
||||
tools, and each withheld write with its `reason` and `hint`. It does not apply
|
||||
the serve-time catalog and state size checks; the export reports those.
|
||||
|
||||
Re-record a withheld write at most twice, and only for a recording gap. Stop at
|
||||
once when the reason is application behaviour, and report the write as
|
||||
withheld with its hint:
|
||||
|
||||
| Reason | What to do |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| `no-state-target` | Re-record: read the collection or item the write changes. |
|
||||
| `no-observation` | Re-record: read the entity back by id after the write; read it first for an update or delete. |
|
||||
| `unconfirmed` | Re-record: read the entity and its list after the write. |
|
||||
| `incomplete-entities` | Re-record: read the entity through every view that lists it. |
|
||||
| `unexplained-change` | Re-record once with a second, different call of the same write. |
|
||||
| `no-call` | Re-record once with a write that succeeds. |
|
||||
| `side-effect` | Stop: the application changes other entities. |
|
||||
| `contradicted` | Stop: a later read disagrees with the modelled effect. |
|
||||
| `body-unusable` | Stop: the body is not a JSON object. |
|
||||
|
||||
Use new scratch names on each attempt; the first attempt's objects may still
|
||||
exist.
|
||||
New browser scenario captures include request times, so a fully timed capture
|
||||
can learn a write clock and serve updates that stamp modification times. Older
|
||||
captures or ones missing a request start keep record order and learn no clock.
|
||||
When coverage reports that limitation, record again with the current version
|
||||
before concluding that the timestamp change cannot be served.
|
||||
|
||||
## Export and hand off
|
||||
|
||||
`export_environment_bundle` with `source: {kind: "retained-evidence",
|
||||
evidence_id}` (or `{kind: "evidence-file", path}`), an absolute
|
||||
`output_directory` that does not exist yet and whose parent does, and a `name`
|
||||
(required when the application runs on `localhost` or an IP address). It returns
|
||||
the coverage again, `tool_count`, the written files and warnings; `dry_run:
|
||||
true` reports without writing. The bundle installs `rea-agents` of this REA's
|
||||
version from the registry; when the user runs an unreleased REA build, pass the
|
||||
`package_tarball` they give you (a packed `rea-agents` tarball) instead.
|
||||
|
||||
Tell the user how many tools answer from the state, which writes are served and
|
||||
which are withheld and why, and the run command (`agent-env run <folder>`). Say
|
||||
that the bundle ships the recorded responses and the capture's local paths
|
||||
(for a browser scenario, the browser executable's path), and
|
||||
list any `credential-named-members` warning pointers for review. Never publish
|
||||
or share the bundle yourself.
|
||||
|
||||
See
|
||||
[agent environments](https://github.com/morluto/rea/blob/main/docs/agent-environments.md)
|
||||
for what the state, replay and the bundle establish, and
|
||||
[evidence workflows](evidence-workflows.md) for the manifest and state views.
|
||||
@@ -48,7 +48,9 @@ or absence:
|
||||
- `compare_artifacts` compares inventory pages by occurrence path, content,
|
||||
metadata, and graph relations.
|
||||
- `compare_functions` compares explicit function Evidence, not fuzzy
|
||||
whole-binary matches.
|
||||
whole-binary matches. It rejects an `analyze_function` summary reply; pass
|
||||
the summary's `parent_evidence_id` as a `retained-evidence` reference or
|
||||
the complete dossier.
|
||||
- `compare_bundles` compares canonical bundle membership and unknown history.
|
||||
- `find_changed_behavior` combines existing comparisons; static differences
|
||||
remain candidates, not causal proof.
|
||||
@@ -104,6 +106,13 @@ each plan states why in its `reason`. It replays the capture instead with
|
||||
`--replay-only` or when the state is unavailable (not derivable, or a catalog
|
||||
over the discovery budget), and its stopped document's `state` says which
|
||||
applied.
|
||||
Use `view: {kind: "environment-coverage"}` with the same rules to see what an
|
||||
environment built from a capture would serve: read tools answered from the
|
||||
state or replayed with their reason, and each write tool served or withheld
|
||||
with a hint about what to record next; it does not apply the serve-time
|
||||
catalog and state size checks. `rea environment-build <capture.har> <dir>`
|
||||
inspects, projects and exports in one step and prints the same coverage, or
|
||||
`null` when the bundle serves replay.
|
||||
|
||||
For a PE/ELF export question, `inspect_native_exports` accepts `detail: "summary"`
|
||||
and retains the complete table. Query `inspect_analysis_view` with
|
||||
|
||||
@@ -17,15 +17,20 @@ the complete artifact inventory and identity but reads source text and analyzes
|
||||
only selected files. The result and summary record `source_selection`; files
|
||||
outside scope and their relationships remain unknown, so partial application
|
||||
coverage does not mean the selected source failed. Use repeated `--source-path`
|
||||
on either static application CLI route. Omit the selection when the question
|
||||
requires complete application analysis; `source_paths: []` is invalid, not an
|
||||
unfiltered request. `detail: "summary"` reduces delivery
|
||||
on either static application CLI route, or `--source-paths-json` with a JSON
|
||||
file for selections too long for one command line. Omit the selection when the
|
||||
question requires complete application analysis; `source_paths: []` is invalid,
|
||||
not an unfiltered request. `detail: "summary"` reduces delivery
|
||||
and does not by itself reduce analysis work.
|
||||
|
||||
ASAR header/index admission defaults to 16 MiB / 16777216 bytes;
|
||||
`REA_ASAR_MAX_HEADER_BYTES` (at most 256 MiB, set where REA starts) changes it.
|
||||
`source_paths`, `detail`, and `max_heap_mb` do not bypass or raise it. Or
|
||||
analyze an extracted directory.
|
||||
an admission error names `asar.max_header_bytes` and its bounds (at most
|
||||
256 MiB). Call `update_analysis_settings` with that setting, `action: "set"`
|
||||
and enough bytes, then retry the same full-archive request. No inspection or
|
||||
REA restart is required. `REA_ASAR_MAX_HEADER_BYTES` seeds future REA processes.
|
||||
`source_paths`, `detail`, and `max_heap_mb` do not bypass or raise header admission.
|
||||
Runtime JavaScript timeout/heap defaults are also editable; explicit per-call
|
||||
`analysis_timeout_ms` and `max_heap_mb` take precedence.
|
||||
|
||||
Exact `#alias` specifiers resolve through the importer's
|
||||
enclosing package `imports` map to package-local files; nested `node_modules`
|
||||
|
||||
@@ -4,8 +4,10 @@ For release comparisons, export `list_procedures` Evidence from each target befo
|
||||
closing it. Close clears session records: import both bundles after collecting the
|
||||
two targets, or supply portable inline Evidence. `match_native_functions` pairs unique exact names and, when supplied,
|
||||
complete observed body bytes. Reuse optional same-context `list_names`,
|
||||
`procedure_info`, `read_bytes` and existing `analyze_function` Evidence; avoid
|
||||
decompiling every function merely to match it. Its summary retains a parent for
|
||||
`procedure_info`, `read_bytes` and existing `analyze_function` dossiers as
|
||||
`left_observations`/`right_observations`; an MCP `analyze_function` summary
|
||||
reply contributes its `parent_evidence_id` as a `retained-evidence` reference,
|
||||
not the summary itself. Avoid decompiling every function merely to match it. Its summary retains a parent for
|
||||
`inspect_analysis_view` `function-matches` collections `matches` and `functions`.
|
||||
Select columns, batch IDs and page individual facts; aliases remain unresolved.
|
||||
Unpaired observations do not prove additions/removals. Existing matched dossier
|
||||
@@ -110,6 +112,32 @@ not proof the image is unsigned in every catalog or overlay sense. Signatures,
|
||||
chains, timestamps, and Authenticode digest coverage remain unobserved. See
|
||||
[PE Authenticode certificate tables](https://github.com/morluto/rea/blob/main/docs/pe-certificates.md).
|
||||
|
||||
## PE import and delay-load tables
|
||||
|
||||
Use `inspect_pe_imports` for an explicit local PE32/PE32+ image when the
|
||||
question concerns imported DLL and function names, ordinals, delay-load
|
||||
descriptors, or the pefile import hash. No `open_binary`, Windows SDK, or
|
||||
target execution is required. The CLI equivalent is `inspect-pe-imports PATH`.
|
||||
Preserve artifact SHA-256, directory file ranges, original DLL spellings, and
|
||||
ILT/IAT RVAs. A missing `IMAGE_DIRECTORY_ENTRY_IMPORT` directory is observed
|
||||
absence of that table, not proof the image never imported APIs through another
|
||||
table or overlay. Bound snapshots, loaded IAT contents, and export-forward
|
||||
resolution remain unobserved. See
|
||||
[PE import and delay-load tables](https://github.com/morluto/rea/blob/main/docs/pe-imports.md).
|
||||
|
||||
## PE TLS callbacks and load configuration
|
||||
|
||||
Use `inspect_pe_load_config` for an explicit local PE32/PE32+ image when the
|
||||
question concerns code that runs before the entry point through TLS callbacks,
|
||||
or the security cookie, SafeSEH, CFG, EH-continuation and XFG declarations in
|
||||
the load configuration. No `open_binary`, Windows SDK, or target execution is
|
||||
required. The CLI equivalent is `inspect-pe-load-config PATH`. Preserve artifact
|
||||
SHA-256, directory and callback-array file ranges, and callback VAs as
|
||||
hexadecimal strings. Fields outside the declared `Size` are `null`. Guard-flag
|
||||
mitigations carry `evidence_kind: "inferred"`; enforcement remains unobserved.
|
||||
See
|
||||
[PE TLS callbacks and load configuration](https://github.com/morluto/rea/blob/main/docs/pe-load-config.md).
|
||||
|
||||
## ELF note tables
|
||||
|
||||
Use `inspect_elf_notes` for an explicit local ELF32/ELF64 image when the
|
||||
@@ -121,6 +149,37 @@ absence of those declarations, not proof the image never carried notes in
|
||||
another container. See
|
||||
[ELF note tables](https://github.com/morluto/rea/blob/main/docs/elf-notes.md).
|
||||
|
||||
## Apple IPS crash reports
|
||||
|
||||
Use `inspect_apple_ips` for an explicit local Apple `.ips` file when the
|
||||
question concerns crash metadata, exception and termination facts, threads,
|
||||
usedImages, lossless registers, or documented crash classes. No `open_binary`,
|
||||
Xcode, atos, or target execution is required. The CLI equivalent is
|
||||
`inspect-apple-ips PATH`. Preserve artifact SHA-256, `bug_type` as a string,
|
||||
uppercase image UUIDs, and integer literals that exceed IEEE-754 range. Only
|
||||
`bug_type` `"309"` yields a crash body; other DiagnosticReports types return
|
||||
no crash result. Opened Mach-O and dSYM UUID joins remain unobserved. See
|
||||
[Apple IPS crash reports](https://github.com/morluto/rea/blob/main/docs/apple-ips.md).
|
||||
|
||||
## Linux kernel modules
|
||||
|
||||
Use `inspect_kernel_module` for an explicit local ELF32/ELF64 relocatable
|
||||
object when the question concerns `.modinfo` license, vermagic, alias,
|
||||
depends, or parm strings, the `__versions` symbol CRCs, or an appended module
|
||||
signature trailer. No `open_binary`, Linux host, or `modinfo` program is
|
||||
required. The CLI equivalent is `inspect-kernel-module PATH`. Preserve
|
||||
artifact SHA-256, key order, duplicate keys, CRC hex, and section file ranges.
|
||||
A missing section is observed absence when section names are known, not proof
|
||||
the module never carried that metadata. `.gnu.linkonce.this_module` is reported
|
||||
as present or absent; `struct module` stays unknown because its layout changes
|
||||
with the kernel version. `__ksymtab` records are not decoded. The PKCS#7 range
|
||||
and its SHA-256 are observed; certificate, signer, and digest coverage remain
|
||||
unvalidated. An absent trailer is not proof the module is unsigned in another
|
||||
container. gzip, xz, and zstd whole-file containers are unsupported and name
|
||||
`external_decompression` as the next probe: use an external codec utility to
|
||||
decompress into a separate file, then call `inspect_kernel_module` on that file. See
|
||||
[Linux kernel modules](https://github.com/morluto/rea/blob/main/docs/kernel-modules.md).
|
||||
|
||||
## CPython pyc files
|
||||
|
||||
Use `inspect_python_pyc` for an explicit local CPython 3.7–3.13 `.pyc` when the
|
||||
@@ -138,7 +197,11 @@ question concerns IFF chunks, atom names, exports, imports, lambdas, or the
|
||||
Code header. No `open_binary`, Erlang installation, or bytecode execution is
|
||||
required. The CLI equivalent is `inspect-erlang-beam PATH`. Preserve artifact
|
||||
SHA-256, chunk file ranges, 1-based atom indices, and original atom spellings.
|
||||
Missing optional tables stay null. See
|
||||
Missing optional tables stay null. For a few facts, use `detail: "summary"` with
|
||||
a `beam` view selecting a collection, exact names/indices and fields; read later
|
||||
pages from `parent_evidence_id` or the complete Evidence bundle. Same-name
|
||||
exports retain every arity and original atom index. CLI summary delivery requires
|
||||
`--evidence_output`. Null table counts remain distinct from decoded empty tables. See
|
||||
[Erlang BEAM files](https://github.com/morluto/rea/blob/main/docs/erlang-beam.md).
|
||||
|
||||
## SQLite snapshots
|
||||
@@ -231,6 +294,9 @@ 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.
|
||||
The default MCP reply is already a summary of that dossier: its
|
||||
`normalized_result.parent_evidence_id` is the retained ID to page, and its
|
||||
null counts mark facets the provider did not record or declared unavailable.
|
||||
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
|
||||
@@ -276,14 +342,18 @@ providers. Top-level session capabilities describe the current route, and
|
||||
bridge startup, and readiness. The default 330,000 ms is configurable through
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS`; a smaller query still needs the same cold import.
|
||||
|
||||
Preserve useful Evidence before closing the session or restarting REA. Check
|
||||
`close_binary` and resolve reported cleanup failures. Set a larger startup budget
|
||||
in the environment that launches REA, then restart REA and reconnect the MCP
|
||||
client before reopening the same target. Closing and reopening a binary in the
|
||||
existing server keeps its original configuration and starts import again.
|
||||
Environment changes in an agent's shell do not update an already running MCP
|
||||
server. If its launch configuration cannot be changed, report that constraint
|
||||
and the exact retry setting instead of claiming a fixed technical limit.
|
||||
When the error names `ghidra.startup_timeout_ms`, call
|
||||
`update_analysis_settings` with `action: "set"` and a larger value within the
|
||||
reported bounds. Resolve retained cleanup before the next startup attempt.
|
||||
No REA restart is needed; an already accepted startup keeps its original
|
||||
budget. A new attempt repeats import. Preserve useful Evidence before closing
|
||||
and reopening the target when remediation requires that lifecycle step.
|
||||
|
||||
For a per-function timeout, update `ghidra.decompile_timeout_seconds` and retry
|
||||
the same function on the existing Program. Explicit `null` removes that
|
||||
per-function deadline. Inspection is optional when the error supplies the
|
||||
setting and bounds. Runtime updates disappear when REA exits; environment
|
||||
changes only seed future REA processes.
|
||||
|
||||
The client's tool-call deadline must allow startup plus the requested query;
|
||||
server settings and progress notifications cannot override it. CLI analysis
|
||||
|
||||
@@ -36,6 +36,9 @@ unchecked. Maintainers can help resolve open questions.
|
||||
Use "none" or "not applicable" only when established. -->
|
||||
|
||||
- Semantic owner and earliest changed stage:
|
||||
<!-- Name the producer of parsed facts or resources and its affected consumers.
|
||||
Summarize superseded paths removed and any distinct policy, lifecycle,
|
||||
lazy-loading, or compatibility responsibility retained. -->
|
||||
- Contribution scope fit and linked maintainer decision:
|
||||
- CLI and MCP/tool-catalog contract:
|
||||
- Provider, bridge, target-format, or platform compatibility:
|
||||
@@ -68,6 +71,10 @@ source, link, or rendered-document checks. -->
|
||||
- User-visible CLI/MCP output (if applicable):
|
||||
- Remaining proof gaps:
|
||||
|
||||
For boundary fixes, identify the applicable [boundary regressions](https://github.com/morluto/rea/blob/main/docs/testing.md#boundary-regressions)
|
||||
and [lifecycle regressions](https://github.com/morluto/rea/blob/main/docs/testing.md#lifecycle-regressions)
|
||||
covered by the evidence above, and explain relevant gaps.
|
||||
|
||||
For evidence-bearing changes:
|
||||
|
||||
- [ ] Observed, derived, and inferred claims remain distinguishable.
|
||||
|
||||
@@ -789,7 +789,7 @@ jobs:
|
||||
id: npm-cache
|
||||
uses: ./.github/actions/npm-cache
|
||||
- run: npm ci
|
||||
- name: Run the public CLI/MCP reconstruction journey
|
||||
- name: Verify static CLI/MCP journeys and synthetic report conformance
|
||||
env:
|
||||
REA_READINESS_REPORT_PATH: readiness-report.json
|
||||
run: |
|
||||
@@ -858,6 +858,7 @@ jobs:
|
||||
src/process/capture/FilesystemSnapshot.test.ts
|
||||
tests/process-global/filesystemSnapshotFallbackCancellation.test.ts
|
||||
tests/boundary/filesystem/typescriptCompiler.test.ts
|
||||
tests/boundary/filesystem/releaseProposal.test.ts
|
||||
tests/boundary/filesystem/binaryTarget.test.ts
|
||||
src/contracts/sessionPathInputs.test.ts
|
||||
tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Real Android metadata bridge
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
paths:
|
||||
- .github/workflows/real-android-metadata.yml
|
||||
- bridge/android/**
|
||||
- src/android/JadxRelease.ts
|
||||
- scripts/fixtures/android/**
|
||||
- tests/conformance/android/**
|
||||
- tests/fixtures/android/static-initializers/**
|
||||
- tests/fixtures/android/direct-invokes/**
|
||||
- .nvmrc
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: android-metadata-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
android-metadata:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
- name: Fetch checksum-pinned engine and public APK fixture
|
||||
run: node scripts/fixtures/android/fetch.mjs "$RUNNER_TEMP/rea-android"
|
||||
- name: Compile and exercise the real metadata bridge
|
||||
shell: bash
|
||||
run: |
|
||||
export JAVA_HOME="$JAVA_HOME_21_X64"
|
||||
android_root="$RUNNER_TEMP/rea-android"
|
||||
classes="$android_root/classes"
|
||||
jar="$android_root/jadx-headless-mcp-0.7.1-all.jar"
|
||||
mkdir -p "$classes"
|
||||
"$JAVA_HOME/bin/javac" -J-Xmx512m -J-XX:ActiveProcessorCount=2 \
|
||||
-classpath "$jar" -d "$classes" \
|
||||
bridge/android/ReaJadxBridge.java \
|
||||
tests/conformance/android/ReaJadxMetadataRegression.java
|
||||
"$JAVA_HOME/bin/java" -Xmx512m -XX:ActiveProcessorCount=2 \
|
||||
-classpath "$classes:$jar" ReaJadxMetadataRegression \
|
||||
"$android_root/ApiDemos-debug.apk" \
|
||||
"$GITHUB_WORKSPACE/tests/fixtures/android/static-initializers" \
|
||||
"$classes" "$GITHUB_WORKSPACE/tests/fixtures/android/direct-invokes" \
|
||||
| tee "$android_root/metadata.log"
|
||||
grep -F 'RAW_CLASS_SELECTOR_REGRESSION_PASS nested=true metadata=true references=true' \
|
||||
"$android_root/metadata.log"
|
||||
@@ -48,7 +48,8 @@ jobs:
|
||||
- uses: ./.github/actions/portable-build-cache
|
||||
with:
|
||||
build_cache_artifact: ${{ inputs.build_cache_artifact }}
|
||||
- run: npm run verify:browser
|
||||
# Own a fresh bus so Chromium never depends on an inherited session address.
|
||||
- run: dbus-run-session -- npm run verify:browser
|
||||
env:
|
||||
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
||||
REA_BROWSER_NO_SANDBOX: "true"
|
||||
@@ -44,7 +44,8 @@ jobs:
|
||||
- uses: ./.github/actions/portable-build-cache
|
||||
with:
|
||||
build_cache_artifact: ${{ inputs.build_cache_artifact }}
|
||||
- run: env -u DBUS_SESSION_BUS_ADDRESS npm run verify:browser:runtime
|
||||
# Own a fresh bus so Chromium never depends on an inherited session address.
|
||||
- run: dbus-run-session -- npm run verify:browser:runtime
|
||||
env:
|
||||
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
||||
REA_BROWSER_NO_SANDBOX: "true"
|
||||
@@ -46,8 +46,12 @@ jobs:
|
||||
build_cache_artifact: ${{ inputs.build_cache_artifact }}
|
||||
- name: Install the pinned compiler into an isolated fixture directory
|
||||
run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10
|
||||
- run: npm run verify:browser:source-maps
|
||||
# Own a fresh bus so Chromium never depends on an inherited session address.
|
||||
- run: dbus-run-session -- npm run verify:browser:source-maps
|
||||
env:
|
||||
# Retain browser launch argv/PID/stderr in the verifier's captured
|
||||
# CLI failure diagnostics without changing its deadline or retrying.
|
||||
DEBUG: pw:browser
|
||||
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
||||
REA_BROWSER_NO_SANDBOX: "true"
|
||||
REA_WEB_SOURCE_MAP_COMPILER: ${{ runner.temp }}/rea-web-source-map-compiler/node_modules/esbuild/lib/main.js
|
||||
@@ -47,19 +47,63 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
run: |
|
||||
finalized=$(gh api --paginate "repos/${GH_REPO}/pulls?state=open&base=main&per_page=100" \
|
||||
--jq '.[] | select(.head.repo.full_name == .base.repo.full_name) | select(.head.ref | startswith("release-please--branches--main--")) | select(any(.labels[]; .name == "rea:release-notes-finalized")) | .number')
|
||||
# Filter at the repository connection, without a search-index dependency.
|
||||
pages=$(gh api graphql --paginate --slurp \
|
||||
-f owner="${GH_REPO%/*}" -f name="${GH_REPO#*/}" \
|
||||
-f query='query($owner:String!,$name:String!,$endCursor:String) {
|
||||
repository(owner:$owner,name:$name) {
|
||||
nameWithOwner
|
||||
pullRequests(first:100,after:$endCursor,states:OPEN,baseRefName:"main",labels:["rea:release-notes-finalized"]) {
|
||||
nodes { number headRefName headRepository { nameWithOwner } }
|
||||
pageInfo { hasNextPage endCursor }
|
||||
}
|
||||
}
|
||||
}')
|
||||
finalized=$(jq -er '
|
||||
if type != "array" or length == 0 then error("Missing GitHub pages") else . end |
|
||||
if .[-1].data.repository.pullRequests.pageInfo.hasNextPage != false
|
||||
then error("Incomplete GitHub pagination") else . end |
|
||||
map(
|
||||
if (.errors // [] | length) != 0 then error("GitHub query failed") else . end |
|
||||
.data.repository |
|
||||
if (.nameWithOwner | type) != "string" or (.pullRequests.nodes | type) != "array" or
|
||||
(.pullRequests.pageInfo.hasNextPage | type) != "boolean"
|
||||
then error("Invalid GitHub repository connection") else . end |
|
||||
.nameWithOwner as $repo | .pullRequests.nodes[] |
|
||||
if (.number | type) != "number" or (.headRefName | type) != "string" or (has("headRepository") | not) or
|
||||
(.headRepository != null and (.headRepository.nameWithOwner | type) != "string")
|
||||
then error("Invalid GitHub pull request") else . end |
|
||||
select(.headRepository.nameWithOwner == $repo) |
|
||||
select(.headRefName | startswith("release-please--branches--main--")) | .number
|
||||
) | map(tostring) | join(" ")' <<< "$pages")
|
||||
if [[ -n "${finalized}" ]]; then
|
||||
echo "Finalized release notes on PR ${finalized}; automatic proposal refresh is paused." >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "frozen=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
|
||||
- name: Check out proposal controller and complete Git history
|
||||
if: steps.editorial.outputs.frozen != 'true'
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
||||
if: steps.editorial.outputs.frozen != 'true'
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
target-branch: main
|
||||
skip-github-release: true
|
||||
node-version-file: .nvmrc
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Install proposal controller dependencies
|
||||
if: steps.editorial.outputs.frozen != 'true'
|
||||
run: npm ci
|
||||
|
||||
- name: Update release proposal
|
||||
if: steps.editorial.outputs.frozen != 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
SOURCE_SHA: ${{ github.sha }}
|
||||
run: node scripts/release-proposal.mjs --target-branch main --source-sha "$SOURCE_SHA"
|
||||
|
||||
merged-release:
|
||||
name: Release reviewed main merge
|
||||
@@ -232,15 +276,25 @@ jobs:
|
||||
node scripts/release-notes.mjs publication --repository "$GH_REPO" \
|
||||
--source "$SOURCE_SHA"
|
||||
|
||||
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
|
||||
id: release
|
||||
with:
|
||||
- name: Prepare checkpoint release proposal
|
||||
if: inputs.phase == 'prepare'
|
||||
id: proposal
|
||||
env:
|
||||
# A dedicated credential starts PR CI automatically; the built-in
|
||||
# token creates approval-required PR runs for maintainers to approve.
|
||||
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
RELEASE_BRANCH: ${{ inputs.release_branch }}
|
||||
SOURCE_SHA: ${{ steps.branch.outputs.sha }}
|
||||
run: node scripts/release-proposal.mjs --target-branch "$RELEASE_BRANCH" --source-sha "$SOURCE_SHA"
|
||||
|
||||
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
|
||||
if: inputs.phase == 'publish'
|
||||
id: release
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
target-branch: ${{ inputs.release_branch }}
|
||||
skip-github-release: ${{ inputs.phase == 'prepare' }}
|
||||
skip-github-pull-request: ${{ inputs.phase == 'publish' }}
|
||||
skip-github-release: false
|
||||
skip-github-pull-request: true
|
||||
|
||||
- name: Require a merged release PR for publication
|
||||
if: inputs.phase == 'publish' && steps.release.outputs.release_created != 'true'
|
||||
@@ -260,26 +314,26 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Check out release pull request
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
with:
|
||||
ref: ${{ fromJSON(steps.release.outputs.pr).headBranchName }}
|
||||
ref: ${{ fromJSON(steps.proposal.outputs.pr).headBranchName }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js for generated documentation
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Install dependencies
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
run: npm ci
|
||||
|
||||
- name: Validate prepared release version and migration notes
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ inputs.release_branch }}
|
||||
SOURCE_SHA: ${{ steps.branch.outputs.sha }}
|
||||
@@ -289,11 +343,11 @@ jobs:
|
||||
--source-sha "$SOURCE_SHA"
|
||||
|
||||
- name: Regenerate release documentation
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
run: npm run docs:generate
|
||||
|
||||
- name: Validate generated release documentation
|
||||
if: inputs.phase == 'prepare' && steps.release.outputs.prs_created == 'true'
|
||||
if: inputs.phase == 'prepare' && steps.proposal.outputs.prs_created == 'true'
|
||||
run: npm run docs:check && git diff --exit-code
|
||||
|
||||
qualification:
|
||||
|
||||
@@ -17,10 +17,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Exercise unavailable-runtime diagnostics, the first supported release,
|
||||
# and new patches on both supported lines without hand-editing versions.
|
||||
# Exercise unavailable-runtime diagnostics and rolling supported releases.
|
||||
# Security floors prevent fallback to an older hosted-toolcache patch.
|
||||
# The repository-pinned Node 24 version also runs the complete test suite.
|
||||
node: ["22.x", "24.22.1", "24.x", "26.x"]
|
||||
node: ["^22.23.4", "24.22.1", "^24.22.1", "^26.12.1"]
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
|
||||
+95
-3
@@ -1,7 +1,13 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "unicorn", "oxc"],
|
||||
"plugins": ["typescript", "import", "unicorn", "oxc", "vitest"],
|
||||
"rules": {
|
||||
"rea/no-buffer-deep-equality": "error",
|
||||
"rea/cancellation-cause": "error",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-unsafe-optional-chaining": "error",
|
||||
"no-useless-escape": ["warn", { "allowRegexCharacters": ["-"] }],
|
||||
"complexity": ["warn", 20],
|
||||
"max-depth": ["warn", 4],
|
||||
"max-lines": [
|
||||
@@ -23,7 +29,38 @@
|
||||
"max-params": ["warn", 4],
|
||||
"no-var": "warn",
|
||||
"no-var-requires": "error",
|
||||
"typescript/no-import-type-side-effects": "error"
|
||||
"typescript/no-import-type-side-effects": "error",
|
||||
"vitest/no-standalone-expect": "off",
|
||||
"vitest/no-conditional-expect": "off",
|
||||
"vitest/expect-expect": "off",
|
||||
"vitest/no-disabled-tests": "off",
|
||||
"vitest/require-mock-type-parameters": "off",
|
||||
"vitest/require-to-throw-message": "off",
|
||||
"import/no-duplicates": [
|
||||
"warn",
|
||||
{
|
||||
"preferInline": false
|
||||
}
|
||||
],
|
||||
"vitest/valid-expect": [
|
||||
"warn",
|
||||
{
|
||||
"maxArgs": 2
|
||||
}
|
||||
],
|
||||
"rea/no-evidence-json-preadmission": "error",
|
||||
"rea/no-positional-tool-contract": "error",
|
||||
"rea/no-fixture-root-cleanup": "error",
|
||||
"typescript/no-floating-promises": "error",
|
||||
"typescript/no-misused-promises": "warn",
|
||||
"typescript/return-await": ["error", "error-handling-correctness-only"],
|
||||
"typescript/switch-exhaustiveness-check": [
|
||||
"error",
|
||||
{
|
||||
"considerDefaultExhaustiveForUnions": true
|
||||
}
|
||||
],
|
||||
"rea/no-shared-module-mock": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
@@ -36,6 +73,12 @@
|
||||
"no-var-requires": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["src/**/*.ts"],
|
||||
"rules": {
|
||||
"typescript/no-misused-promises": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["tests/**/*.ts", "src/**/*.test.ts", "src/**/*.fixture.ts"],
|
||||
"rules": {
|
||||
@@ -47,7 +90,8 @@
|
||||
"skipBlankLines": true,
|
||||
"skipComments": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"typescript/no-misused-promises": "warn"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -91,6 +135,45 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["tests/**/*.test.ts", "src/**/*.test.ts"],
|
||||
"rules": {
|
||||
"vitest/valid-expect": [
|
||||
"warn",
|
||||
{
|
||||
"maxArgs": 2
|
||||
}
|
||||
],
|
||||
"vitest/valid-expect-in-promise": "error",
|
||||
"vitest/no-focused-tests": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"scripts/lib/http3-capture-assertions.test.mjs",
|
||||
"scripts/lib/http3-verifier-lifecycle.test.mjs"
|
||||
],
|
||||
"rules": {
|
||||
"typescript/no-floating-promises": [
|
||||
"error",
|
||||
{
|
||||
"allowForKnownSafeCalls": [
|
||||
{
|
||||
"from": "package",
|
||||
"package": "@types/node",
|
||||
"name": "test"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["scripts/fixtures/javascript-recovery/code-split/entry.mjs"],
|
||||
"rules": {
|
||||
"typescript/no-floating-promises": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"env": {
|
||||
@@ -109,5 +192,14 @@
|
||||
".devin",
|
||||
".factory",
|
||||
"third_party"
|
||||
],
|
||||
"options": {
|
||||
"reportUnusedDisableDirectives": "error"
|
||||
},
|
||||
"jsPlugins": [
|
||||
{
|
||||
"name": "rea",
|
||||
"specifier": "./scripts/lint/index.mjs"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -80,7 +80,7 @@ Coordinate expensive checks across agents. If a test unexpectedly consumes heavy
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
For test changes or provider claims, use [docs/testing.md](docs/testing.md). Select applicable [boundary regressions](docs/testing.md#boundary-regressions) for parser, inventory, snapshot, and projection fixes. 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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -108,10 +108,11 @@ distinguish source-derived conclusions, proposed checks, and unavailable coverag
|
||||
Address actionable automated review findings and explain disagreements.
|
||||
|
||||
Leave the template's **Author readiness** declarations unchecked for the human
|
||||
owner to complete. Never attest to human review on their behalf. Keep the PR in
|
||||
draft until the human declares the PR initially ready. Later pushes do not
|
||||
invalidate that declaration or require another human sign-off. Keep the PR body
|
||||
and affected validation current as work changes. The readiness check validates
|
||||
owner to complete. Never attest to human review on their behalf. Draft status
|
||||
is optional; preserve the PR's current draft status unless the user asks to change
|
||||
it. Later pushes do not invalidate the readiness declaration or require another
|
||||
human sign-off. Keep the PR body and affected validation current as work changes.
|
||||
The readiness check validates
|
||||
the filled declaration; CI and automated review results do not establish that
|
||||
human review occurred, maintainer scope approval, or merge permission.
|
||||
|
||||
|
||||
+30
-4
@@ -25,6 +25,18 @@ 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.
|
||||
|
||||
Before retiring an alias or facade, trace runtime registration, dynamic imports,
|
||||
JavaScript verifiers, subprocess scripts, and packaged entrypoints as well as
|
||||
TypeScript references. Tests may be the last consumers of a superseded internal
|
||||
path; migrate their distinct assertions to the current production path before
|
||||
removing it. Preserve validation, lazy loading, caller policy, and resource
|
||||
acquisition and cleanup supplied by the old boundary. Published APIs, persisted
|
||||
formats, and independently versioned bridges require an explicit compatibility
|
||||
decision; an internal representation alone does not establish that obligation.
|
||||
See [interpreting boundary facts once](docs/tool-design.md#interpret-boundary-facts-once)
|
||||
for admission ownership and the distinction between repeated validation and
|
||||
independent checks.
|
||||
|
||||
For analysis workflows and agent interfaces, follow the
|
||||
[performance priorities](AGENTS.md#performance). Explain the selected output
|
||||
scope, reuse/cache decisions, and relevant before/after measurements when these
|
||||
@@ -35,7 +47,9 @@ compare equivalent real tasks before claiming an improvement.
|
||||
|
||||
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
|
||||
When adding or changing an admission ceiling, budget, or deadline, follow
|
||||
[admission limits and recovery](docs/design/limits-and-recovery.md).
|
||||
[analysis settings, limits, and recovery](docs/design/limits-and-recovery.md)
|
||||
for ownership, operation snapshots, provider integration, and the steps for
|
||||
adding a runtime setting.
|
||||
|
||||
## Reporting issues
|
||||
|
||||
@@ -89,7 +103,11 @@ Human ownership and review remain required when CI or an automated reviewer
|
||||
reports success. Readiness requests maintainer review; it does not grant scope
|
||||
approval or permission to merge.
|
||||
|
||||
Draft PRs may request early feedback with open questions and incomplete checks.
|
||||
Draft status is optional. Draft PRs may request early feedback with open questions
|
||||
and incomplete checks. Agents preserve the current draft status unless asked to
|
||||
change it; missing readiness declarations or later updates do not require a PR
|
||||
to become a draft.
|
||||
|
||||
Leave the readiness declaration unchecked until the human owner has completed
|
||||
it. The declaration records initial readiness; later pushes do not invalidate
|
||||
it or require another human sign-off. Keep the PR description and affected
|
||||
@@ -368,9 +386,17 @@ Real-provider execution is uncached.
|
||||
### Temporary files and diagnostics
|
||||
|
||||
Tests use `createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`
|
||||
for exact-path, awaited cleanup, including failures and timeouts.
|
||||
for exact-path, awaited cleanup, including failures and timeouts. It registers
|
||||
deletion with Vitest's `onTestFinished`; do not also add its result to a roots
|
||||
array or an `afterEach` removal. `createTestWorkspace` from
|
||||
`tests/support/workspace/workspaceFixture.ts` leaves cleanup with its caller,
|
||||
which must await `removeTestWorkspace`. Keep explicit resource teardown before
|
||||
directory deletion, using the case's `finally` or `afterEach`; Vitest runs
|
||||
`afterEach` before `onTestFinished` and awaits finish hooks in reverse
|
||||
registration order.
|
||||
`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.
|
||||
rejects remaining REA-owned paths. It cannot detect duplicate deletion owners or
|
||||
prove resource-close ordering. Never glob-clean shared `/tmp/rea-*` content.
|
||||
|
||||
`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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
**English** · [简体中文](docs/readme/README_zh.md) · [繁體中文](docs/readme/README_zh-TW.md) · [日本語](docs/readme/README_ja.md) · [한국어](docs/readme/README_ko.md) · [Türkçe](docs/readme/README_tr.md) · [Русский](docs/readme/README_ru.md) · [Tiếng Việt](docs/readme/README_vi.md) · [ไทย](docs/readme/README_th.md) · [Deutsch](docs/readme/README_de.md) · [Español](docs/readme/README_es.md) · [Français](docs/readme/README_fr.md) · [Українська](docs/readme/README_uk.md) · [Polski](docs/readme/README_pl.md) · [Português (Brasil)](docs/readme/README_pt-BR.md) · [العربية](docs/readme/README_ar.md) · [فارسی](docs/readme/README_fa.md) · [Bahasa Indonesia](docs/readme/README_id.md) · [Italiano](docs/readme/README_it.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md) · [Roman Urdu](docs/readme/README_ur-Latn.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md) · [Roman Urdu](docs/readme/README_ur-Latn.md) · [Română](docs/readme/README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -192,7 +192,10 @@ Additional tools and host support depend on the target:
|
||||
| Godot PCK | Archive inventory and extraction, original header/directory facts and selected content identities | Built-in static formats 2, 3 and 4; no Godot required |
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources and dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](docs/rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](docs/pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](docs/pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](docs/elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and documented crash classes | Built-in static JSON inspection; [Apple IPS](docs/apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](docs/kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, imports, lambdas and the Code header | Built-in static BEAM inspection; [Erlang BEAM](docs/erlang-beam.md) |
|
||||
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
|
||||
|
||||
@@ -16,6 +16,7 @@ notices supplied with the software you actually obtain or redistribute.
|
||||
| Material | Use and licensing records |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| npm dependencies | [Complete inventory](licenses/npm-dependencies.txt) of every entry in `package-lock.json`, including transitive, optional platform, development, and website dependencies. [Runtime notices](licenses/npm-runtime-notices.txt) preserve the copyright, license, and NOTICE documents from integrity-verified release archives, plus the MIT notice for Rolldown's generated runtime helpers. Development dependencies are inventoried but are not all distributed in REA's npm package. |
|
||||
| pefile ordinal tables | Import-hash ordinal names are derived from [pefile 2024.8.26](https://github.com/erocarrera/pefile/tree/4b3b1e2e568a88d4f1897d694d684f23d9e270c4), copyright 2004–2024 Ero Carrera. Preserve the [MIT license](licenses/pefile-2024.8.26-LICENSE.txt). The Python package is not a runtime dependency. |
|
||||
| NativeAOT parser | REA's derived parser uses the MIT-licensed [ghidra-nativeaot](https://github.com/Washi1337/ghidra-nativeaot/tree/effeb734fc570c32650f88b159608979dc7b423e) work of Washi and the NativeAOT layout definitions in [dotnet/runtime](https://github.com/dotnet/runtime/tree/a3b2d40328be0be3f8dd43f0e5cc925b8827b044). Preserve [Washi's MIT notice](licenses/nativeaot-parser-MIT.txt) and the [.NET Foundation MIT notice](licenses/dotnet-runtime-MIT.txt). |
|
||||
| EVM analysis | `evmole@0.9.3`, MIT, copyright 2023 Maxim Andreev. The published npm archive omits its license document; REA retains the [original upstream license](third_party/evmole/LICENSE) and [provenance](third_party/evmole/README.md). It is also included in the runtime notices. |
|
||||
| Windows native addon | The release addon is compiled with MinGW-w64 and statically links GCC runtime libraries. Preserve the [MinGW-w64 runtime notices](licenses/MinGW-w64-runtime.txt), [GPLv3 text](licenses/GPL-3.0.txt), and [GCC Runtime Library Exception 3.1](licenses/GCC-Runtime-Library-Exception-3.1.txt). The exception governs eligible compiled combinations; it does not relicense the runtime itself under MIT. The Node-API build headers are from Node 22.19.0; its [original license and component notices](licenses/Node-22.19.0-LICENSE.txt) are retained. Node itself is supplied by the user. Snapshot provenance and release-toolchain review requirements are in [licenses/README.md](licenses/README.md). |
|
||||
|
||||
@@ -3,6 +3,8 @@ import com.google.gson.*;
|
||||
import io.modelcontextprotocol.kotlin.sdk.server.*;
|
||||
import io.modelcontextprotocol.kotlin.sdk.types.*;
|
||||
import jadx.api.*;
|
||||
import jadx.api.plugins.input.data.annotations.EncodedValue;
|
||||
import jadx.api.plugins.input.data.attributes.JadxAttrType;
|
||||
import jadx.api.plugins.input.data.ICodeReader;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.insns.InsnIndexType;
|
||||
@@ -40,7 +42,8 @@ class ReaJadxBridge {
|
||||
|
||||
private record MethodSnapshot(String name, String rawName, String shortId, List<String> bodyAbsenceMarkers,
|
||||
Map<String, Object> summary) {}
|
||||
private record ClassSnapshot(JavaClass node, List<MethodSnapshot> methods, Map<String, Object> summary) {}
|
||||
private record ClassSnapshot(JavaClass node, List<MethodSnapshot> methods, Map<String, Object> summary,
|
||||
Map<String, Object> summaryWithValues) {}
|
||||
private record ManifestSnapshot(String text, Map<String, Object> summary) {}
|
||||
|
||||
private static final class InputFailure extends IllegalArgumentException {
|
||||
@@ -142,6 +145,14 @@ class ReaJadxBridge {
|
||||
return value.getAsString();
|
||||
}
|
||||
|
||||
private static boolean flag(JsonObject args, String name) {
|
||||
JsonElement value = args.get(name);
|
||||
if (value == null) return false;
|
||||
if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isBoolean())
|
||||
throw new IllegalArgumentException(name + " must be a boolean");
|
||||
return value.getAsBoolean();
|
||||
}
|
||||
|
||||
private static int integer(JsonObject args, String name, int fallback) {
|
||||
JsonElement value = args.get(name);
|
||||
if (value == null) return fallback;
|
||||
@@ -263,18 +274,43 @@ class ReaJadxBridge {
|
||||
"dex_descriptor", descriptor,
|
||||
"is_constructor", method.isConstructor(), "def_pos", 0));
|
||||
}).toList();
|
||||
List<Map<String, Object>> fields = node.getFields().stream()
|
||||
.sorted(Comparator.comparing(FieldNode::getAlias))
|
||||
.map(field -> Map.<String, Object>of("name", field.getAlias(),
|
||||
"type", field.getType().toString(), "def_pos", 0)).toList();
|
||||
List<FieldNode> orderedFields = new ArrayList<>(node.getFields());
|
||||
orderedFields.sort(Comparator.comparing(FieldNode::getAlias));
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
List<Map<String, Object>> valuedFields = new ArrayList<>();
|
||||
boolean anyValue = false;
|
||||
for (FieldNode field : orderedFields) {
|
||||
Map<String, Object> entry = Map.of("name", field.getAlias(),
|
||||
"type", field.getType().toString(), "def_pos", 0);
|
||||
fields.add(entry);
|
||||
Map<String, Object> value = dexStaticValue(field);
|
||||
if (value == null) valuedFields.add(entry);
|
||||
else {
|
||||
anyValue = true;
|
||||
Map<String, Object> valued = new LinkedHashMap<>(entry);
|
||||
valued.put("dex_static_value", value);
|
||||
valuedFields.add(Collections.unmodifiableMap(valued));
|
||||
}
|
||||
}
|
||||
List<String> inner = node.getInnerClasses().stream().map(ClassNode::getFullName).toList();
|
||||
Map<String, Object> summary = Map.of(
|
||||
"full_name", cls.getFullName(), "name", cls.getName(),
|
||||
"full_name", cls.getFullName(), "raw_name", cls.getRawName(), "name", cls.getName(),
|
||||
"method_count", methods.size(), "field_count", fields.size(),
|
||||
"inner_class_count", inner.size(), "inner_classes", inner,
|
||||
"methods", methods.stream().map(MethodSnapshot::summary).toList(), "fields", fields);
|
||||
index.computeIfAbsent(cls.getFullName(), ignored -> new ArrayList<>())
|
||||
.add(new ClassSnapshot(cls, methods, summary));
|
||||
"methods", methods.stream().map(MethodSnapshot::summary).toList(), "fields", List.copyOf(fields));
|
||||
// DEX static values are opt-in, so method and reference lookups keep the member-only reply.
|
||||
Map<String, Object> summaryWithValues = summary;
|
||||
if (anyValue) {
|
||||
Map<String, Object> copy = new LinkedHashMap<>(summary);
|
||||
copy.put("fields", List.copyOf(valuedFields));
|
||||
summaryWithValues = Collections.unmodifiableMap(copy);
|
||||
}
|
||||
ClassSnapshot snapshot = new ClassSnapshot(cls, methods, summary, summaryWithValues);
|
||||
index.computeIfAbsent(cls.getFullName(), ignored -> new ArrayList<>()).add(snapshot);
|
||||
// Keep the binary identity supplied by JADX; '$' can also be a literal
|
||||
// name character, so replacing separators would invent lookup aliases.
|
||||
if (!cls.getRawName().equals(cls.getFullName()))
|
||||
index.computeIfAbsent(cls.getRawName(), ignored -> new ArrayList<>()).add(snapshot);
|
||||
}
|
||||
}
|
||||
classes = Collections.unmodifiableMap(index);
|
||||
@@ -289,6 +325,28 @@ class ReaJadxBridge {
|
||||
return candidates.get(0);
|
||||
}
|
||||
|
||||
/** A static final field's class-definition static value; a static initializer can still assign it. */
|
||||
private static Map<String, Object> dexStaticValue(FieldNode field) {
|
||||
if (!field.getAccessFlags().isStatic() || !field.getAccessFlags().isFinal()) return null;
|
||||
EncodedValue encoded = field.get(JadxAttrType.CONSTANT_VALUE);
|
||||
if (encoded == null) return null;
|
||||
Object value = encoded.getValue();
|
||||
// JADX also attaches the shared null to static finals without a value, so null is never reported.
|
||||
// Wide and floating values keep their Java text instead of a lossy JSON number.
|
||||
return switch (encoded.getType()) {
|
||||
case ENCODED_BOOLEAN -> Map.of("type", "boolean", "value", value);
|
||||
case ENCODED_BYTE -> Map.of("type", "byte", "value", value);
|
||||
case ENCODED_SHORT -> Map.of("type", "short", "value", value);
|
||||
case ENCODED_CHAR -> Map.of("type", "char", "value", (int) (Character) value);
|
||||
case ENCODED_INT -> Map.of("type", "int", "value", value);
|
||||
case ENCODED_LONG -> Map.of("type", "long", "value", value.toString());
|
||||
case ENCODED_FLOAT -> Map.of("type", "float", "value", value.toString());
|
||||
case ENCODED_DOUBLE -> Map.of("type", "double", "value", value.toString());
|
||||
case ENCODED_STRING -> Map.of("type", "string", "value", value);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private List<MethodSnapshot> methods(ClassSnapshot cls, JsonObject args) {
|
||||
String name = string(args, "method_name");
|
||||
List<MethodSnapshot> result = cls.methods().stream().filter(method -> method.name().equals(name)).toList();
|
||||
@@ -439,7 +497,8 @@ class ReaJadxBridge {
|
||||
"items", items));
|
||||
}
|
||||
ClassSnapshot cls = selected(args);
|
||||
if (name.equals("get_class_summary")) return json(cls.summary());
|
||||
if (name.equals("get_class_summary"))
|
||||
return json(flag(args, "dex_static_values") ? cls.summaryWithValues() : cls.summary());
|
||||
if (name.equals("get_method_body")) {
|
||||
List<MethodSnapshot> overloads = methods(cls, args);
|
||||
int index = integer(args, "overload_index", 0);
|
||||
@@ -454,7 +513,7 @@ class ReaJadxBridge {
|
||||
"markers", code.getMarkers(), "body", code.getText()));
|
||||
}
|
||||
List<JavaNode> uses;
|
||||
String target = string(args, "class_name");
|
||||
String target = (String) cls.summary().get("full_name");
|
||||
MethodSnapshot selectedMethod = null;
|
||||
int overloadIndex = 0;
|
||||
if (name.equals("get_xrefs_to_class")) uses = cls.node().getUseIn();
|
||||
@@ -522,7 +581,7 @@ class ReaJadxBridge {
|
||||
SessionHolder holder = new SessionHolder(defaults);
|
||||
ServerCapabilities capabilities = new ServerCapabilities(
|
||||
new ServerCapabilities.Tools(null), null, null, null, null, null, null, Map.of());
|
||||
Server server = new Server(new Implementation("rea-jadx-bridge", "5", null, null, null),
|
||||
Server server = new Server(new Implementation("rea-jadx-bridge", "7", null, null, null),
|
||||
new ServerOptions(capabilities), "", ignored -> Unit.INSTANCE);
|
||||
SessionToolsKt.registerSessionTools(server, holder);
|
||||
ClassToolsKt.registerClassTools(server, holder);
|
||||
@@ -564,9 +623,12 @@ class ReaJadxBridge {
|
||||
if (name.equals("list_classes")) properties.put("query",
|
||||
new kotlinx.serialization.json.JsonObject(Map.of(
|
||||
"type", kotlinx.serialization.json.JsonElementKt.JsonPrimitive("string"))));
|
||||
if (name.equals("get_class_summary")) properties.put("dex_static_values",
|
||||
new kotlinx.serialization.json.JsonObject(Map.of(
|
||||
"type", kotlinx.serialization.json.JsonElementKt.JsonPrimitive("boolean"))));
|
||||
String description = switch (name) {
|
||||
case "list_classes" -> "Pages of case-sensitive matching top-level class names; offset and next_offset are inventory positions, limit bounds matching rows. Omitted or empty query inventories all names.";
|
||||
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation.";
|
||||
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation. Set dex_static_values to include encoded static final field values.";
|
||||
case "get_method_body" -> "Source for an exact class and stable same-name overload index; static initializers use smali to preserve folded field initialization.";
|
||||
default -> "Complete static using-node inventory for an exact class or selected method overload; one node may contain multiple invoke instructions, and source lines are unresolved.";
|
||||
};
|
||||
|
||||
@@ -404,6 +404,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
writeSuccess(writer, request.id, result);
|
||||
return;
|
||||
}
|
||||
decompileTimeoutSeconds = request.decompileTimeoutSeconds() == null
|
||||
? descriptor.decompileTimeoutSeconds() : request.decompileTimeoutSeconds();
|
||||
writeSuccess(writer, request.id, handleRequest(request, descriptor));
|
||||
}
|
||||
catch (RequestFailure failure) {
|
||||
@@ -643,6 +645,9 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
mapping.addProperty("initialized", block.isInitialized());
|
||||
mapping.addProperty("loaded", block.isLoaded());
|
||||
mapping.addProperty("overlay", block.isOverlay());
|
||||
mapping.addProperty("readable", block.isRead());
|
||||
mapping.addProperty("writable", block.isWrite());
|
||||
mapping.addProperty("executable", block.isExecute());
|
||||
mapping.addProperty("length", source.getLength());
|
||||
FileBytes backing = source.getFileBytes().orElse(null);
|
||||
int sourceIndex = backing == null ? -1 : files.indexOf(backing);
|
||||
@@ -3378,7 +3383,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
"decompile_timed_out",
|
||||
"Ghidra decompilation of " + canonicalAddress(function.getEntryPoint()) +
|
||||
" exceeded the " + decompileTimeoutSeconds +
|
||||
"-second limit set by REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS"
|
||||
"-second configured decompilation limit (ghidra.decompile_timeout_seconds; launch seed REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS)"
|
||||
);
|
||||
}
|
||||
if (!results.decompileCompleted()) {
|
||||
@@ -4768,7 +4773,18 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
}
|
||||
|
||||
private static Request parseRequest(String line, String expectedToken) {
|
||||
JsonObject object = requireObject(JsonParser.parseString(line), REQUEST_KEYS);
|
||||
JsonElement parsed = JsonParser.parseString(line);
|
||||
Set<String> keys = new HashSet<>(REQUEST_KEYS);
|
||||
if (parsed.isJsonObject() && parsed.getAsJsonObject().has("decompile_timeout_seconds"))
|
||||
keys.add("decompile_timeout_seconds");
|
||||
JsonObject object = requireObject(parsed, keys);
|
||||
Integer timeout = null;
|
||||
if (object.has("decompile_timeout_seconds")) {
|
||||
JsonElement value = object.get("decompile_timeout_seconds");
|
||||
timeout = value.isJsonNull() ? 0 : requireInteger(object, "decompile_timeout_seconds");
|
||||
if (!value.isJsonNull() && (timeout < 1 || timeout > MAX_DECOMPILE_TIMEOUT_SECONDS))
|
||||
throw new IllegalArgumentException("Invalid per-request decompile deadline");
|
||||
}
|
||||
int id = requireInteger(object, "id");
|
||||
if (id <= 0 || !constantTimeEquals(requireString(object, "token"), expectedToken)) {
|
||||
throw new IllegalArgumentException("Bridge request authentication failed");
|
||||
@@ -4777,7 +4793,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
if (params == null || !params.isJsonObject()) {
|
||||
throw new IllegalArgumentException("Bridge request parameters are invalid");
|
||||
}
|
||||
return new Request(id, requireString(object, "method"), params.getAsJsonObject());
|
||||
return new Request(id, requireString(object, "method"), params.getAsJsonObject(), timeout);
|
||||
}
|
||||
|
||||
private static JsonObject requireObject(JsonElement element, Set<String> keys) {
|
||||
@@ -4971,7 +4987,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
JsonArray analysisExtensions,
|
||||
int decompileTimeoutSeconds
|
||||
) {}
|
||||
private record Request(int id, String method, JsonObject params) {}
|
||||
private record Request(int id, String method, JsonObject params, Integer decompileTimeoutSeconds) {}
|
||||
|
||||
private static final class RequestFailure extends RuntimeException {
|
||||
private final String code;
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.model.mem.MemoryBlockSourceInfo;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Rebuild a GameCube/Wii DOL memory map from the validated load ranges REA's TypeScript
|
||||
* admission wrote. BinaryLoader maps the whole file once at address 0; this
|
||||
* script replaces that block with text, data, and BSS blocks at their load addresses.
|
||||
*/
|
||||
public final class ReaGhidraPrepareDol extends GhidraScript {
|
||||
// Canonical v2 header, 18 section rows, 12 gap rows and entry, using uint32 hex.
|
||||
private static final int MAX_PLAN_BYTES = 13 + 18 * 49 + 12 * 30 + 17;
|
||||
private static final class Section {
|
||||
final String kind;
|
||||
final int index;
|
||||
final long fileOffset;
|
||||
final long address;
|
||||
final long size;
|
||||
|
||||
Section(String kind, int index, long fileOffset, long address, long size) {
|
||||
this.kind = kind;
|
||||
this.index = index;
|
||||
this.fileOffset = fileOffset;
|
||||
this.address = address;
|
||||
this.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
private record BssGap(long address, long size) {}
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
String[] arguments = getScriptArgs();
|
||||
if (arguments.length != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"GameCube DOL preparation requires exactly one section table path"
|
||||
);
|
||||
}
|
||||
if (!currentProgram.getExecutableFormat().equals("Raw Binary") ||
|
||||
!currentProgram.getLanguageID().getIdAsString().startsWith("PowerPC:BE:32:")) {
|
||||
throw new IllegalArgumentException(
|
||||
"GameCube DOL preparation requires a BinaryLoader import in big-endian 32-bit PowerPC"
|
||||
);
|
||||
}
|
||||
Path tablePath = Path.of(arguments[0]);
|
||||
if (!Files.isRegularFile(tablePath, LinkOption.NOFOLLOW_LINKS)) {
|
||||
throw new IllegalArgumentException("GameCube DOL section table is not a regular file");
|
||||
}
|
||||
if (Files.size(tablePath) > MAX_PLAN_BYTES) {
|
||||
throw new IllegalArgumentException("GameCube DOL plan exceeds the canonical format's byte bound");
|
||||
}
|
||||
|
||||
List<Section> sections = new ArrayList<>();
|
||||
List<BssGap> bssGaps = new ArrayList<>();
|
||||
int expectedSections = -1;
|
||||
int expectedGaps = -1;
|
||||
long entry = -1;
|
||||
for (String line : Files.readAllLines(tablePath)) {
|
||||
String[] fields = line.trim().split("\\s+");
|
||||
switch (fields[0]) {
|
||||
case "plan" -> {
|
||||
requireFields(fields, 4, line);
|
||||
if (expectedSections >= 0 || !fields[1].equals("2")) {
|
||||
throw new IllegalArgumentException("Duplicate or unsupported GameCube DOL plan header");
|
||||
}
|
||||
expectedSections = Integer.parseInt(fields[2]);
|
||||
expectedGaps = Integer.parseInt(fields[3]);
|
||||
// A DOL has 18 slots, including at most 11 data slots and 12 BSS gaps.
|
||||
if (expectedSections < 1 || expectedSections > 18 || expectedGaps < 0 || expectedGaps > 12) {
|
||||
throw new IllegalArgumentException("GameCube DOL plan counts exceed the format's slot bounds");
|
||||
}
|
||||
}
|
||||
case "section" -> {
|
||||
requireFields(fields, 6, line);
|
||||
if (expectedSections < 0 || sections.size() >= expectedSections) {
|
||||
throw new IllegalArgumentException("GameCube DOL section exceeds its declared count");
|
||||
}
|
||||
sections.add(new Section(
|
||||
fields[1],
|
||||
Integer.parseInt(fields[2]),
|
||||
Long.decode(fields[3]),
|
||||
Long.decode(fields[4]),
|
||||
Long.decode(fields[5])
|
||||
));
|
||||
}
|
||||
case "bss-gap" -> {
|
||||
requireFields(fields, 3, line);
|
||||
if (expectedGaps < 0 || bssGaps.size() >= expectedGaps) {
|
||||
throw new IllegalArgumentException("GameCube DOL BSS gap exceeds its declared count");
|
||||
}
|
||||
long address = Long.decode(fields[1]);
|
||||
long size = Long.decode(fields[2]);
|
||||
if (address < 0 || size <= 0) {
|
||||
throw new IllegalArgumentException("GameCube DOL BSS gap is not a positive range");
|
||||
}
|
||||
bssGaps.add(new BssGap(address, size));
|
||||
}
|
||||
case "entry" -> {
|
||||
requireFields(fields, 2, line);
|
||||
entry = Long.decode(fields[1]);
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Unknown GameCube DOL table line: " + line);
|
||||
}
|
||||
}
|
||||
if (expectedSections != sections.size() || expectedGaps != bssGaps.size() || entry < 0) {
|
||||
throw new IllegalArgumentException("GameCube DOL section table is incomplete");
|
||||
}
|
||||
|
||||
Memory memory = currentProgram.getMemory();
|
||||
List<FileBytes> files = memory.getAllFileBytes();
|
||||
if (files.size() != 1) {
|
||||
throw new IllegalStateException("GameCube DOL preparation requires exactly one imported file image");
|
||||
}
|
||||
FileBytes fileBytes = files.get(0);
|
||||
AddressSpace space = currentProgram.getAddressFactory().getDefaultAddressSpace();
|
||||
|
||||
// Remove the whole-file block before creating section blocks, so no two blocks claim one address.
|
||||
for (MemoryBlock block : memory.getBlocks()) {
|
||||
for (MemoryBlockSourceInfo source : block.getSourceInfos()) {
|
||||
if (source.getFileBytes().isPresent() && source.getFileBytes().get().equals(fileBytes)) {
|
||||
memory.removeBlock(block, monitor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Section section : sections) {
|
||||
if (section.fileOffset + section.size > fileBytes.getSize()) {
|
||||
throw new IllegalArgumentException(
|
||||
"GameCube DOL " + section.kind + " " + section.index + " exceeds the imported file"
|
||||
);
|
||||
}
|
||||
boolean text = section.kind.equals("text");
|
||||
if (!text && !section.kind.equals("data")) {
|
||||
throw new IllegalArgumentException("Unknown GameCube DOL section kind: " + section.kind);
|
||||
}
|
||||
MemoryBlock block = memory.createInitializedBlock(
|
||||
"." + section.kind + section.index,
|
||||
space.getAddress(section.address),
|
||||
fileBytes,
|
||||
section.fileOffset,
|
||||
section.size,
|
||||
false
|
||||
);
|
||||
block.setRead(true);
|
||||
block.setWrite(!text);
|
||||
block.setExecute(text);
|
||||
}
|
||||
|
||||
// Apply the domain owner's exact uninitialized ranges; do not reinterpret BSS here.
|
||||
int gapIndex = 0;
|
||||
for (BssGap gap : bssGaps) {
|
||||
MemoryBlock block = memory.createUninitializedBlock(
|
||||
".bss" + gapIndex++,
|
||||
space.getAddress(gap.address()),
|
||||
gap.size(),
|
||||
false
|
||||
);
|
||||
block.setRead(true);
|
||||
block.setWrite(true);
|
||||
block.setExecute(false);
|
||||
}
|
||||
|
||||
Address entryAddress = space.getAddress(entry);
|
||||
MemoryBlock entryBlock = memory.getBlock(entryAddress);
|
||||
if (entryBlock == null || !entryBlock.isExecute()) {
|
||||
throw new IllegalArgumentException("GameCube DOL entry must lie in an executable section");
|
||||
}
|
||||
addEntryPoint(entryAddress);
|
||||
if (!disassemble(entryAddress) || createFunction(entryAddress, "__start") == null) {
|
||||
throw new IllegalStateException("GameCube DOL entry cannot be decoded as a function");
|
||||
}
|
||||
currentProgram.getOptions(Program.PROGRAM_INFO).setBoolean("REA raw binary prepared", true);
|
||||
currentProgram.getOptions(Program.PROGRAM_INFO).setBoolean("REA GameCube DOL prepared", true);
|
||||
}
|
||||
|
||||
private static void requireFields(String[] fields, int count, String line) {
|
||||
if (fields.length != count) {
|
||||
throw new IllegalArgumentException("Malformed GameCube DOL table line: " + line);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,11 @@ export default defineConfig({
|
||||
{ text: "Model artifacts", link: "/model-artifacts" },
|
||||
{ text: "Rust dependencies", link: "/rust-binaries" },
|
||||
{ text: "PE certificates", link: "/pe-certificates" },
|
||||
{ text: "PE imports", link: "/pe-imports" },
|
||||
{ text: "PE TLS/load config", link: "/pe-load-config" },
|
||||
{ text: "ELF notes", link: "/elf-notes" },
|
||||
{ text: "Apple IPS crash reports", link: "/apple-ips" },
|
||||
{ text: "Linux kernel modules", link: "/kernel-modules" },
|
||||
{ text: "CPython pyc files", link: "/python-pyc" },
|
||||
{ text: "Erlang BEAM", link: "/erlang-beam" },
|
||||
{
|
||||
@@ -78,6 +82,7 @@ export default defineConfig({
|
||||
{ text: "Ghidra raw binary", link: "/raw-binary" },
|
||||
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
|
||||
{ text: "Ghidra PowerPC", link: "/ghidra-ppc" },
|
||||
{ text: "Ghidra GameCube DOL", link: "/ghidra-dol" },
|
||||
{ text: "Ghidra semantics", link: "/ghidra-provider" },
|
||||
],
|
||||
},
|
||||
|
||||
+330
-32
@@ -1,16 +1,20 @@
|
||||
# Agent environments from recorded captures
|
||||
|
||||
Use `rea environment-serve` to serve an environment manifest as an agent
|
||||
environment: an MCP server whose tools answer from what one retained web
|
||||
network capture observed, plus the environment card the agentenv framework
|
||||
reads to discover it. By default the server derives the
|
||||
[state the capture observed](#the-state-a-capture-observed) at startup and
|
||||
answers read tools from it, and the write tools whose effect the capture
|
||||
confirmed by changing it; `--replay-only` replays the capture's records
|
||||
Use `rea environment-build` to turn one recorded capture into an agent
|
||||
environment bundle in one offline step: a folder `agent-env run` builds and
|
||||
runs, whose MCP server answers from what the capture observed. See
|
||||
[Build a bundle in one step](#build-a-bundle-in-one-step).
|
||||
|
||||
The steps it composes are separate commands too. `rea environment-serve` serves
|
||||
an environment manifest as an agent environment: an MCP server whose tools
|
||||
answer from what one retained web network capture observed, plus the
|
||||
environment card the agentenv framework reads to discover it. By default the
|
||||
server derives the [state the capture observed](#the-state-a-capture-observed)
|
||||
at startup and answers read tools from it, and the write tools whose effect the
|
||||
capture confirmed by changing it; `--replay-only` replays the capture's records
|
||||
instead. Nothing is fetched from the recorded application; every answer comes
|
||||
from retained Evidence. `rea environment-export` writes the same pair as a
|
||||
bundle folder `agent-env run` builds and runs; see
|
||||
[Export a bundle](#export-a-bundle).
|
||||
bundle folder; see [Export a bundle](#export-a-bundle).
|
||||
|
||||
```sh
|
||||
rea inspect-web-network-capture /absolute/session.har har --format json > capture.json
|
||||
@@ -36,6 +40,185 @@ The third command serves that manifest from the state it derives from the
|
||||
capture; see [Serve from the state](#serve-from-the-state). Both served files
|
||||
are complete REA Evidence JSON as the commands write it with `--format json`;
|
||||
the `evidence` member of `view.json` is the whole of `capture.json`.
|
||||
A `view.json` can also name the capture file as
|
||||
`{"kind": "evidence-file", "path": "capture.json"}`, which projects it as
|
||||
retained Evidence instead of charging the whole capture as inline input.
|
||||
|
||||
## Build a bundle in one step
|
||||
|
||||
```sh
|
||||
rea environment-build grafana.har ./grafana --json
|
||||
agent-env run ./grafana
|
||||
```
|
||||
|
||||
`rea environment-build <capture> [directory]` takes a `.har` file, or capture
|
||||
Evidence JSON from `inspect-web-network-capture` (HAR) or
|
||||
`capture-browser-scenario`, and writes the bundle
|
||||
[Export a bundle](#export-a-bundle) describes. It inspects a HAR as
|
||||
`inspect-web-network-capture` does (Evidence input skips this), projects the
|
||||
environment manifest from that Evidence as retained Evidence, authenticates
|
||||
the pair, prepares the state the bundle's server derives at startup, and
|
||||
writes the bundle with the export. For the same capture path, every file it
|
||||
writes is byte-identical to what `inspect-web-network-capture`,
|
||||
`inspect-analysis-view` and `environment-export` write, Evidence ids included,
|
||||
when `view.json` lists the same rules in the views' order and the export is
|
||||
given the build's name. It reads one file and writes one folder: it fetches
|
||||
nothing and launches no browser (HAR inspection runs REA's own decoder
|
||||
process), so record a browser scenario with `capture-browser-scenario` first
|
||||
and pass its Evidence. Other capture formats are refused, as the manifest view
|
||||
refuses them, and a HAR document saved as `.json` is refused with a hint to
|
||||
name it `.har`.
|
||||
|
||||
- `--template-rule <rule>`, repeated, replaces the default opt-in rules
|
||||
`after-uid-literal`, `opaque-token`, `sibling-variance` and
|
||||
`prefix-variance`, the rules the published capture-built environments use;
|
||||
`--format-rules-only` applies none, the views' own default. Rules apply in
|
||||
the views' fixed order, the report lists them, and a repeated rule is
|
||||
refused as the views refuse it.
|
||||
- `--name` names the env folder and env id. Without it the name is the
|
||||
manifest's, unless the capture's origin is a loopback name or an IP literal:
|
||||
the capture file then names it (`grafana.har` and `grafana.capture.json`
|
||||
become `grafana`) and a `name-from-file` warning says so. A file name that
|
||||
yields no portable label (kebab-case, at most 64 characters, not a Windows
|
||||
device name) is refused; pass `--name`.
|
||||
- `--package-tarball` works as for the export, and `--capture-timeout-ms`
|
||||
as for `inspect-web-network-capture`.
|
||||
- `--dry-run` runs every stage and prints the report with `status: "planned"`
|
||||
and the files a build would write, but writes nothing and does not check the
|
||||
directory, which may then be omitted. It reads and hashes a
|
||||
`--package-tarball` as a build does before copying it, so it refuses the
|
||||
tarballs a build refuses, including one whose contents cannot be read.
|
||||
|
||||
The directory must be absent or empty, as for the export; the build never
|
||||
replaces a folder. A refusal before the write leaves nothing behind. A capture
|
||||
Evidence file, an inspected HAR's Evidence and the projected manifest must each
|
||||
fit the live heap headroom for parsing and sealing, checked before the file is
|
||||
read or the Evidence serialized; one that does not is refused as
|
||||
`resource_constraint`. Each
|
||||
refusal names its stage: `environment-build` for the build's own checks,
|
||||
`inspect_web_network_capture` and `inspect_analysis_view` for inspection and
|
||||
projection, `environment-export` for the bundle. SIGINT cancels the build
|
||||
(`cancelled`); before the bundle stage nothing is written, and a cancellation
|
||||
during the write names the bundle it wrote. Stage progress is logged to stderr
|
||||
at info level; the report is the only output on stdout:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "built",
|
||||
"directory": "/work/grafana",
|
||||
"name": "grafana",
|
||||
"capture": {
|
||||
"evidence_id": "ev_…",
|
||||
"operation": "inspect_web_network_capture",
|
||||
"records": 105,
|
||||
"input": "har"
|
||||
},
|
||||
"manifest": {
|
||||
"evidence_id": "ev_…",
|
||||
"tools": 48,
|
||||
"excluded_groups": 0,
|
||||
"template_rules": [
|
||||
"after-uid-literal",
|
||||
"opaque-token",
|
||||
"sibling-variance",
|
||||
"prefix-variance"
|
||||
]
|
||||
},
|
||||
"state": { "served": true, "evidence_id": "ev_…" },
|
||||
"coverage": {
|
||||
"reads": {
|
||||
"state": 36,
|
||||
"recorded": 6,
|
||||
"recorded_reasons": { "query-varies": 3, "…": 1 }
|
||||
},
|
||||
"writes": {
|
||||
"served": [{ "tool": "delete_folders_by_uid", "effect": "delete" }],
|
||||
"withheld": [
|
||||
{
|
||||
"tool": "post_folders",
|
||||
"effect": "create",
|
||||
"reason": "unconfirmed",
|
||||
"hint": "No later read showed the effect. Read the entity and its list after the write.",
|
||||
"exemplar_ordinal": 94,
|
||||
"contradicted_by": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"tool_count": 37,
|
||||
"package_source": { "kind": "registry", "specifier": "rea-agents@…" },
|
||||
"files": [{ "path": "README.md", "bytes": 4210 }],
|
||||
"warnings": [{ "code": "name-from-file", "message": "…" }],
|
||||
"next": ["agent-env run /work/grafana"]
|
||||
}
|
||||
```
|
||||
|
||||
`coverage` is the state's read views and write plans summarized, and `null`
|
||||
when the state is unavailable and the bundle serves replay. The
|
||||
[environment coverage](web-network-captures.md#environment-coverage) view
|
||||
reports the same summary for any capture without building, so an agent can
|
||||
check it after each recording. The view summarizes the state as derived; it
|
||||
does not apply the serve-time admission checks, so for an environment whose
|
||||
served catalog exceeds the discovery budget, or whose state exceeds what
|
||||
`data/add` loads, it still reports the state while the build reports `coverage:
|
||||
null` and the bundle serves replay. Each withheld write carries a hint about
|
||||
what to record next; hints never change what is served:
|
||||
|
||||
| Reason | Hint |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `no-state-target` | The write's path names no collection or item the capture reads. Read the collection or item it changes. |
|
||||
| `no-call` | No recorded call of this tool was modelled, for example because every call failed. Record a successful call. |
|
||||
| `body-unusable` | The retained request or response cannot be modelled. Record a successful call with a complete supported request and reproducible response. |
|
||||
| `no-observation` | Nothing showed the entity or document this write changed. Read a created entity back by id right after the write; for an update or delete the state must already hold the entity, so read it before the write or record the create that made it. |
|
||||
| `unexplained-change` | The write changed fields it did not send, in a way no rule explains. A second, different call of the same tool can show the pattern. |
|
||||
| `contradicted` | A later read disagreed with the modelled effect. Check the read at contradicted_by. |
|
||||
| `side-effect` | The write changed something besides its own entity, which the environment does not model. |
|
||||
| `unconfirmed` | No later read showed the effect. Read the entity and its list after the write. |
|
||||
| `incomplete-entities` | The write is confirmed, but the views that show its entity cannot render it in full. Read the written entity through every view that lists it. |
|
||||
|
||||
The bundle ships `evidence.json`, the whole capture Evidence, response bodies
|
||||
included. Inspection excludes the values of the standard authentication headers
|
||||
(`Authorization`, `Cookie` and `Set-Cookie` among them) and URL userinfo; a
|
||||
custom key header such as `X-Api-Key`, a token in the query string and tokens
|
||||
an application returns in bodies remain. The environment views refuse captures
|
||||
inspected with `--sensitive-value`, so scrub a capture before building it. The
|
||||
report's `credential-named-members` warning counts recorded header names, query
|
||||
parameter names and JSON or form body members whose names look like
|
||||
credentials (whole name segments such as `token`, `secret`, `password`,
|
||||
`api_key`, `authorization` or `session`) and hold a value, and lists the first
|
||||
20 by record and pointer, never by value. A body is read as a form or as JSON by
|
||||
its recorded media type, or by its shape when it has none or one naming
|
||||
neither. A browser scenario is
|
||||
scanned by event (`event 4 response /token` names
|
||||
`normalized_result.events.items[4]`): every retained request and response
|
||||
content event, including a response whose request began before the browser was
|
||||
attached and a transaction no record represents, and each transaction URL's
|
||||
query once. Bodies larger than 4 MiB of UTF-8 text are not
|
||||
scanned; `credential-scan-incomplete` counts them and lists up to 20 record or
|
||||
event pointers, including base64 bodies whose decoded scan was cut. An empty name
|
||||
warning does not establish that these bodies were checked. Names do not establish sensitivity,
|
||||
so the build never refuses on them. Capture
|
||||
|
||||
Evidence also records the capture file's absolute path (`subject.local_path`,
|
||||
`parameters.capture_path`, `locations`, `artifact.path`), and the bundle
|
||||
carries it: build from a neutral folder when that path should not ship.
|
||||
|
||||
Over MCP, `export_environment_bundle` builds the same bundle and returns the
|
||||
same report. Its `source` is capture Evidence the session retained
|
||||
(`{"kind": "retained-evidence", "evidence_id"}`), such as a
|
||||
`capture_browser_scenario` or `inspect_web_network_capture` result, or a
|
||||
capture Evidence file (`{"kind": "evidence-file", "path"}`); inspect a HAR with
|
||||
`inspect_web_network_capture` first. Retained Evidence is written into the
|
||||
bundle as `--format json` writes it, so the bundle is the one
|
||||
`environment-build` writes from that file. `output_directory` must be an
|
||||
absolute path that does not exist yet, whose parent does; the tool creates it
|
||||
and refuses an existing directory, empty or not. `name`, `template_rules`,
|
||||
`package_tarball` and `dry_run` work as `--name`, `--template-rule`,
|
||||
`--package-tarball` and `--dry-run` do, and retained Evidence has no file to
|
||||
name the environment after, so a loopback or IP origin needs `name`. Unlike
|
||||
`--dry-run`, `dry_run` still checks `output_directory`. Destination refusals
|
||||
name `export_environment_bundle`; the others name their stage as
|
||||
`environment-build`'s do.
|
||||
|
||||
## From a browser scenario
|
||||
|
||||
@@ -125,6 +308,51 @@ the replayed body is the bytes the browser exposes for each response, with any
|
||||
declared secret replaced by its redaction marker (a body that redaction had to
|
||||
empty replays no body).
|
||||
|
||||
To record writes, sign in through the UI and then send the application's API
|
||||
calls with [request steps](browser-scenario-contract.md#request-steps): each
|
||||
sends one request to the start origin through the page's own `fetch`, with the
|
||||
session's cookies, and a header can carry the CSRF cookie or stored token the
|
||||
application's own requests send. A write is served only when the capture shows
|
||||
its effect, so read each collection before writing, read every written entity
|
||||
back by id and in its list right after the write, and leave more than a second
|
||||
between a create and its first edit. A request step's path is fixed when the
|
||||
scenario is written and cannot use a value an earlier response returned, so an
|
||||
id must be known before the run: one the caller chooses, such as a `uid` in the
|
||||
create body, or one an earlier scenario created. When the server assigns ids,
|
||||
read the list after each create (the create's response or the list shows the
|
||||
new entity), and record updates and deletes in a second scenario that reads
|
||||
the first one's objects by id before editing them, or make them through the
|
||||
UI. The environment coverage view names each
|
||||
write it withholds and what to record next. A scenario with write requests
|
||||
changes the application's data: record against an instance whose data may
|
||||
change.
|
||||
|
||||
```json
|
||||
{
|
||||
"step_id": "create-folder-1",
|
||||
"action": "request",
|
||||
"method": "POST",
|
||||
"path": "/api/folders",
|
||||
"headers": [
|
||||
{
|
||||
"name": "X-CSRFToken",
|
||||
"value": { "source": "cookie", "name": "csrftoken" }
|
||||
}
|
||||
],
|
||||
"json": { "title": "Scratch folder 1" },
|
||||
"expected_status": [200, 201]
|
||||
}
|
||||
```
|
||||
|
||||
Each record takes its start and duration from the browser's timing (the time
|
||||
the scenario observed the request where the browser reported no start), so the
|
||||
state orders and overlaps
|
||||
records as it does a HAR's and learns a write clock: an update the application
|
||||
stamps with a modification time can be served. A scenario captured before
|
||||
these times were recorded has none; its records keep request order and the
|
||||
state learns no clock, so such updates stay `unexplained-change` until it is
|
||||
recorded again.
|
||||
|
||||
## What a manifest is
|
||||
|
||||
An environment manifest is a projection of one application's recorded request
|
||||
@@ -431,12 +659,12 @@ member reports which applied:
|
||||
|
||||
Each read tool answers according to its view in the state:
|
||||
|
||||
| View | Answer |
|
||||
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `item` | The entity the path arguments name, rendered into the recorded envelope of `envelope_ordinal`. Arguments match as replay matches them: each collection segment equals the held collection's segment as written or after percent-decoding, and the identity is the last argument percent-decoded, then as written; values are never re-split on `/`. Any entity the state holds answers, including one `data/add` loaded; query arguments only decide `replay.exact_match`. An entity the state does not hold answers the tool's latest recorded 400, 404 or 410 response with `state.view` `missing`, or is a tool error when none was recorded; one lacking a field every recording carried is a tool error, unless a read showed the application leaves that field out; a body is never invented. |
|
||||
| `list` | When the arguments name one of the lines the view checked exactly (its latest recordings before the first related write; every path and query value equal to the recording's, and every recorded query parameter supplied), that recorded envelope with its array rendered from the state: every entity of the collection in state order for `membership: "all"` or a line `all_record_ordinals` names, or the recorded members still held. A call with no query argument answers from such a line of the collection its path arguments name that only pages its list, with `replay.exact_match` false. On a line the view's `query` answers, and for a call whose every query argument has a role there (an argument-less call aside), the answer is the query evaluated over the state: filtered, searched, sorted and paged, with counters at the number listed and `query.totals` at the number matched, and `state.membership: "query"`; such a call answers on a query or whole line of its collection with `replay.exact_match` false. A value an `inert` parameter never recorded, or a parameter without a role, replays its recording. A member lacking a field every recording carried makes the call a tool error rather than a partial list. |
|
||||
| `document` | When the arguments name the document's checked line exactly, the state's value for it; a tool error when the state holds none. |
|
||||
| `recorded` | The recording, as replay answers it. |
|
||||
| View | Answer |
|
||||
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `item` | The entity the path arguments name, rendered into the recorded envelope of `envelope_ordinal`, whose `per_response_members` (such as a request id), like a list's or a document's, keep their recorded values. Arguments match as replay matches them: each collection segment equals the held collection's segment as written or after percent-decoding, and the identity is the last argument percent-decoded, then as written; values are never re-split on `/`. Any entity the state holds answers, including one `data/add` loaded; query arguments only decide `replay.exact_match`, except that a call matching one of the view's `projected_query_keys`, or on a view with `projected_record_ordinals` asking for some fields only with a value other than `*` no checked line gave or one a replayed read gave, replays its recording. An entity the state does not hold answers the tool's latest recorded 400, 404 or 410 response with `state.view` `missing`, or is a tool error when none was recorded; one lacking a field every recording carried is a tool error, unless a read showed the application leaves that field out; a body is never invented. |
|
||||
| `list` | When the arguments name one of the lines the view checked exactly (its latest recordings before the first related write; every path and query value equal to the recording's, and every recorded query parameter supplied), that recorded envelope with its array rendered from the state: every entity of the collection in state order for `membership: "all"` or a line `all_record_ordinals` names, or the recorded members still held. A call with no query argument answers from such a line of the collection its path arguments name that only pages its list, with `replay.exact_match` false. On a line the view's `query` answers, and for a call whose every query argument has a role there (an argument-less call aside), the answer is the query evaluated over the state: filtered, searched, sorted and paged, with counters at the number listed and `query.totals` at the number matched, and `state.membership: "query"`; such a call answers on a query or whole line of its collection with `replay.exact_match` false. A value an `inert` parameter never recorded, a parameter without a role, a call matching one of the view's `projected_query_keys`, or a field selection the checked lines do not show (as for `item`), replays its recording. A member lacking a field every recording carried makes the call a tool error rather than a partial list. |
|
||||
| `document` | When the arguments name the document's checked line exactly, the state's value for it; a tool error when the state holds none. |
|
||||
| `recorded` | The recording, as replay answers it. |
|
||||
|
||||
A read with repeated query values uses replay, because the state query model
|
||||
does not infer repeated-parameter semantics. A repeated-query write is refused
|
||||
@@ -451,18 +679,36 @@ An item or list view that always spells a clock field otherwise than the
|
||||
entity's stored value names that spelling in `clock_formats`, and a value it
|
||||
never recorded, such as a created entity's clock, is rendered in it: a list that
|
||||
writes `+00:00` where item reads write `Z` lists a new entity the same way.
|
||||
A view that names a field in `sorted_arrays` lists that string array sorted, as
|
||||
a read-back showed the application does, while the state keeps it in the order
|
||||
it was written, so a write's own answer echoes it. If a later counted read
|
||||
contradicts that ordering, the view stays recorded and its earlier reads no
|
||||
longer confirm served writes. A view that names a field in `nested_fields`
|
||||
always showed that field's objects with the same keys, in any order, and fewer
|
||||
than an entity stores, such
|
||||
as a list showing a parent without the parent's own nested type; a stored
|
||||
object it never recorded, such as a created entity's parent, is rendered with
|
||||
those keys. Members a view names in
|
||||
`per_response_members`, such as a request id each response mints, keep the
|
||||
value its recording carried. A list's `counters` and `query.totals` are
|
||||
top-level members or members one level down in a paging object
|
||||
(`/pageInfo/totalRows`); either is set to the number listed or matched, and
|
||||
members beside it such as `isLastPage` stay as recorded.
|
||||
|
||||
A list or document call that names no checked line, including a line recorded
|
||||
after a write or with other query values, answers from the recording. Every
|
||||
answer has the replay shape plus `state`: `{"source": "state", "view": …}`
|
||||
naming the entity, collection or document path, or `{"source": "recording",
|
||||
"reason": …}` with the view's reason, `no-view`, `unrecorded-request`, `page-exceeded` (a call naming a page of a whole list that the collection has outgrown) or `projection` (a call to an item tool whose recordings asked for some fields only, naming such a parameter for an entity the state holds; the answer is a recording, so it does not show served writes). A
|
||||
"reason": …}` with the view's reason, `no-view`, `unrecorded-request`, `page-exceeded` (a call naming a page of a whole list that the collection has outgrown), `projection` (a call to an item or list tool with replayed reads asking for a selection of fields the checked lines do not show, or leaving out a projection parameter every checked line names) or `variant` (a call matching another `projected_query_keys` key: a parameter, or a value of one, only lines showing the entities in another representation named, or leaving out a parameter every other line named). A `projection` or `variant` answer is a recording, so it does not show served writes. A
|
||||
state answer carries the base record's status, content type and `replay`
|
||||
provenance with `truncated: false`; one whose JSON would exceed 256 KiB is
|
||||
refused as a `resource_constraint` tool error rather than cut. Extraction does
|
||||
not state-back a document whose rendered JSON exceeds 256 KiB; that read stays
|
||||
recorded (`rendered-oversize`) and replays the captured body. Query `POST`s
|
||||
stay served and answer from their recordings with the reason `query-body`.
|
||||
recorded (`rendered-oversize`) and replays the captured body. Query `POST`s,
|
||||
and `POST` tools the capture shows only reading (a lookup answering as a `GET`
|
||||
did, an RPC tunnel naming read operations, a session renewal), stay served and
|
||||
answer from their recordings with the reason `query-body`; they are not write
|
||||
tools.
|
||||
|
||||
A line establishes whole-collection membership only from the beginning:
|
||||
`offset`, `start`, `_start` and `page` must be zero when present. Positive or
|
||||
@@ -477,20 +723,38 @@ tools are not served, so no call claims a change it does not make; each one's
|
||||
plan states why in its `reason`. A served write changes the live state, which
|
||||
every MCP session and `data/get` then see:
|
||||
|
||||
| Effect | Call |
|
||||
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `create` | Adds an entity to the collection the path names, built from the observed entity with each ruled field taken from the call or generated, at the plan's `insert` position. A plan tied to its exemplar's collection writes only there. |
|
||||
| `update` | Sets the sent members on the entity the path names, constants for members accepted only with their recorded value, and the clock, increment, slug, unique and renewed changes the plan models. |
|
||||
| `delete` | Removes the entity the path names. |
|
||||
| `document` | Merges the body into the plan's document object, or replaces it for `PUT`. |
|
||||
| Effect | Call |
|
||||
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `create` | Adds an entity to the collection the path names, built from the observed entity with each ruled field taken from the call or generated, at the plan's `insert` position. A plan tied to its exemplar's collection writes only there. |
|
||||
| `update` | Sets the sent members on the entity the path names, constants for members accepted only with their recorded value, and the clock, nested clock, increment, slug, stamp, derived, composed, reference, unique and renewed changes the plan models. |
|
||||
| `update` (action) | A `POST`, `PUT` or `PATCH` to an item path plus an action segment (`/{type}/{id}/archive`) sets, on the entity before the segment, each scalar the recorded calls showed the action set (`set`), with any sent members; it is served only when a recorded call found those fields already set, so a toggle never is. |
|
||||
| `delete` | Removes the entity the path names. |
|
||||
| bulk `update` or `delete` | A `DELETE`, `PUT` or `PATCH` at a collection, or a `POST` to it plus `delete`, `remove` or `destroy`, applies its effect to every entity the body names, as recorded: an array of ids or of objects carrying the id field, at the root or as the body's one array member (`{"IDs": […], "Read": true}`). |
|
||||
| `document` | Merges the body into the plan's document object, or replaces it for `PUT`. |
|
||||
|
||||
An update's unsent changes follow the plan's rules. A `held-clock` is a clock
|
||||
the client sends back as it read it and the application stamps anew (Ghost's
|
||||
`updated_at`): the call must send the entity's value and the field takes the
|
||||
write's clock. A `nested-clock` sets the clocks inside an object the entity
|
||||
holds, in that object's recorded format. A `stamp` writes the acting user
|
||||
the entity already names under its `created…by` counterpart into a
|
||||
`modified…by` or `updated…by` field. A `derived` field takes a value showing
|
||||
the one sent member's text that the entity stores nowhere (a field Ghost
|
||||
derives from `html`), only with that member's recorded value. An action's
|
||||
`set` rule sets a scalar to the value the recorded calls left it at.
|
||||
|
||||
Its answer has the status and content type of the plan's recorded response,
|
||||
with the written entity or its identity rendered in, no body, or the recorded
|
||||
body. A call whose body is not an object, sends a member the capture did not
|
||||
show stored, sends a fixed member with another value or a member of another
|
||||
JSON type, or lacks a required member is a tool error naming the accepted
|
||||
members; so is a rendered answer missing a field the recorded response
|
||||
carried, and an update or delete of an entity the state does not hold answers
|
||||
members; so is a call sending query parameters other than the exemplar's (they
|
||||
may change what the body does), a body not wrapped in the exemplar's envelope
|
||||
(Ghost's `{"posts": [{…}]}`), a bulk call naming an id the state does not hold,
|
||||
a `held-clock` member sent with another value than the entity holds, a call
|
||||
sending a `derived` rule's member to an entity that does not hold the value the
|
||||
recorded call found, a nested clock on an entity holding no such object, and a
|
||||
rendered answer missing a field the recorded response carried, and an update or delete of an entity the state does not hold answers
|
||||
the recorded 400, 404 or 410 of the tool or of an item view of the type, if
|
||||
any. A refused call leaves the state unchanged. Values a write generates are
|
||||
deterministic: the clock starts at `write_clock` and advances one second per
|
||||
@@ -499,7 +763,8 @@ largest they generated, and UUIDs and tokens derive from the state Evidence
|
||||
id, tool, field and write count, skipping held values. `data/reset` and
|
||||
`data/add` restart the clock, counter and sequences, so the same calls after a
|
||||
reset give the same state. Answers carry `state: {"source": "state", "view":
|
||||
"create" | "update" | "delete", …}` or `"document-write"`.
|
||||
"create" | "update" | "delete", …}` or `"document-write"`; a bulk answer adds
|
||||
`ids`, every entity it wrote in body order, with `id` naming the first.
|
||||
|
||||
The data plane serves three JSON-RPC methods:
|
||||
|
||||
@@ -654,6 +919,25 @@ after an update and referential rules on delete are not modelled. An exported
|
||||
bundle carries no state file: its server derives the state at startup, as the
|
||||
export does to predict what it serves.
|
||||
|
||||
Known limits of served writes:
|
||||
|
||||
- A recorded view answers from its recordings after a served write: Mailpit's
|
||||
`get_messages`, recorded as `list-differs`, still lists a message a served
|
||||
delete removed.
|
||||
- Served n8n workflow updates accept any `versionId`, while served Ghost post
|
||||
updates require `updated_at` to match the entity (a `held-clock`).
|
||||
- A slug derived from a title can repeat across served creates with the same
|
||||
title, where the application would make it unique.
|
||||
- A `composed` string copies sent text as sent: an application that escapes or
|
||||
renders it (HTML entities, Markdown) differs for text that needs it, as
|
||||
BookStack's `description_html` would for a description holding `&`.
|
||||
- A served create's sequence id is the state's next value, not the gaps an
|
||||
application's own sequence would leave.
|
||||
- Nested clocks are served in the spelling of the write's own response, which
|
||||
can differ from what a later read of the application shows.
|
||||
- A served write to an entity that a replayed (unserved) create made answers
|
||||
as for a missing entity, since the state never held it.
|
||||
|
||||
## Export a bundle
|
||||
|
||||
`rea environment-export` writes the same pair as a bundle folder the agentenv
|
||||
@@ -781,9 +1065,11 @@ Numeric arrays retain that containing field's clock context through nested
|
||||
arrays; an object's own fields establish their own context. Numeric values at
|
||||
the body root, in root arrays, or under measurement fields remain literal.
|
||||
|
||||
Generated strings normalize only where this confirmed, served write's entity
|
||||
response rules identify generation. A `unique` rule or UUID identity rule must
|
||||
still compare two UUIDs; a `renewed` rule applies only at its recorded pointers,
|
||||
Generated values normalize only where this confirmed, served write's entity
|
||||
response rules identify generation. A UUID identity rule must still compare two
|
||||
UUIDs, and a `unique` rule two UUIDs or two generated integers (10 to 20
|
||||
digits) of one JSON kind and length; a `renewed` rule applies only at its
|
||||
recorded pointers,
|
||||
with `*` matching actual array items. Token/sequence strings retain the existing
|
||||
format check: equal length of at least eight, the same character classes, and
|
||||
a digit. Numeric sequences continue to compare literally unless an ID mapping
|
||||
@@ -795,6 +1081,12 @@ Admitted generated values must also preserve aliases and distinct identities
|
||||
within that response. UUID identity uses the generator's case-insensitive
|
||||
matching; token and sequence strings retain their literal identity. This
|
||||
correspondence ends with the answer and is not inferred across calls.
|
||||
A `composed` response field must spell the value its parts build from that
|
||||
response's own fields. Its parts then compare by their rendered text or their
|
||||
source fields' clock and ID rules. A coherent archive URL can therefore differ
|
||||
only in normalized clock digits without reporting a value difference; an
|
||||
incoherent URL still differs even when both sides repeat the same stale text.
|
||||
Normalized compositions count under `generated`; source fields are counted once.
|
||||
The report counts each kind of normalised
|
||||
value; the generation rules remain model-derived facts, rather than new
|
||||
observations of the application.
|
||||
@@ -807,8 +1099,14 @@ remain unchanged. Clock-format comparison and respelling recognize four-digit
|
||||
ISO years `0000`–`0099` as well as later years, with normal calendar validation.
|
||||
Respelling preserves the original value when the target zone would require a year
|
||||
outside `0000`–`9999`; generated writes refuse a clock outside that format.
|
||||
Capture-state extraction still uses millisecond coordinates for request intervals
|
||||
and their ordering, and generated-clock progression compares milliseconds.
|
||||
Capture-state start ordering uses the same exact recorded timestamp facts,
|
||||
including minute-only times and fractions longer than nine digits. Recorded
|
||||
spellings may use `T` or a space, `Z` or an extended/compact offset, or no zone
|
||||
(interpreted as UTC). Equal starts use ordinal order; a missing or unreadable
|
||||
start makes the capture use record order. Request interval and overlap checks
|
||||
still use millisecond coordinates, and generated-clock progression compares
|
||||
milliseconds. Derived ISO clock formats still require seconds and at most nine
|
||||
fractional digits.
|
||||
|
||||
Comparison keeps response representations distinct: JSON values compare structurally, text compares as text, and a
|
||||
retained base64 body compares by bytes (including with UTF-8 text carrying those same bytes), never by its base64
|
||||
|
||||
@@ -34,6 +34,53 @@ One-shot CLI output remains complete. Older servers require the existing complet
|
||||
request after schema discovery. APK authenticity and runtime behavior remain
|
||||
unverified.
|
||||
|
||||
## Manifest component projection
|
||||
|
||||
`inspect_android_package` also returns a static inventory of declared
|
||||
activities, aliases, services, receivers and providers from the decoded
|
||||
manifest. `declared_name` preserves the source attribute; `name` resolves a
|
||||
relative name only when the manifest package is known and the resolved copy
|
||||
fits the UTF-8 byte budget. An unresolved package or exhausted name budget
|
||||
retains the declared name and marks the inventory partial. Empty component
|
||||
names and names with forbidden DEX characters retain their raw spelling and
|
||||
are not treated as identities. Valid DEX spaces, including boundary spaces,
|
||||
are preserved when resolving component names and matching alias targets.
|
||||
Whitespace in the manifest package is rejected by its separate package grammar.
|
||||
Component permissions inherit the application
|
||||
permission when no component permission is declared, except an activity alias
|
||||
with no permission: Android documents that case as requiring no permission
|
||||
through the alias. `permission_source` distinguishes a local declaration,
|
||||
inherited value, no requirement (including an explicit empty override), and a
|
||||
value omitted because its resource/manifest-placeholder token is unresolved
|
||||
or the total permission-byte budget was reached. Resource and placeholder
|
||||
references are not expanded at this parser boundary. Repeated inherited
|
||||
values share one inventory-wide byte budget.
|
||||
Provider `android:readPermission` and `android:writePermission` overrides are
|
||||
not projected as separate fields; their presence marks the inventory partial
|
||||
and is called out in `limitations`. Relative component names are not resolved
|
||||
against a manifest package with surrounding whitespace.
|
||||
Class-name segments follow DEX `SimpleName` characters, including a leading
|
||||
digit or hyphen, rather than Java source identifier rules. Relative-name
|
||||
expansion does not prove class existence, DEX-version compatibility or runtime
|
||||
loadability. SDK defaults accept JADX's decimal and hexadecimal integer
|
||||
spellings; the original SDK declaration strings remain unchanged.
|
||||
|
||||
`exported` is the declared literal `true` or `false`, otherwise null.
|
||||
`exported_default` is the documented default only where it can be established;
|
||||
it remains null for unknown provider target SDKs, nonliteral declarations, or
|
||||
components with filters targeting API 31 or later that omit the now-required
|
||||
explicit declaration. A limitation records the latter validation error.
|
||||
Provider authorities and all inventory dimensions are bounded. `status:
|
||||
"partial"` and `limitations` identify omitted declarations or values; a
|
||||
capacity limitation appears only when an actual collection limit was reached.
|
||||
The projection does not merge manifests, expand resource references, or
|
||||
observe runtime enabled/export state.
|
||||
|
||||
The service `foreground_service_type` field preserves the declared attribute,
|
||||
including an empty value or surrounding spaces; `null` means the attribute is
|
||||
absent or the component is not a service. This field does not validate service
|
||||
type tokens or establish runtime eligibility.
|
||||
|
||||
## Supply tools
|
||||
|
||||
Use a **full JDK 17 or newer** (including its compiler module) and
|
||||
@@ -147,6 +194,21 @@ queries accept the same `overload_index`; the bridge resolves the selected
|
||||
method node and the result reports its index and displayed signature. These
|
||||
indices are tied to the current artifact and engine, not stable across builds.
|
||||
|
||||
`inspect_android_class` also reports `dex_static_value` for each `static final`
|
||||
field whose class definition encodes a value in its DEX static values, so
|
||||
compile-time constants are readable even when the class has no `<clinit>`.
|
||||
Each value is typed: `boolean`, `byte`, `short`, `char` (UTF-16 code unit) and
|
||||
`int` values are JSON booleans or numbers, while `long`, `float` and `double`
|
||||
values are strings holding Java's text for the value, so 64-bit values stay
|
||||
exact. The field reports `null` when no value is encoded, the encoded value is
|
||||
null or of another kind, or the field is not `static final`. The value is read from parsed
|
||||
metadata without generating source, and a static initializer can still assign
|
||||
the field; use `inspect_android_method` on `<clinit>` for that evidence.
|
||||
Only `inspect_android_class` asks the bridge for these values.
|
||||
`inspect_android_method` and `trace_android_references` read the member-only
|
||||
class summary, so large encoded strings cannot push their member lookup past
|
||||
the 8 MiB protocol frame limit.
|
||||
|
||||
Smali fallbacks select one complete block using the original method name and DEX
|
||||
descriptor, before applying the source byte limit. This preserves the selected
|
||||
overload even when Java code generation renames a method. If the selected Java
|
||||
@@ -193,6 +255,13 @@ the same source byte limit and explicit truncation reporting.
|
||||
full reported display types, fields and inner class names. Synthetic members
|
||||
that code generation hides can appear in the inventory; it stays consistent
|
||||
after method decompilation within the retained session.
|
||||
Class and method inspection and reference tracing accept either the exact
|
||||
reported class name or its original binary name, including `$` in nested and
|
||||
anonymous classes. The bridge keeps both identities from JADX; it does not
|
||||
replace separators or guess suffix matches. Ambiguous selectors are refused.
|
||||
Follow-up calls preserve the selected name, while results report the frozen
|
||||
JADX display name. Quote `$` names in the shell, for example
|
||||
`'com.example.Manager$WorkerThread'`.
|
||||
Exact DEX prototypes are reported from frozen JADX method metadata as
|
||||
`dex_descriptor`, for example `(I)V`. Display names can be JADX aliases;
|
||||
the descriptor alone is not a complete raw DEX method ID. Overload indices
|
||||
@@ -346,11 +415,17 @@ export REA_JADX_OPERATION_TIMEOUT_MS=600000
|
||||
|
||||
The value must be a decimal millisecond count from 1 to 2147483647; anything
|
||||
else is refused before Java starts. REA reads it from the environment captured
|
||||
at process start. A change applies on the next process start; an already
|
||||
running server keeps the deadline it started with. The same deadline bounds
|
||||
each upstream call. A timeout names `REA_JADX_OPERATION_TIMEOUT_MS`, the
|
||||
effective milliseconds, and that range. A passing JADX configuration check in
|
||||
`rea doctor` reports the effective `operation_timeout_ms`. Explicit
|
||||
at process start. Changing that environment requires a new REA process. On a
|
||||
running MCP server, set `jadx.operation_timeout_ms` through
|
||||
`update_analysis_settings` to change the default for newly accepted operations;
|
||||
queued or running operations retain their accepted budget. The same deadline
|
||||
bounds each upstream call. Timeout recovery reports the effective milliseconds
|
||||
and range, with `details.limit` identifying the runtime setting. An invalid
|
||||
provider-local launch value can also be repaired by a runtime override; reset
|
||||
exposes that invalid launch value again. See the
|
||||
[settings design](design/limits-and-recovery.md#invalid-launch-configuration).
|
||||
A passing JADX configuration check in `rea doctor` reports its launch-derived
|
||||
`operation_timeout_ms`; it does not inspect another running server's overrides. Explicit
|
||||
cancellation still ends the operation immediately, and partial observations
|
||||
and owned-process cleanup are unchanged. Raising the deadline does not extend
|
||||
the bridge's 30-second startup handshake or the upstream **90-second**
|
||||
|
||||
@@ -239,13 +239,19 @@ serialized size of the report together with its limitations (which repeat
|
||||
archive names) is then checked against an 8 MiB output budget (the exact check
|
||||
is authoritative); an over-budget report is refused, not truncated.
|
||||
|
||||
The whole-file reader retains read chunks and a concatenated buffer; total
|
||||
process memory exceeds the selected file's size. It also computes the complete
|
||||
The whole-file reader allocates the selected snapshot and bounded read scratch;
|
||||
total process memory exceeds the selected file's size. It also computes the complete
|
||||
file SHA-256, so inspection is not header-only. Content digests are recomputed
|
||||
at most once per SHA-256/SHA-512 algorithm during one inspection. Input,
|
||||
inflation, decoded-record and serialized-output bounds keep work finite;
|
||||
resource refusals are distinct from malformed format errors.
|
||||
|
||||
If the stable read completes but closing its descriptor fails or is cancelled,
|
||||
the error retains `details.partial_observation` with the selected path, complete
|
||||
file SHA-256 and byte count. These facts describe the acquired file; they do not
|
||||
establish any decoded signing facts. Failed cleanup remains visible until the
|
||||
provider releases the descriptor on a cleanup retry.
|
||||
|
||||
A file that is not a ZIP is refused as an unsupported target. A damaged ZIP
|
||||
(local headers but no end-of-central-directory), a central directory that
|
||||
cannot be walked or whose declared record count does not account for all of
|
||||
|
||||
@@ -93,6 +93,10 @@ still suppresses all string projection, including in this mode.
|
||||
`target.bytes` bind the observation to the exact APK that was decoded.
|
||||
The Evidence subject carries the same snapshot digest and caller-selected
|
||||
path, including when the original file changes during decoding.
|
||||
A change during snapshot acquisition reports retryable `artifact_changed`;
|
||||
wait for a stable input before retrying. Host read permission failures report
|
||||
`access_denied`, while a missing or non-regular selected path reports
|
||||
`invalid_request` with the rejected `path` field.
|
||||
- **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.
|
||||
|
||||
@@ -213,6 +213,9 @@ Resolution follows dyld:
|
||||
already loaded image reuses it.
|
||||
- Symlinks such as `Versions/Current` are followed inside the analyzed root.
|
||||
An escape through `..` or an absolute link is `escapes-target`.
|
||||
- Dyld path components are POSIX names. On Windows hosts, link text uses `\`
|
||||
as its separator, and a dyld component that contains `\` or `:` cannot name
|
||||
a file in the analyzed root, so its candidate is `absent`.
|
||||
|
||||
Each edge lists every candidate path tried, with its outcome: `resolved`,
|
||||
`absent`, `not-mach-o`, `malformed`, `unsupported` (recognized Mach-O outside
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# Apple IPS crash reports
|
||||
|
||||
`inspect_apple_ips` / `inspect-apple-ips` answers whether one selected local
|
||||
Apple `.ips` file is a crash report (`bug_type` string `"309"`), which process,
|
||||
exception, and termination facts that report records, which threads and
|
||||
`usedImages` rows it lists, and which documented crash classes its strings
|
||||
match. It reads the file without executing a target and does not require Xcode,
|
||||
atos, a disassembler, or pwntools.
|
||||
|
||||
```bash
|
||||
rea inspect-apple-ips /absolute/path/to/report.ips --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
requires an absolute filesystem path and preserves that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_apple_ips",
|
||||
"arguments": { "path": "/artifacts/report.ips" }
|
||||
}
|
||||
```
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte length.
|
||||
`metadata` is the first-line JSON object. `bug_type` stays a string. The crash
|
||||
body is parsed only when that string is `"309"`. Other types, including `"288"`
|
||||
stackshots, return no crash result.
|
||||
|
||||
`process`, `exception`, `termination`, `faulting_thread`, `threads`, and
|
||||
`images` reproduce documented body fields when present, including each image's
|
||||
`name` and each frame's `symbolLocation` (as `symbol_location`, the byte offset
|
||||
from the start of `recorded_symbol`). Integers keep their
|
||||
decimal literals and a hexadecimal form, including arm64e registers above
|
||||
2^53. Frame roles follow the recorded frame index: row zero of the resolved
|
||||
faulting thread is `faulting_instruction`, row zero of other threads is
|
||||
`current_instruction`, and later rows are `return_address`. Each runtime
|
||||
address uses that row's own image base and offset. The recorded `inline` flag
|
||||
does not supply a missing offset or authorize borrowing another row's address.
|
||||
When `faultingThread` is missing or does not resolve to a recorded thread
|
||||
object, row-zero roles are `unknown`; the recorded lookup remains available.
|
||||
A translated process records Rosetta's registers in a nested
|
||||
`threadState.rosetta` object; each one is reported as `rosetta.<name>` and
|
||||
counts toward the register budget. A [public ReportCrash `.ips` log](https://github.com/Mortennn/Dozer/issues/189)
|
||||
shows `rosetta.tmp2`, `tmp1`, and `tmp0` beside ordinary x86 registers. The
|
||||
test fixture quotes that register excerpt inside an authored report body; it
|
||||
does not generate a new Rosetta crash during the test.
|
||||
Observed JSON strings retain `""`; `null` means the field was missing or JSON
|
||||
`null`. This includes image paths, frame symbols, process text, and the older
|
||||
string `osVersion` form. Unlisted JSON keys and generic register names also
|
||||
retain empty spellings. An empty image architecture remains recorded as `""`
|
||||
while `uuid_unknown` stays true, since that spelling does not establish an
|
||||
architecture. An empty UUID is malformed, so its exact spelling appears in
|
||||
`coverage.type_mismatches` and its canonical UUID remains unknown.
|
||||
`process.os_version` keeps the producer's dictionary (`train`, `build`,
|
||||
`release_type`, `is_embedded`) or the older string form. Image UUIDs are uppercase 8-4-4-4-12; an all-zero UUID
|
||||
or a missing or empty `arch` is `uuid_unknown`. Image `source` letters keep their
|
||||
documented meaning (`P` process, `S` shared cache, `C` shared cache library,
|
||||
`K` kernel, `U` kernel cache, `T` kernel text exec, `A` absolute). Keys the
|
||||
documentation does not list remain in `unlisted_keys` or `unlisted_body_keys`.
|
||||
|
||||
Each frame's `image_index` refers to its entry in `images`. Image architecture,
|
||||
UUID and `uuid_unknown` are retained once on that image. Resolve the reference
|
||||
when using those facts; an absent or out-of-range index leaves the image
|
||||
unknown. This avoids repeating image text for every stack frame.
|
||||
|
||||
A present value whose JSON type differs from the documented one is never read
|
||||
as absent: it is listed in `coverage.type_mismatches` with its path, the
|
||||
expected type, and the observed type, and `coverage.status` becomes
|
||||
`partial`. A crash body without `threads` or `usedImages` is also `partial`.
|
||||
Malformed image UUID strings likewise make coverage partial; their exact spelling
|
||||
is retained in the mismatch's `recorded_value`, while the canonical image UUID
|
||||
remains unknown. Both 32 hexadecimal digits and canonical hyphenated UUIDs are accepted.
|
||||
Unresolved thread/image references also make coverage partial. A rejected
|
||||
integer lookup keeps its exact decimal literal in `recorded_integer`, including
|
||||
negative values and values above uint32. Valid uint32 lookup values remain in
|
||||
`faulting_thread` or `image_index` even when the referenced row is unavailable.
|
||||
|
||||
`classification` matches only documented SIGKILL codes (compared by their
|
||||
canonical hexadecimal form), `EXC_GUARD` subtypes,
|
||||
pointer-authentication suffixes, and dyld missing-library strings. A report
|
||||
that matches none of those rules is `unclassified`.
|
||||
|
||||
Opened Mach-O and dSYM UUID joins remain unobserved. Symbol names printed
|
||||
inside the report are recorded claims and are not verified. Linux ELF cores
|
||||
use the separate [recorded crash](recorded-crashes.md) workflow.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 1 MiB by default (16 MiB maximum). At most 256
|
||||
threads, 8192 frames, 1024 `usedImages` rows, and 16384 `threadState`
|
||||
register slots are examined by default (4096 / 65536 / 4096 / 262144
|
||||
maximum). Budgets are checked before each row is parsed, and body members the
|
||||
report does not interpret are syntax-checked without being kept. Fixed
|
||||
allowances bound JSON nesting (64 levels), unlisted key names per object
|
||||
(1024), and `termination.reasons` entries (256). Malformed metadata, a
|
||||
truncated crash body, invalid UTF-8, a NUL in the text, and exhausted budgets
|
||||
fail without partial success.
|
||||
|
||||
`max_integer_text_bytes` (`--max-integer-text-bytes` in the CLI) separately
|
||||
bounds retained decimal and hexadecimal integer text, including every derived
|
||||
runtime address and rejected lookup literal. Its default is 8 MiB of UTF-16 text storage and its maximum is
|
||||
64 MiB. Each appearance counts, even when an object could be shared in memory
|
||||
but would be serialized more than once. The parser reserves a conservative
|
||||
upper bound before numeric conversion or address expansion, then releases the
|
||||
unused reservation after each value. It reuses the parsed source integer when
|
||||
the same image base contributes to many frames.
|
||||
|
||||
Raise this per-call allowance on the next call when more room is needed; no
|
||||
restart is required. File-size and row budgets do not raise it. This allowance
|
||||
is separate from JSON wire size, MCP response limits and the client's receive
|
||||
buffer. An exhausted allowance reports a typed resource error without partial
|
||||
success or truncated integer facts.
|
||||
|
||||
```bash
|
||||
rea inspect-apple-ips /absolute/path/to/report.ips --max-integer-text-bytes 16777216 --json
|
||||
```
|
||||
|
||||
This workflow does not execute a target, launch atos, or search for dSYMs.
|
||||
@@ -23,7 +23,7 @@ graph TD
|
||||
SESSION["SessionProviderRouter + BinarySession<br/>one immutable deep binding per target<br/>disjoint auxiliary routing"]
|
||||
REGISTRY["AnalysisProviderRegistry<br/>sorted deep candidates<br/>deterministic selection, no fallback"]
|
||||
RECORDS["src/application/investigation/<br/>composed InvestigationRecords + narrow ports<br/>EvidenceLedger and Unknown ownership"]
|
||||
SNAPSHOT["BinarySessionRecords + AnalysisSnapshotCache<br/>binary target/profile snapshots<br/>compatibility facade and post-commit notifications"]
|
||||
SNAPSHOT["BinarySessionRecords + AnalysisSnapshotCache<br/>binary target/profile snapshots and session file ownership<br/>record coordination and post-commit notifications"]
|
||||
JS_RECON["src/application/javascript/ + src/artifacts/javascript/<br/>JavaScript artifact reconstruction<br/>directory/ASAR reads<br/>AST-only bundle projection"]
|
||||
end
|
||||
|
||||
@@ -75,7 +75,7 @@ graph TD
|
||||
end
|
||||
|
||||
subgraph "Domain Layer"
|
||||
DOMAIN["src/domain/<br/>Pure side-effect-free modules<br/>evidence, comparisons, application graphs"]
|
||||
DOMAIN["src/domain/<br/>Pure side-effect-free modules<br/>format declarations, Evidence, comparisons, application graphs"]
|
||||
end
|
||||
|
||||
subgraph "Configuration"
|
||||
@@ -86,8 +86,8 @@ graph TD
|
||||
TESTS["tests/<br/>Vitest suite<br/>fixtures/ holds fake launcher, bridge, and CDP seams"]
|
||||
end
|
||||
|
||||
subgraph "Evaluation"
|
||||
EVALUATION["src/evaluation/<br/>Agent release evaluation<br/>session transcript scoring"]
|
||||
subgraph "Development Evaluation"
|
||||
EVALUATION["tests/evaluation/model-evals/<br/>Agent release evaluation<br/>session transcript scoring"]
|
||||
end
|
||||
|
||||
DISPATCH --> CLI
|
||||
|
||||
@@ -100,6 +100,8 @@ one section or symbol, or a stable page without re-running the decoder. CLI
|
||||
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.
|
||||
An empty retained section or symbol collection has no valid item index. Its page
|
||||
view can still return an empty page.
|
||||
Malformed authenticated layout input remains rejected with the owning schema's
|
||||
safe field diagnostics under `source.normalized_result`, including the field
|
||||
path and type or value reason. Evidence authentication and decoder validation
|
||||
|
||||
@@ -94,6 +94,14 @@ content. Actual JSON properties with those names remain content. Reference-only
|
||||
objects, unsupported values, and opaque cookie partition identities remain
|
||||
incomplete. Previously exported fingerprints are not recomputed; recapture both
|
||||
sides when comparing captures produced across this decoder change.
|
||||
IndexedDB schema fingerprints with `projection_version: 2` include the observed
|
||||
database version and object-store definitions. A missing, malformed, or imprecise
|
||||
version leaves the schema fingerprint incomplete while retaining observed store
|
||||
facts. Historical fingerprints without this marker covered object stores only:
|
||||
matching historical hashes cannot establish unchanged database versions, and a
|
||||
historical hash is not compared with a version-bearing hash. Recapture both
|
||||
sides for a complete IndexedDB version comparison; other proven storage changes
|
||||
remain reportable.
|
||||
|
||||
Script comparison groups observations by reported URL and compares unordered
|
||||
content samples. Producer inventory keys include optional metadata, so a changed
|
||||
@@ -371,9 +379,17 @@ REA establishes a main-frame origin boundary before enabling Runtime, Debugger,
|
||||
An observed navigation also takes precedence over failures from stale
|
||||
document reads, such as a script ID invalidated by reload; cancellation remains
|
||||
cancellation. Retry after navigation settles, or refresh target discovery if
|
||||
the selected page was replaced. Screenshot origin refusals identify the
|
||||
current document's permitted-origin scope and direct the caller to select a
|
||||
permitted document or explicitly revise `allowed_origins`.
|
||||
the selected page was replaced. Origin-scope refusals from page inspection,
|
||||
runtime observation, screenshots, and WebMCP discovery explain the permitted
|
||||
HTTP(S) origin scope and direct the caller to select a permitted document or
|
||||
explicitly revise `allowed_origins`. Page capture also preserves an observed
|
||||
main-frame scope violation when a later document read fails. An unresolved
|
||||
initial main frame does not establish an origin violation; its bounded startup
|
||||
retries retain a distinct refusal.
|
||||
|
||||
Screenshot capture requires a valid main-frame identity. Malformed identity
|
||||
produces a protocol failure; a readable child frame cannot substitute for the
|
||||
main frame.
|
||||
|
||||
The web-session timeline uses CDP monotonic seconds where the event producer
|
||||
provides a comparable timestamp; absent or invalid timestamps are `null` rather
|
||||
@@ -396,8 +412,12 @@ allowance; exhaustion fails the observation explicitly instead of guessing scope
|
||||
|
||||
## Data minimization
|
||||
|
||||
The Link projection parses repeated CDP header field lines independently and
|
||||
retains their declarations in order. Each link keeps its target in `href` and
|
||||
Response metadata parses repeated CDP header field lines independently. The
|
||||
Link projection retains their declarations in order. `csp.directives` lists the
|
||||
directives of every CSP policy in order, across field lines and comma-separated
|
||||
policies, without recording policy boundaries, so a directive name can repeat.
|
||||
Single-valued policy fields combine their lines as one comma-separated value,
|
||||
as RFC 9110 specifies. Each link keeps its target in `href` and
|
||||
its relationship context in `context_url` with a separate `context_scope`;
|
||||
absent `anchor` uses the response URL, while a relative `anchor` resolves
|
||||
against that URL. Anchored links remain in the projection, but a `link_rel`
|
||||
@@ -414,6 +434,17 @@ complete Structured Field Item, including parameters such as `report-to`.
|
||||
These are declarations, not an assessment of the document's effective policy;
|
||||
absent, malformed or non-token items project as `null`.
|
||||
|
||||
Console entries, WebSocket frame summaries, and selected request/response JSON
|
||||
shape outputs share one 8 MiB retained-observation allowance per capture. Shape
|
||||
inference admits expanded path bytes before allocating those paths, including
|
||||
escaped and Unicode property names. Replacing or removing a request's shapes
|
||||
refunds their retained charges. A refused body shape preserves network metadata
|
||||
and any captured peer shape with `resource_budget_exhausted` coverage; a refused
|
||||
WebSocket frame is counted as dropped rather than reclassified as non-JSON text.
|
||||
The allowance has no runtime override. Protocol messages and JSON input parsing
|
||||
remain subject to their separate transport admission; this output allowance does
|
||||
not bound the whole process heap.
|
||||
|
||||
REA retains local observation data and removes only URL userinfo credentials, explicitly declared scenario secrets, and values from structured credential/storage fields:
|
||||
|
||||
- URL observations preserve the complete local URL, including query values, fragments, duplicate parameters, and their order. Only username/password userinfo is removed; malformed original URL strings remain available with `origin: null`.
|
||||
@@ -421,7 +452,7 @@ REA retains local observation data and removes only URL userinfo credentials, ex
|
||||
- Supported DOM URL attributes are projected separately as resolved destinations. Empty `action` on HTML or XHTML forms and empty `formaction` on HTML or XHTML submit controls resolve to the document URL; other relative URL attributes resolve against the captured document base.
|
||||
- Accessibility structure and reported roles are retained by default, while names and descriptions require `include_accessibility_text: true`. The browser protocol may omit an individual role; that role remains unknown for comparison. Other observed accessibility differences can still establish a change.
|
||||
- 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 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. A JSON-typed request body that CDP reports through `hasPostData` but omits from `postData`, or that cannot be parsed as JSON, makes `json_body_shapes` unavailable. That request's `body_shapes.status` is `partial`, not `included`, when only its response shape was captured. 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.
|
||||
- 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. A JSON-typed request body that CDP reports through `hasPostData` but omits from `postData`, or that cannot be parsed as JSON, makes `json_body_shapes` unavailable. That request's `body_shapes.status` is `partial`, not `included`, when only its response shape was captured. Base64 response bytes must be valid UTF-8 before JSON interpretation; invalid bytes leave the response shape unavailable and preserve any observed request shape and network metadata. Producer-decoded strings and genuine U+FFFD characters retain their reported meaning. 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.
|
||||
For normalized passive inputs with complete request inventories on both sides,
|
||||
request additions and removals remain observable even when selected body shapes,
|
||||
response metadata, or WebSocket coverage are unavailable. HTTP request and
|
||||
@@ -578,6 +609,22 @@ Network and console coverage starts only after REA attaches and enables the rele
|
||||
|
||||
Source maps are not fetched by inspection. Bundle analysis fetches them only when `fetch_source_maps` is selected, with exact-origin redirect checks and no credentials, cookies, or referrer. Each fetch operation uses `source_map_fetch_timeout_ms` (default 30000) and a 64 MiB aggregate streamed-response budget across redirects. The byte budget has no runtime override. A fetch overrun is an item limitation, not a thrown analysis timeout. A deadline or byte-limit failure remains explicitly unavailable and makes bundle completeness partial. Source-map decoding also bounds raw resolved identities to 64 MiB and aggregate inline evidence to 32 MiB. Failed maps preserve their failure context when it fits; if another context cannot fit, collection stops with the full requested count, the returned processed count, and an explicit unknown-results limitation. Retained mappings and original sources are returned inline. See [source-location limits](web-source-location.md) for the structural decoder bounds. Original source artifacts with `.ts`, `.tsx`, `.mts`, or `.cts` suffixes carry `text/typescript`; other source names retain `text/javascript`.
|
||||
|
||||
A fully read response that fails UTF-8, JSON, mapping, or structural validation
|
||||
retains `artifact: null`, empty original-source, module-edge, and mapping
|
||||
arrays, and an explicit failure limitation. Invalid content is `invalid`;
|
||||
decoder or structural capacity refusal is `fetch_failed`. Its optional
|
||||
`response_identity` records the complete body's SHA-256 digest, byte count,
|
||||
and `fetch-response-body-bytes` representation without retaining malformed
|
||||
text or charging that text to the 32 MiB output budget. These are bytes
|
||||
delivered by Fetch after HTTP content decoding and before UTF-8 decoding, not
|
||||
HTTP wire bytes. The identity is absent when the body was not fully read, and
|
||||
older observations may omit it. A response whose text cannot fit the existing
|
||||
output budget is likewise `fetch_failed` with text omitted and completed-body
|
||||
identity; JSON parsing and source-map decoding are not attempted. Successful and partial maps keep their
|
||||
full text artifacts. Their original text, including an initial BOM or XSSI
|
||||
line, remains distinct from the parsing view that removes that framing.
|
||||
Collection reads the body once and does not raise its response or output limits.
|
||||
|
||||
When fetching is selected, source-map `excluded` facts preserve the capture
|
||||
ledger's reasons and counts for declarations rejected before download. No
|
||||
disallowed URL details are retained or fetched. `requested` and `processed`
|
||||
@@ -585,6 +632,17 @@ count the admitted fetch requests; exclusions are counted separately. Excluded
|
||||
declarations make the collection unavailable, or partial when maps were retained.
|
||||
An empty collection with no declarations remains `not_requested`.
|
||||
|
||||
If the caller cancels while later source maps are being fetched, the failure's
|
||||
partial Evidence retains the captured page and every completed map item. Its
|
||||
`normalized_result.kind` is `web-bundle-acquisition` and
|
||||
`analysis_status` is `not_performed`: no script-analysis result is claimed.
|
||||
`source_maps.requested` remains the admitted request count,
|
||||
`source_maps.processed` counts completed items, and any unprocessed requests
|
||||
have an explicit unknown-results limitation. Capture exclusions remain in the
|
||||
same collection. The cancellation error keeps the caller's exact reason;
|
||||
an already observed response resource or cleanup failure keeps its own error
|
||||
category and cleanup owner.
|
||||
|
||||
Source-map items retain the script's `declared_url` separately from the observed
|
||||
`effective_url`. Successful maps use the latter as their source-resolution base.
|
||||
Failed fetches retain the last response URL observed within the approved origins;
|
||||
|
||||
@@ -10,8 +10,10 @@ liveness deadlines. `INPUT_JSON` may be inline JSON or a JSON file path.
|
||||
The minimal request contains only browser launch/connect selection, `start_url`,
|
||||
and at least one `actions` entry. Launch `headless` defaults to `true` and can
|
||||
be set to `false` where the host supports a visible browser. Navigations follow
|
||||
the destinations named by the scenario and the page's ordinary browser requests;
|
||||
there is no separate origin allowlist or request-interception layer. Environment
|
||||
the destinations named by the scenario and the page's ordinary browser requests,
|
||||
and [request steps](#request-steps) send only to the start URL's origin;
|
||||
there is no separate origin allowlist. Request steps use a temporary dispatch
|
||||
gate for cancellation; ordinary page requests retain their browser behavior. Environment
|
||||
settings (including service workers blocked by default), empty storage, and a
|
||||
final sanitized URL capture are supplied by default. Set
|
||||
`environment.service_workers` to `allow` when the application requires them.
|
||||
@@ -204,7 +206,8 @@ language environments.
|
||||
HTTP(S) URLs may include ordinary query values and fragments directly. Use
|
||||
ordered structured query entries when a value needs to reference a declared
|
||||
environment-backed secret. Form, storage, and cookie values are either literal
|
||||
strings or declared secret references. Raw URL userinfo credentials are rejected.
|
||||
strings or declared secret references; request step headers can also read a
|
||||
cookie or local storage value from the page. Raw URL userinfo credentials are rejected.
|
||||
Captured credential-header
|
||||
values are not retained, and declared secret values are redacted automatically.
|
||||
A secret may be declared solely to
|
||||
@@ -315,6 +318,113 @@ external browser without closing it. The request itself defines the operation;
|
||||
there is no additional REA grant step. The browser and host still enforce their
|
||||
own access and process rules.
|
||||
|
||||
## Request steps
|
||||
|
||||
A `request` step sends one HTTP request from the page with the page's own
|
||||
`fetch`, so the browser attaches the session's cookies and the request is
|
||||
recorded in the step's network events like any request the application makes.
|
||||
Use it to record an application's API, including writes, when driving the UI
|
||||
for each call would be slower or less exact than calling the endpoint the UI
|
||||
calls. It is the only action that changes application state without a user
|
||||
gesture, so run scenarios with write requests only against an instance whose
|
||||
data you may change. This scenario creates one item:
|
||||
|
||||
```json
|
||||
{
|
||||
"browser": {
|
||||
"mode": "launch",
|
||||
"executable_path": "/absolute/path/to/chromium"
|
||||
},
|
||||
"start_url": { "url": "http://127.0.0.1:3000" },
|
||||
"actions": [
|
||||
{
|
||||
"step_id": "create-item",
|
||||
"action": "request",
|
||||
"method": "POST",
|
||||
"path": "/api/items",
|
||||
"query": [
|
||||
{ "name": "notify", "value": { "source": "literal", "value": "false" } }
|
||||
],
|
||||
"headers": [
|
||||
{
|
||||
"name": "X-CSRFToken",
|
||||
"value": { "source": "cookie", "name": "csrftoken" }
|
||||
},
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": {
|
||||
"source": "local_storage",
|
||||
"key": "auth",
|
||||
"json_pointer": "/token"
|
||||
},
|
||||
"prefix": "Bearer "
|
||||
}
|
||||
],
|
||||
"json": { "title": "Scratch item 1" },
|
||||
"expected_status": [201],
|
||||
"timeout_ms": 10000
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `method` is `GET`, `HEAD`, `POST`, `PUT`, `PATCH` or `DELETE`. `json` is the
|
||||
body, sent with `Content-Type: application/json` unless a header sets one; a
|
||||
`GET` or `HEAD` step cannot carry it.
|
||||
- `path` starts with one `/` and must resolve to the start URL's origin, which
|
||||
validation checks before the browser starts. When the step runs, the page must
|
||||
be on that origin, checked again in the page as the request is sent; add a
|
||||
`goto` step first if an earlier action left it. A query in `path` is sent as
|
||||
written (a fragment is not sent), and `query` entries are appended after it
|
||||
in order and may reference declared secrets.
|
||||
- Request steps follow no redirects: a redirect answer fails the step, and
|
||||
nothing is sent to the location it names, though a write the redirect
|
||||
answered may already have been applied. `expected_status` cannot name a 3xx
|
||||
status. Give the path the redirect names; with header values selected, the
|
||||
capture records its `Location`.
|
||||
- Header values are literals, declared secrets, a cookie the browser holds for
|
||||
the request URL (`{"source": "cookie", "name"}`, HttpOnly cookies included,
|
||||
whose value the page's scripts can then see while the request runs), or a
|
||||
local storage entry on the start origin (`{"source": "local_storage",
|
||||
"key"}`, with an optional `json_pointer` to a string or number in a stored
|
||||
JSON value). `prefix` is sent before the value. A value read from the page is
|
||||
redacted like a declared secret, as `[REDACTED:page:<step_id>.<header>]`,
|
||||
from records made after the step reads it; a response recorded earlier, such
|
||||
as the login response that returned a token, keeps the value. A value read
|
||||
again keeps its first marker, and a value shorter than 8 characters is not
|
||||
redacted, since redacting it would rewrite ids, ports and hosts throughout
|
||||
the capture. A value is redacted as stored and as `fetch` sends it, without
|
||||
surrounding spaces and tabs. A missing cookie, key or pointer fails the step.
|
||||
Reading a page value raises the estimated cost of redacting every later
|
||||
body, so the bodies kept within `max_network_body_allocation_bytes` (1 MiB
|
||||
by default) get smaller: after a 32-character `X-CSRFToken` value, a body over
|
||||
about 47 KiB is kept as `unavailable`. Raise `capture.limits` when the
|
||||
application's responses are larger.
|
||||
- Validation refuses a header name given twice in a step, header names a
|
||||
page's `fetch` cannot set, such as `Cookie`, `Origin`, `Host` or `Sec-*`, and
|
||||
`User-Agent`, which Chrome drops; it refuses line breaks and other ASCII
|
||||
control characters in literal values and prefixes, and the step fails before sending
|
||||
when a secret or page value holds them.
|
||||
- The step completes when the whole response has been read. With
|
||||
`expected_status`, any other status fails the step and the later actions are
|
||||
recorded as `cancelled`; without it, any response completes the step. A
|
||||
network error fails the step. `timeout_ms` covers reading the header values
|
||||
and the request: a step whose time runs out, or that is cancelled, before
|
||||
its request is sent sends nothing, but a request already sent can still reach
|
||||
the application after the step fails.
|
||||
An absolute deadline also covers browser evaluation queued behind page work.
|
||||
A temporary route checks cancellation again at network dispatch and is removed
|
||||
when the request evaluation settles. A page controlled by a service worker
|
||||
is refused because its fetch can bypass that dispatch gate; use the default
|
||||
blocked service-worker policy for request steps.
|
||||
|
||||
The request runs in the page's main world, so an application that wraps
|
||||
`fetch` sees it, and it goes through the same network observation as other
|
||||
page requests: select network content (bodies or header values) to record it.
|
||||
Captures with request steps state in `limitations` that the steps sent their
|
||||
declared requests through the page's fetch. A scenario without request steps
|
||||
is unchanged.
|
||||
|
||||
## Network evidence
|
||||
|
||||
`capture.events: ["network"]` retains request, response, completion, failure,
|
||||
@@ -355,6 +465,17 @@ and unfinished-request metadata. Select content independently:
|
||||
All three options default to `false`. Any selected network content also enables
|
||||
network metadata observation; listing `network` in `events` is then optional.
|
||||
Each observed request object receives a capture-scoped `transaction_id`.
|
||||
Each `request` event carries `observed_at`, the wall-clock time REA observed the
|
||||
request start. Playwright reports the browser's own start only once a request
|
||||
ends, so each `request-finished` or `request-failed` event carries `started_at`,
|
||||
the browser's wall-clock start, and `elapsed_ms`, its time from that start to
|
||||
the end of the response, when the browser reports them. The environment views
|
||||
time scenario records from these, as HAR entries are timed: the browser's start
|
||||
where it reported one, else `observed_at`, which trails it by up to tens of
|
||||
milliseconds while REA reads other responses, and a duration of 0 where the
|
||||
browser reported none. Captures made before these fields existed lack them and
|
||||
are read in record order. REA versions before them refuse captures that carry
|
||||
them. Scenario comparisons ignore all three (`ignore_network_request_timing`).
|
||||
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. Request events require both transaction fields;
|
||||
@@ -452,8 +573,8 @@ and compared as an unordered collection after caller rules apply, because
|
||||
concurrent responses arrive in any order and can land in a later step; a
|
||||
redirect retains the complete predecessor ancestry, including each hop's own
|
||||
request, response outcome, and selected network content. Each transaction's
|
||||
capture-local IDs, sequence/index fields, and content source-sequence anchor
|
||||
are removed. Caller rules normalize retained strings before hashing. The
|
||||
capture-local IDs, sequence/index fields, content source-sequence anchor and
|
||||
request times (`observed_at`, `started_at`, `elapsed_ms`) are removed. Caller rules normalize retained strings before hashing. The
|
||||
`preserve_redirect_transaction_ancestry` built-in rule fingerprints each hop
|
||||
as canonical SHA-256 of `{ events, redirected_from }`: `events` is the sorted
|
||||
list of its normalized event SHA-256 digests, and `redirected_from` is its
|
||||
@@ -474,7 +595,10 @@ scope/flags, value fingerprints, and duplicate entries even when redaction or
|
||||
literal rules make names collide. Captured storage arrays retain their original
|
||||
order. The `compare_storage_entries_as_unordered_collection` built-in rule
|
||||
participates in the normalization commitment; new storage comparison digests
|
||||
therefore differ from earlier order-sensitive comparisons.
|
||||
therefore differ from earlier order-sensitive comparisons. The
|
||||
`ignore_network_request_timing` built-in rule likewise joins the commitment, so
|
||||
normalization digests differ from comparisons made before it, though captures
|
||||
with and without request times compare alike.
|
||||
|
||||
Each aligned step reports changed, unchanged, or unknown. Changed and unknown
|
||||
action, screenshot, DOM, accessibility, URL, history, storage, and event
|
||||
|
||||
+127
-4
@@ -236,6 +236,16 @@ Formats 2, 3 and 4 retain header, directory and integrity facts. Compact deliver
|
||||
keeps complete Evidence in the requested bundle. See [Godot PCK](godot-pck.md)
|
||||
for embedded packs, batch queries and unknown encrypted coverage.
|
||||
|
||||
Inspect a Node.js SEA carrier without running it:
|
||||
|
||||
```sh
|
||||
rea inspect-artifact ./application --json
|
||||
rea extract-artifact ./application --json
|
||||
```
|
||||
|
||||
See [Node.js SEA](node-sea.md) for supported layouts, script and asset paths,
|
||||
fuse observations, and the real-fixture verification lane.
|
||||
|
||||
Inspect local model declarations without loading weights:
|
||||
|
||||
```bash
|
||||
@@ -259,8 +269,8 @@ The command decodes a version 24, 27, 29, 31 or 39 `global-metadata.dat` and rep
|
||||
images, type, method and member names, string literals, index ranges, header
|
||||
sections and SHA-256. With `--binary PATH` it also reads the matching
|
||||
`GameAssembly.dylib`, `GameAssembly.dll` or `libil2cpp.so` (never runs it) and
|
||||
links each method to its code address; `--ghidra-seeds PATH` then writes Ghidra
|
||||
function seeds. It does not decrypt metadata. MCP defaults to compact counts
|
||||
links each method to its code address; `--generic-instances` adds generic
|
||||
method instances and `--ghidra-seeds PATH` then writes Ghidra function seeds. It does not decrypt metadata. MCP defaults to compact counts
|
||||
with retained Evidence; query indexed rows with filters, batch indices and
|
||||
selected fields. The CLI defaults to complete Evidence;
|
||||
`--detail summary --evidence_output FILE` exports the full result to a new file
|
||||
@@ -290,6 +300,17 @@ embedded X.509 serial, issuer, subject, and validity fields. A missing security
|
||||
directory is observed absence of that table. See
|
||||
[PE Authenticode certificate tables](pe-certificates.md).
|
||||
|
||||
Inspect PE import and delay-load tables without executing the image:
|
||||
|
||||
```bash
|
||||
rea inspect-pe-imports /absolute/path/to/application.exe --json
|
||||
```
|
||||
|
||||
The workflow reports DLL names, named and ordinal functions, delay-load
|
||||
descriptors, and a pefile-compatible import hash of the standard import table.
|
||||
A missing import directory is observed absence of that table. See
|
||||
[PE import and delay-load tables](pe-imports.md).
|
||||
|
||||
Inspect ELF PT_NOTE and SHT_NOTE tables without executing the image:
|
||||
|
||||
```bash
|
||||
@@ -300,6 +321,33 @@ The workflow reports note owners, types, descriptor hashes, and GNU build-id
|
||||
or ABI-tag fields when those descriptors match. A missing note table is
|
||||
observed absence of those declarations. See [ELF note tables](elf-notes.md).
|
||||
|
||||
Inspect an Apple `.ips` crash report without executing a target:
|
||||
|
||||
```bash
|
||||
rea inspect-apple-ips /absolute/path/to/report.ips --json
|
||||
```
|
||||
|
||||
The workflow reports first-line metadata, process/exception/termination facts,
|
||||
threads, usedImages, lossless integer registers, and documented crash classes
|
||||
when `bug_type` is `"309"`. Other DiagnosticReports types return no crash
|
||||
result. See [Apple IPS crash reports](apple-ips.md).
|
||||
Inspect Linux kernel module metadata without executing the module or requiring
|
||||
`modinfo`:
|
||||
|
||||
```bash
|
||||
rea inspect-kernel-module /absolute/path/to/module.ko --json
|
||||
```
|
||||
|
||||
The workflow reports ordered `.modinfo` keys (duplicate `alias` and `parm`
|
||||
entries preserved), `__versions` symbol CRCs, presence of
|
||||
`.gnu.linkonce.this_module` and `__ksymtab` sections, observed `.init.text`
|
||||
and `.exit.text` sizes, and an appended signature trailer. `struct module` is
|
||||
not decoded and the signature is not validated. Other ELF types are not
|
||||
applicable. gzip, xz, and zstd containers are unsupported and name
|
||||
`external_decompression` as the next probe: decompress with an external
|
||||
utility, then inspect the decompressed file. See
|
||||
[Linux kernel modules](kernel-modules.md).
|
||||
|
||||
Inspect a CPython 3.7–3.13 `.pyc` header and nested marshal code objects
|
||||
without executing bytecode or installing Python:
|
||||
|
||||
@@ -339,11 +387,21 @@ rea trace /absolute/path/to/program "search" --provider ghidra --json
|
||||
a function dossier; `decompile` returns pseudocode. For assembly instructions
|
||||
alone, use `rea instructions`. A macOS `.app` bundle can be supplied directly.
|
||||
|
||||
A complete dossier can reach several megabytes of value-flow and references.
|
||||
`rea function ... --detail summary --evidence_output /absolute/path/dossier.json` returns the
|
||||
compact summary and saves the complete dossier as an Evidence bundle, never
|
||||
overwriting an existing file. Page that bundle without reanalysis by naming it
|
||||
as an `inspect-analysis-view` source, selecting the summary's
|
||||
`normalized_result.parent_evidence_id` when the bundle holds several records:
|
||||
`{"source": {"kind": "evidence-file", "path": "/absolute/path/dossier.json", "evidence_id": "ev_…"}, "view": {"kind": "native", "facet": "pseudocode", "offset": 0, "limit": 4096}}`.
|
||||
MCP `analyze_function` defaults to the same summary and retains the complete
|
||||
dossier in the session for `inspect_analysis_view`.
|
||||
|
||||
Run `rea --help` or a command's `--help` for arguments and output options.
|
||||
The [generated catalog](mcp-contracts.md#generated-catalog) lists all CLI commands and MCP
|
||||
tools. Provider-specific target support is described in the
|
||||
[native guide](native-investigation.md), [DOS guide](ghidra-dos.md),
|
||||
[raw binary guide](raw-binary.md), and
|
||||
[raw binary guide](raw-binary.md), [GameCube DOL guide](ghidra-dol.md), and
|
||||
[Windows Ghidra guide](windows-ghidra-p0.md).
|
||||
|
||||
## Choose a provider
|
||||
@@ -407,7 +465,14 @@ 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.
|
||||
|
||||
Importing an Evidence bundle refreshes retained subject display names and paths.
|
||||
One-shot binary CLI Evidence reports the exact path argument in `caller_input_path`,
|
||||
including relative spelling and symlink aliases. Its subject identifies the
|
||||
inspected artifact; `caller_input_path` does not change the Evidence ID or
|
||||
snapshot query. A replay reports the current invocation's path while leaving
|
||||
the saved Evidence unchanged. Provider inspections continue to include the
|
||||
established `parameters.input_path` field.
|
||||
|
||||
Importing an Evidence bundle refreshes retained request and subject display metadata.
|
||||
It preserves cached analysis results, including observations for other targets.
|
||||
Snapshot bindings that use a replaced record retain its updated display path.
|
||||
|
||||
@@ -495,6 +560,13 @@ by file order. Omit `--evidence-bundle` when the request supplies inline Evidenc
|
||||
|
||||
## Import historical source
|
||||
|
||||
Historical source inventories preserve exact filenames, including literal backslashes
|
||||
on POSIX hosts. Relative import lookup uses the recorded source file's owning
|
||||
directory and decodes URL percent escapes once; encoded slash, NUL and malformed
|
||||
escapes remain unresolved. A decoded backslash remains part of a filename rather
|
||||
than a directory separator. This inventory lookup does not claim that Node can
|
||||
load that filename or apply Node's runtime file-URL admission policy.
|
||||
|
||||
Import an older source tree to compare with the current artifact:
|
||||
|
||||
```bash
|
||||
@@ -707,6 +779,31 @@ like a blank `MCP_HOST`. The bound URL is written to stderr as one JSON log line
|
||||
[agent environments](agent-environments.md) for what the state and replay
|
||||
return and do not establish.
|
||||
|
||||
## Build an environment bundle
|
||||
|
||||
`rea environment-build <capture> [dir] [--name <name>] [--template-rule <rule> ...]
|
||||
[--format-rules-only] [--package-tarball <path>] [--capture-timeout-ms <ms>] [--dry-run]` builds the bundle
|
||||
`environment-export` writes from one recorded capture: a `.har` file, which it
|
||||
inspects as `inspect-web-network-capture` does, or capture Evidence JSON from
|
||||
`inspect-web-network-capture` (HAR) or `capture-browser-scenario`. It projects
|
||||
the environment manifest from the in-memory Evidence with the opt-in rules
|
||||
`after-uid-literal`, `opaque-token`, `sibling-variance` and `prefix-variance`
|
||||
unless `--template-rule` or `--format-rules-only` selects others, prepares the
|
||||
state, and writes the bundle; every file is byte-identical to the three-step
|
||||
path's when that path lists the same rules in the views' order and exports
|
||||
under the build's name. A loopback or IP-literal capture is named after its file unless `--name`
|
||||
is given. It prints one JSON report: the capture and manifest identities, the
|
||||
state, a `coverage` summary of which tools answer from the state, which replay
|
||||
and why each write is withheld with a hint, the files, warnings and the next
|
||||
command. `--dry-run` writes nothing and may omit the directory.
|
||||
|
||||
```sh
|
||||
rea environment-build grafana.har ./grafana --json
|
||||
```
|
||||
|
||||
See [agent environments](agent-environments.md#build-a-bundle-in-one-step)
|
||||
for the report, the hints and what the bundle ships.
|
||||
|
||||
## Export an environment bundle
|
||||
|
||||
`rea environment-export <manifest.json> --evidence <capture.json> <dir>
|
||||
@@ -882,6 +979,10 @@ server resources. It preserves a primary listener diagnostic, or a
|
||||
tool count and Evidence identifiers. The successful `stopped` document is
|
||||
returned only after cleanup is confirmed. The same in-process server owner
|
||||
retains failed stages for retry; the CLI exposes no separate retry command.
|
||||
`rea environment-build` is one-shot too: it prints its report and exits `0`,
|
||||
or prints the refusing stage's structured error and exits `1`, writing nothing
|
||||
when the refusal comes before the bundle is written. SIGINT cancels it with a
|
||||
`cancelled` error; a cancellation before the bundle stage writes nothing.
|
||||
`rea environment-export` is one-shot: it prints the written files and exits
|
||||
`0`, or prints a structured `invalid_request` error and exits `1` for the same
|
||||
pair refusals, a non-empty or file-occupied directory, a missing package
|
||||
@@ -958,3 +1059,25 @@ Counting retains the existing bounded formatted-string allocation after capacity
|
||||
admission; omit the flag to stream large JSON documents without materializing
|
||||
the complete formatted text. Exhausted token windows display an empty range at
|
||||
the total token count and have no next offset.
|
||||
|
||||
### `inspect-devicetree`
|
||||
|
||||
Inspect an explicit local FDT v16/v17 blob without execution or an external tool.
|
||||
Returns header, reservations, node/property tree, derived standard values and
|
||||
selected phandle references. See [devicetree inspection](devicetree.md) for
|
||||
limits and retained-view pagination.
|
||||
|
||||
```bash
|
||||
rea inspect-devicetree /artifacts/board.dtb --json
|
||||
rea inspect-devicetree /artifacts/board.dtb --detail summary --evidence_output /artifacts/board-evidence.json --json
|
||||
```
|
||||
|
||||
### PE TLS and load configuration
|
||||
|
||||
```sh
|
||||
rea inspect-pe-load-config /absolute/path/to/application.exe --json
|
||||
```
|
||||
|
||||
Reports TLS callbacks and size-covered load-config fields without execution.
|
||||
Use `--max-callbacks` and `--max-file-bytes` to set read budgets. See
|
||||
[PE TLS and load configuration](pe-load-config.md).
|
||||
@@ -6,6 +6,17 @@ for the reviewed setup transaction and [client IDs](installation.md#supported-ag
|
||||
The versioned verification notes below describe their stated runs; live service
|
||||
acceptance is verified only where explicitly recorded.
|
||||
|
||||
## Runtime settings and client deadlines
|
||||
|
||||
`update_analysis_settings` changes curated defaults inside the running REA
|
||||
server. It does not edit the client registration, extend the client's tool-call
|
||||
deadline, or recompute timeout values previously derived by `rea setup`. When
|
||||
raising a REA startup or operation deadline, separately ensure the client allows
|
||||
enough time for the full request. Use `inspect_analysis_settings` for the running
|
||||
server's defaults; `rea doctor` checks launch configuration and cannot observe
|
||||
another process's runtime overrides. See the
|
||||
[settings design](design/limits-and-recovery.md) for ownership and lifetime.
|
||||
|
||||
## Client tool names and discovery
|
||||
|
||||
REA advertises canonical names such as `binary_session`. The MCP host decides
|
||||
@@ -305,15 +316,17 @@ for the supported policy values.
|
||||
When direct launcher paths prove the same executable or Node entrypoint,
|
||||
setup retains the existing caller-selected spelling. An otherwise aligned
|
||||
registration therefore needs no rewrite or recovery backup merely because
|
||||
REA was invoked through another symlink. Unresolved identity does not prove
|
||||
equivalence.
|
||||
REA was invoked through another symlink. Setup also retains that spelling when
|
||||
another field, such as an invalid timeout, needs repair. Unresolved identity
|
||||
does not prove equivalence.
|
||||
|
||||
| Settings | Setup ownership |
|
||||
| ----------------------------------------- | --------------------------------------------------------------------- |
|
||||
| Launcher, transport and activation | Refreshes the REA stdio connection and enables it. |
|
||||
| Explicit server environment | Preserves configured overrides and merges selected provider settings. |
|
||||
| Codex positive timeouts and client policy | Retains caller choices; adds missing recommended REA timeouts. |
|
||||
| Unrelated or future server settings | Retains their parsed values. |
|
||||
| Settings | Setup ownership |
|
||||
| ------------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| Launcher, transport and activation | Refreshes the REA stdio connection and enables it. |
|
||||
| Explicit server environment | Preserves configured overrides and merges selected provider settings. |
|
||||
| Codex timeouts | Retains positive values; repairs missing or invalid values to recommended REA defaults. |
|
||||
| Codex approval policies and tool selections | Retains caller choices; refuses known malformed values. |
|
||||
| Unrelated or future server settings | Retains their parsed values. |
|
||||
|
||||
Dry-run applies the same policy validation and writes no files. A successful
|
||||
refresh keeps an exact recovery snapshot of the original configuration;
|
||||
@@ -491,6 +504,28 @@ as stale, and rerunning setup removes the flag to repair it. Native configuratio
|
||||
uses strict JSON; setup refuses comments, trailing commas and a BOM rather than
|
||||
writing a registration ZCode cannot load.
|
||||
|
||||
## FreeBuff
|
||||
|
||||
For FreeBuff, the proposed integration writes `mcpServers.rea` into the user-scope
|
||||
`~/.agents/mcp.json` shared-agent file. Entries carry `command`, `args`, and
|
||||
`env`; stdio is the default transport. The proposed personal skill location is
|
||||
`~/.agents/skills`, so setup installs its skill copy there. Because the same
|
||||
file doubles as ZCode's user-scope fallback (see above), a `freebuff`
|
||||
registration is also in the file ZCode uses until ZCode defines its own native server.
|
||||
Setup and doctor detect FreeBuff from its own profile directory
|
||||
(`~/.config/freebuff-desktop`), not from the shared `.agents` folder that
|
||||
REA's skill installs create for every client.
|
||||
|
||||
The configuration write and personal skill locations are proposed integration
|
||||
boundaries. FreeBuff MCP loading and skill discovery have not been verified
|
||||
with an installed native FreeBuff client/version; filesystem tests cover REA's
|
||||
editing, discovery, and ownership behavior only. Automatic applicability
|
||||
requires the FreeBuff profile directory even when the shared MCP file exists.
|
||||
|
||||
FreeBuff setup support requires `rea-agents@6.8.0` or later. Older versions
|
||||
reject `rea setup --client freebuff` as an unsupported client. See the
|
||||
[installation guide](installation.md#supported-agents) for client availability.
|
||||
|
||||
## DeepSeek Harness
|
||||
|
||||
DeepSeek Harness registers MCP clients through a Cordis YAML patch sequence
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Client and agent verification
|
||||
|
||||
FreeBuff MCP loading and personal skill discovery are currently unverified with
|
||||
an installed native client/version. Its temporary-filesystem coverage verifies
|
||||
REA's configuration and applicability boundaries only; it does not establish
|
||||
that FreeBuff consumes the written registration or skill.
|
||||
|
||||
Use these optional lanes to verify an installed client or evaluate an agent's
|
||||
REA workflow. [Testing REA](testing.md) provides the normal development commands
|
||||
and provider lanes. Each record below states its host, client version, model
|
||||
@@ -458,6 +463,11 @@ real local Codex CLI with:
|
||||
npm run verify:agent
|
||||
```
|
||||
|
||||
The verifier's scenarios, transcript scoring, fixture rubrics, and report gates
|
||||
are development verification code under `tests/evaluation/model-evals/`. The
|
||||
source-owned evaluator runs alongside the compiled REA tools; it is excluded
|
||||
from the shipped runtime package.
|
||||
|
||||
The lane runs scenarios sequentially in standalone Codex (`--no-daemon`) with a
|
||||
disposable HOME and CODEX_HOME under `~/.cache/rea-agent-evaluations/`. Set
|
||||
`REA_AGENT_EVAL_ROOT` to choose another parent directory outside the OS temporary
|
||||
@@ -487,7 +497,7 @@ boundary instead of stopping at Codex approval. Its scenario contract accepts
|
||||
one `provider_unavailable` open refusal without a close, or one successful open
|
||||
followed by a successful close. Other errors, an unclosed session, and a close
|
||||
without acquisition fail. These outcomes and the prompt are owned together in
|
||||
`src/evaluation/AgentEvaluationScenarios.ts`; generic successful-tool sequences
|
||||
`tests/evaluation/model-evals/AgentEvaluationScenarios.ts`; generic successful-tool sequences
|
||||
still apply to scenarios that require them. The provider scenario checks routing,
|
||||
reported limitations, and cleanup; free-form answer correctness remains
|
||||
unassessed. It does not validate a real native engine or authorize runtime execution.
|
||||
|
||||
@@ -1,35 +1,121 @@
|
||||
# Admission limits and recovery
|
||||
# Analysis settings, limits, and recovery
|
||||
|
||||
How to add a REA-owned admission ceiling, budget, or deadline, and what a caller
|
||||
does when one is hit. This is a design rule, not an inventory. Ceilings that
|
||||
should become settings are tracked in
|
||||
This guide explains the runtime settings design for maintainers and developers:
|
||||
who owns each value, when an update takes effect, how providers enforce it, and
|
||||
how to extend the system. The public tool contract is in
|
||||
[MCP contracts](../mcp-contracts.md#editable-analysis-settings); recorded runtime
|
||||
checks and their limitations are in the
|
||||
[verification report](../verification/runtime-analysis-settings.md).
|
||||
|
||||
## Problem and design boundary
|
||||
|
||||
A valid workload can exceed a conservative default. An oversized ASAR header
|
||||
may prevent analysis of the entire archive; a slow Ghidra function may exceed
|
||||
its decompile deadline. Requiring a new REA process to change either budget
|
||||
interrupts the investigation and can discard reusable provider state.
|
||||
|
||||
REA exposes a curated set of analysis defaults through MCP so callers can
|
||||
adjust a reported limit and retry the same workload in the running runtime.
|
||||
Each setting has a typed value, resource bounds, an enforcement owner, and a
|
||||
defined application point. The design applies across archive admission,
|
||||
provider startup, operation deadlines, and worker memory requests.
|
||||
|
||||
The setter changes in-memory defaults. It does not edit arbitrary environment
|
||||
variables, configuration files, MCP registrations, or provider installations.
|
||||
Those mechanisms have different owners and lifetimes. It also cannot change a
|
||||
client deadline, extend accepted work, release retained resources, or remove a
|
||||
fixed representation limit. Exposing a setting requires a working enforcement
|
||||
path, not just an entry in the tool schema.
|
||||
|
||||
Further ceilings that should become settings are tracked in
|
||||
[#6176](https://github.com/morluto/rea/issues/6176). Naming honesty for limit
|
||||
errors is [#5910](https://github.com/morluto/rea/issues/5910).
|
||||
|
||||
## Ownership and data flow
|
||||
|
||||
| Owner | Responsibility |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Domain definitions](https://github.com/morluto/rea/blob/main/src/domain/analysisSettingDefinitions.ts) and [types](https://github.com/morluto/rea/blob/main/src/domain/analysisSettings.ts) | Exact setting IDs, value types, shared bounds/defaults, units, provider/operation associations, application points, and structured limit metadata. Numeric constants stay with their domain owner. |
|
||||
| [Launch parser](https://github.com/morluto/rea/blob/main/src/config/analysisSettings.ts) | Parse selected launch values once, preserving an invalid value as a typed configuration failure rather than substituting a default. |
|
||||
| [AnalysisSettings](https://github.com/morluto/rea/blob/main/src/application/AnalysisSettings.ts) | Own one runtime's launch baseline, immutable override revisions, atomic updates, inspection, and accepted-operation snapshots. It does not own provider lifecycle or cleanup. |
|
||||
| [Composition](https://github.com/morluto/rea/blob/main/src/main/eagerRuntime.ts) and [typed configuration views](https://github.com/morluto/rea/blob/main/src/config/runtimeAnalysisSettings.ts) | Inject the same settings reader into providers and workflows; translate overrides into the configuration each consumer understands. |
|
||||
| Provider or resource owner | Resolve the effective budget, enforce it at the applicable boundary, and attach the actual value and known source to failures. |
|
||||
| [MCP registration boundary](https://github.com/morluto/rea/blob/main/src/server/EvidenceMcpServerCore.ts) | Enter the operation's settings scope before invoking its handler. |
|
||||
| [Settings contracts](https://github.com/morluto/rea/blob/main/src/contracts/analysisSettingsContracts.ts) and [tool registration](https://github.com/morluto/rea/blob/main/src/server/registerAnalysisSettingsTools.ts) | Validate named requests and deliver inspection/update results without requiring an open target or healthy analysis provider. |
|
||||
|
||||
The normal path is: composition creates the store, an MCP handler captures its
|
||||
current revision, and providers read that snapshot when resolving budgets.
|
||||
If an owner rejects work, it reports the effective limit through the shared
|
||||
error projection. A subsequent settings update publishes a new revision for
|
||||
later handlers. It does not reach into the failed operation or retry it.
|
||||
|
||||
### Accepted-operation snapshots
|
||||
|
||||
`AnalysisSettings.run()` installs the current immutable snapshot in
|
||||
`AsyncLocalStorage`. Its `read` function returns that snapshot inside the
|
||||
operation and the latest revision outside it. Providers depend on the reader
|
||||
contract rather than on the mutable store or an ambient environment lookup.
|
||||
|
||||
Acceptance here is entry into the registered handler's settings scope, not
|
||||
arrival of bytes at the MCP transport. Work queued or awaited within that scope
|
||||
keeps its snapshot. Deferred server initialization must still dispatch through
|
||||
the canonical scoped handler.
|
||||
|
||||
| Event | Revision used |
|
||||
| --------------------------------------------------------- | ----------------------------------- |
|
||||
| Operation A enters its handler, then waits for a provider | Current revision 0 |
|
||||
| A settings update publishes revision 1 | Future handlers can read revision 1 |
|
||||
| Operation A resumes and starts its worker | Its accepted revision 0 |
|
||||
| Operation B enters its handler | Revision 1 |
|
||||
|
||||
This gives each operation stable budget semantics even if another connection
|
||||
updates settings while it waits. `next_worker` and `next_startup` describe where
|
||||
an accepted value is applied; they do not cause workers or startups belonging
|
||||
to an older operation to adopt a newer revision.
|
||||
|
||||
Inspection deliberately reads the store's current defaults, rather than the
|
||||
calling operation's snapshot. It reports `active_values.status: "not_observed"`:
|
||||
an inspection result cannot establish the budget or remaining time of an
|
||||
already-running worker.
|
||||
|
||||
### Composition and embedding
|
||||
|
||||
The MCP runtime creates one store and supplies its reader to provider factories.
|
||||
`createServer` uses a supplied store or creates one, and wires its default
|
||||
providers to that store. An embedder supplying a custom binary session or other
|
||||
provider must also inject the same reader into that provider's composition and
|
||||
pass the store to `createServer`. Merely exposing the settings tools cannot
|
||||
make a custom provider consume updates.
|
||||
|
||||
Keep default factories, explicitly supplied providers, transport composition,
|
||||
and deferred handler dispatch covered separately where their wiring differs.
|
||||
Resolve settings at the operation boundary; copying a runtime value into a
|
||||
provider constructor would freeze it at launch. For entrypoints outside the
|
||||
MCP wrapper, an embedder needing the same snapshot guarantee must establish
|
||||
the operation scope with `AnalysisSettings.run()`.
|
||||
|
||||
## Name a default, then a setting when operators need headroom
|
||||
|
||||
Put the number in a named constant with a unit. Do not leave it as a magic
|
||||
number at the call site.
|
||||
|
||||
When a workload may need more room, add a setting whose unset value is that
|
||||
constant. One module under
|
||||
[`src/config/`](https://github.com/morluto/rea/blob/main/src/config) owns the
|
||||
default, any floor, the maximum, the schema, the parser, and the recovery
|
||||
text. Register that schema on `environmentSchema` in
|
||||
[`environment.ts`](https://github.com/morluto/rea/blob/main/src/config/environment.ts).
|
||||
`parseConfig` calls `parseEnvironment`. Doctor uses that same parser through
|
||||
`nativeAnalysisConfigurationError`, so startup and `rea doctor` accept the
|
||||
same values. Add the name to `SELECTED_REGISTRATION_SETTINGS` so `rea setup`
|
||||
copies it into the client registration. Unset keeps today's behavior. An
|
||||
invalid value is a `ConfigurationError` and projects as `configuration_invalid`.
|
||||
Do not fall back to the default.
|
||||
constant. Pure numeric contracts live in `src/domain/analysisResourceLimits.ts`
|
||||
or their existing domain owner. `analysisSettingDefinitions.ts` binds the
|
||||
curated runtime IDs to those same bounds, defaults and application points.
|
||||
Environment parsers and recovery text stay under `src/config/`; register launch
|
||||
schemas on `environmentSchema` so startup and doctor agree. Add launch settings
|
||||
to `SELECTED_REGISTRATION_SETTINGS` when setup should forward them. Unset keeps
|
||||
today's behavior. An invalid launch value remains a configuration failure,
|
||||
never a silent fallback; its validation boundary determines whether MCP can
|
||||
start (see [invalid launch configuration](#invalid-launch-configuration)). An
|
||||
invalid runtime write is `invalid_request` and changes nothing.
|
||||
|
||||
[`REA_REGEX_MATCHING_DEADLINE_MS`](https://github.com/morluto/rea/blob/main/src/config/regexMatchingDeadline.ts)
|
||||
([#6267](https://github.com/morluto/rea/pull/6267)) is the reference. Default
|
||||
5000 ms, floor 1 ms, maximum 2147483647 ms, because Node schedules a longer
|
||||
`setTimeout` delay as 1 ms. Setup copies the setting. A hit says:
|
||||
|
||||
> The effective REA_REGEX_MATCHING_DEADLINE_MS value is 5000 ms (source default; default 5000 ms, floor 1 ms, maximum 2147483647 ms). Set REA_REGEX_MATCHING_DEADLINE_MS in the environment that starts REA to a positive decimal integer from 1 to 2147483647, then restart REA. The worker old-generation heap does not raise this deadline.
|
||||
For example, `regex.matching_deadline_ms` and its launch seed
|
||||
`REA_REGEX_MATCHING_DEADLINE_MS` share a 5000 ms default, 1 ms floor and
|
||||
2147483647 ms maximum. Node schedules a longer `setTimeout` delay as 1 ms.
|
||||
Changing the runtime setting affects the next accepted search; changing the
|
||||
launch environment affects the next REA process.
|
||||
|
||||
[`REA_MCP_MAX_RESPONSE_BYTES`](https://github.com/morluto/rea/blob/main/src/config/mcpResponseBudget.ts)
|
||||
is the byte-budget shape: a decimal safe integer with a 10 MiB floor
|
||||
@@ -39,7 +125,8 @@ raise REA's reserved string limit or Node's string ceiling. The setup
|
||||
allowlist does not copy this setting. A new headroom setting should, following
|
||||
the regex deadline.
|
||||
|
||||
A per-call budget is not an environment setting. JavaScript `max_heap_mb`
|
||||
A per-call budget can have a runtime default without having an environment
|
||||
setting. JavaScript `max_heap_mb`
|
||||
(CLI `--max-heap-mb`) is an integer from 128 to 16384 MiB, default 1024. It
|
||||
applies on the next analysis, which starts a new worker, and does not restart
|
||||
REA. It does not raise the parent result budget, transfer ceilings, or fixed
|
||||
@@ -51,8 +138,122 @@ does: its recovery says to set `NODE_OPTIONS` (for example
|
||||
`--max-old-space-size=<MiB>`) on the process that starts REA, then restart
|
||||
that process. `max_heap_mb` does not raise it.
|
||||
|
||||
## Runtime settings through MCP
|
||||
|
||||
`inspect_analysis_settings` lists the curated settings, their current and launch
|
||||
values, source, bounds, application point and relevant operation names. Filters
|
||||
by exact setting IDs, provider or operation intersect. Active worker values are explicitly `not_observed`; a configured default is
|
||||
not a measurement of active work. Inspection also separates known server limits from unknown client deadlines and receive buffers.
|
||||
|
||||
`update_analysis_settings` accepts an atomic `changes` array. Each entry names
|
||||
an exact `setting` and either `action: "set"` with a schema-validated `value`, or
|
||||
`action: "reset"`. Reset restores the launch value. `expected_revision` is an
|
||||
optional compare-and-set guard; conflicts and duplicate keys change nothing.
|
||||
An unchanged write does not advance the revision.
|
||||
|
||||
The revision tracks override state, not only effective numeric values. Setting
|
||||
an explicit override equal to the launch value still changes its source to
|
||||
`runtime` and advances the revision. Reset removes that override, even if the
|
||||
effective number stays the same. Validation, revision checks, and duplicate-key
|
||||
checks all happen before publishing the replacement snapshot; a rejected batch
|
||||
cannot partially apply. Clients coordinating writes can supply
|
||||
`expected_revision`; without it, valid updates apply to the current state.
|
||||
|
||||
| Runtime setting | Application point |
|
||||
| ------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `asar.max_header_bytes` | Next archive operation, including full JavaScript application analysis |
|
||||
| `ghidra.startup_timeout_ms`, `hopper.startup_timeout_ms` | Next provider startup attempt |
|
||||
| `ghidra.decompile_timeout_seconds` | Next operation on the existing Ghidra Program; `null` means unbounded |
|
||||
| `jadx.operation_timeout_ms` | Next JADX operation |
|
||||
| `regex.matching_deadline_ms`, `regex.worker_heap_request_mib` | Next search / new regex worker |
|
||||
| `capture.decoder_old_generation_mib` | Next owned capture decoder |
|
||||
| `javascript.analysis_timeout_ms`, `javascript.max_heap_mb` | Next source analysis / new JavaScript worker |
|
||||
| `wasm.command_timeout_ms` | Next WABT operation |
|
||||
|
||||
### Precedence and lifetime
|
||||
|
||||
Where a setting supports an explicit per-call argument, precedence is:
|
||||
|
||||
1. The caller's explicit argument.
|
||||
2. The accepted operation's runtime override.
|
||||
3. Valid launch configuration, where that setting has an environment seed.
|
||||
4. The built-in default when launch configuration is absent.
|
||||
|
||||
An invalid launch value does not fall through to the built-in default. Preserve
|
||||
omitted caller arguments in Evidence: resolving an internal default must not
|
||||
rewrite the request as though the caller supplied it. `null` is the explicit
|
||||
unbounded value for `ghidra.decompile_timeout_seconds`; it is not a substitute
|
||||
for an unknown or omitted value elsewhere.
|
||||
|
||||
A write does not extend active work, relaunch a provider, clear retained
|
||||
cleanup, or invalidate successful Evidence.
|
||||
|
||||
Overrides belong to one REA runtime, survive target close/open, and disappear
|
||||
when REA exits. Connections sharing that runtime share its overrides. No files,
|
||||
ambient environment, registrations or upstream software are edited. Overrides
|
||||
are runtime-wide, not scoped to a target or an individual connection.
|
||||
|
||||
### Failure and retry
|
||||
|
||||
An ASAR admission error supplies `details.limit` with the exact setting,
|
||||
effective value, units, bounds, scope, application point, restart requirement
|
||||
and, when known, required bytes and value source. The agent can immediately call:
|
||||
|
||||
```json
|
||||
{
|
||||
"changes": [
|
||||
{ "setting": "asar.max_header_bytes", "action": "set", "value": 33554432 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Then retry the same full-archive request once work and cleanup have settled.
|
||||
No preliminary inspection or source subset is required. The setter does not
|
||||
retry automatically. If an explicit per-call value caused the failure, correct
|
||||
that argument; raising a runtime default cannot override it.
|
||||
|
||||
The resource owner constructs `details.limit` from the registry plus the budget
|
||||
it actually enforced. Metadata includes `agent_editable: true`,
|
||||
`scope: "rea-runtime"`, and `rea_restart_required: false`. Optional
|
||||
`required_value`, `source`, and `parameter` fields are supplied only where known
|
||||
or applicable. Do not infer a source because a value happens to equal a default.
|
||||
Error copying, attribution, redaction, and delivery must preserve these facts.
|
||||
Human-readable remediation explains the same failure; clients should not need
|
||||
to parse that sentence to identify an editable setting.
|
||||
|
||||
Cache policy is part of enforcement. Successful reusable analysis can survive
|
||||
a budget update. Transient Ghidra decompile failures remain uncached so a raised
|
||||
deadline can recover on the same Program. Admission checks still apply to reused
|
||||
data: lowering an ASAR limit must reject a cached oversized header. Neither
|
||||
raising a limit nor clearing a transient analysis failure authorizes skipping
|
||||
cleanup or changing the identity of the provider session.
|
||||
|
||||
### Invalid launch configuration
|
||||
|
||||
Launch validation has two relevant boundaries. Settings validated by global
|
||||
configuration parsing can prevent REA from starting; an MCP setter cannot
|
||||
repair a server that is not running. Correct the launch environment or
|
||||
registration, use `rea doctor` for its configuration checks, and start REA again.
|
||||
|
||||
Provider-local validation can leave MCP available. For example, an invalid
|
||||
`REA_JADX_OPERATION_TIMEOUT_MS` is inspectable with `source: "invalid"`, a
|
||||
`configuration_error`, and omitted `value` and `launch_value`. A valid runtime
|
||||
override repairs the effective JADX timeout without editing that launch seed.
|
||||
Inspection then reports the runtime value while retaining the launch error.
|
||||
Reset exposes the invalid launch state again; it does not repair or replace it
|
||||
with the built-in default. Provider availability and execution must resolve the
|
||||
same effective setting so readiness changes along with repair and reset.
|
||||
|
||||
## Keep a fixed ceiling honest
|
||||
|
||||
Inspection's separate
|
||||
[constraints](https://github.com/morluto/rea/blob/main/src/server/analysisSettingsConstraints.ts)
|
||||
describe operator-owned, external, and fixed controls. REA can report its
|
||||
configured response budget and parent heap limit; client deadlines and receive
|
||||
buffers remain explicitly unknown. These are not entries accepted by the
|
||||
runtime setter. Raising a worker heap request cannot raise the parent heap,
|
||||
and raising a provider deadline cannot make the client wait longer.
|
||||
|
||||
If the ceiling must stay fixed, say so in the failure. Name the limit and the
|
||||
effective value, say this release has no runtime override, and name what does
|
||||
not raise it. Do not invent a setting.
|
||||
@@ -68,20 +269,22 @@ The string the caller sees includes:
|
||||
|
||||
- the limit or setting name
|
||||
- the effective value and unit
|
||||
- the source (`default` or `setting`)
|
||||
- the source when known (`default`, `setting`, `runtime`, or `request`)
|
||||
- the default, the maximum, and the floor when the setting has one
|
||||
- the next action, including where to set it ("in the environment that starts REA")
|
||||
- whether a restart is required
|
||||
- what the change does not raise
|
||||
|
||||
Invalid settings never take this path. They are `configuration_invalid`.
|
||||
Doctor reports `runtime-configuration:<setting>` and says to correct it in the
|
||||
shell or the MCP registration, then rerun.
|
||||
Distinguish an invalid configuration from a valid budget exhausted by work.
|
||||
Preserve the configuration failure and its setting identity; apply the
|
||||
[launch validation boundary](#invalid-launch-configuration) when describing
|
||||
whether live repair is possible.
|
||||
|
||||
## What agents do
|
||||
|
||||
Follow `remediation.action`. Change a request field or a `REA_*` setting only
|
||||
when that text recommends the change. Restart only when it says the value is
|
||||
Use `details.limit` for a direct runtime update when it names an editable
|
||||
setting. Follow `remediation.action` for per-call, fixed and external controls.
|
||||
Inspect settings only when bounds or application details are missing. Restart only when it says the value is
|
||||
read at startup. A sentence that a control does not raise the limit is not a
|
||||
request to change it.
|
||||
|
||||
@@ -103,22 +306,72 @@ request to change it.
|
||||
- `resource_constraint` for capacity, when `retryable` is true: wait for the
|
||||
active admission to finish, then retry within the reported limits. Do not
|
||||
restart REA to free the slot.
|
||||
- `configuration_invalid`: correct the named setting in the environment that
|
||||
starts REA, then start REA again. Run `rea doctor` for the
|
||||
- `configuration_invalid`: when MCP remains available and the failure belongs
|
||||
to a curated provider-local setting, inspect and set a valid runtime override.
|
||||
Otherwise correct the named setting in the environment that starts REA, then
|
||||
start REA again. Run `rea doctor` for the
|
||||
`runtime-configuration:` check. Re-run `rea setup` for that client when the
|
||||
setting is on the registration allowlist, then reconnect so the new process
|
||||
sees it.
|
||||
- `invalid_request`: correct the reported fields from the current schema or
|
||||
CLI help. Do not repeat the unchanged call.
|
||||
|
||||
A restart is required for an environment setting and for a client still
|
||||
running the previous registration. It is not the first step for a transient
|
||||
A restart is required to adopt a changed launch environment or registration.
|
||||
The curated runtime settings above require no REA restart. It is not the first step for a transient
|
||||
MCP drop, a capacity wait, or retained cleanup.
|
||||
|
||||
## Tests
|
||||
## Adding a runtime setting
|
||||
|
||||
Lock the unset default, one accepted override, rejected floor, maximum, and
|
||||
syntax, and the recovery sentence through `parseEnvironment` and `parseConfig`.
|
||||
1. Identify the enforcing owner and the real resource constraint. Decide whether
|
||||
callers need a per-call argument, a runtime default, a launch-only control,
|
||||
or a fixed limit. A registry entry must not advertise authority REA lacks.
|
||||
2. Define the value type and named numeric bounds with the domain owner. Add the
|
||||
ID and metadata to `analysisSettings.ts` and `analysisSettingDefinitions.ts`.
|
||||
Reuse those bounds in runtime validation, launch parsing, and error metadata.
|
||||
Choose the application point and provider/operation associations from actual
|
||||
consumers; a shared control need not apply to every provider.
|
||||
3. If there is a launch seed, add its parser and appropriate configuration/doctor
|
||||
validation. Decide whether an invalid value blocks the runtime or only the
|
||||
provider. Add it to setup's `SELECTED_REGISTRATION_SETTINGS` when it should
|
||||
be forwarded; runtime editability does not automatically propagate it.
|
||||
4. Thread the shared reader through every applicable composition path. Resolve
|
||||
the effective value within the accepted operation, honor explicit arguments,
|
||||
and preserve their omission in Evidence. Keep availability checks consistent
|
||||
with execution. A worker heap request must not be described as a measured
|
||||
process memory limit.
|
||||
5. Enforce the value at its resource boundary and construct structured limit
|
||||
facts there. Preserve those facts through shared error projection and copies.
|
||||
Check cache reuse, lowered admission, transient failures, and retained cleanup
|
||||
against the same ownership rules.
|
||||
6. Update the public contracts and affected guides, then regenerate catalogs
|
||||
and packaged skill metadata using the repository commands. Keep externally
|
||||
owned and fixed controls in the separate inspection constraints, not in the
|
||||
editable registry. Validate both store semantics and a public recovery path.
|
||||
|
||||
## Tests and verification
|
||||
|
||||
Cover the unset default, accepted overrides, rejected floor/maximum values,
|
||||
and invalid syntax through the owning parser and configuration boundary.
|
||||
[`regexMatchingDeadline.test.ts`](https://github.com/morluto/rea/blob/main/src/config/regexMatchingDeadline.test.ts)
|
||||
is the pattern. Project the failure and assert `configuration_invalid` for a
|
||||
bad value and the recovery wording for a hit.
|
||||
is one example. Assert error codes, setting IDs, values, units, provenance,
|
||||
application points, and resulting behavior. Check that adapters deliver the
|
||||
canonical recovery guidance, with independent assertions for its underlying
|
||||
facts. Avoid freezing prose or deriving all expected values from the same
|
||||
registry used by the implementation; either can hide the wrong failure.
|
||||
See [test design](../testing.md#test-design-and-pruning) for the assertion policy.
|
||||
|
||||
Runtime checks cover atomic validation, stale writes, reset, runtime isolation,
|
||||
accepted-operation snapshots, and explicit argument precedence. Public MCP
|
||||
acceptance must reject an oversized ASAR, raise admission, and successfully
|
||||
retry the same complete archive on the same connection. Lowering admission must
|
||||
also refuse previously cached headers. The real Ghidra timeout verifier checks
|
||||
recovery after a live update without replacing its session. Also cover invalid
|
||||
provider-local launch configuration, repair/reset availability, default and
|
||||
custom composition paths, and preservation of structured limits through error
|
||||
copies. Gates used to overlap work and updates need bounded acknowledgements
|
||||
and release/join in `finally`.
|
||||
|
||||
The [verification report](../verification/runtime-analysis-settings.md) separates
|
||||
public MCP checks, simulated provider coverage, real Ghidra execution, and
|
||||
measured task costs. It does not establish real-provider behavior for every
|
||||
editable setting or active worker telemetry.
|
||||
@@ -0,0 +1,105 @@
|
||||
# Flattened devicetree inspection
|
||||
|
||||
`inspect_devicetree` / `rea inspect-devicetree` reads a local DTB without an
|
||||
engine, target execution or external tools. It supports FDT versions 16 and 17;
|
||||
other versions return `unsupported_target`. Corrupt recognized blobs return
|
||||
`invalid_request`, and exhausted budgets return `resource_constraint` without
|
||||
partial success.
|
||||
|
||||
```bash
|
||||
rea inspect-devicetree /artifacts/board.dtb --json
|
||||
rea inspect-devicetree /artifacts/board.dtb --detail summary --evidence_output /artifacts/board-evidence.json --json
|
||||
```
|
||||
|
||||
The complete Evidence includes the artifact SHA-256, validated header fields,
|
||||
64-bit memory reservations as exact hexadecimal strings, and a flat node tree
|
||||
with explicit parent paths. Each property retains its file offset, byte length,
|
||||
and up to 256 raw bytes as hex. `truncated` qualifies the preview only; parsing
|
||||
coverage includes the entire declared tree. Version 16 has no declared structure
|
||||
size, so `header.size_dt_struct` is null.
|
||||
|
||||
Derived fields carry `confidence: derived`: standard ASCII string lists, scalar
|
||||
phandles and cell counts, and `reg` tuples using the parent's `#address-cells`
|
||||
and `#size-cells` (defaults 2 and 1). Zero-cell components are null (omitted), distinct from an encoded zero. Cell
|
||||
counts above four, invalid counts and incomplete tuples remain undecoded with a
|
||||
limitation. Addresses are bus-local; no `ranges` translation is attempted.
|
||||
Invalid or ambiguous strings remain raw, rather than being guessed.
|
||||
|
||||
The summary is labeled derived and includes root compatible/model, chosen
|
||||
bootargs/stdout-path and aliases. An undecodable alias retains its name with a
|
||||
null path; it is not silently treated as absent. Single-cell `interrupt-parent`, `remote-endpoint` and `msi-parent`
|
||||
references resolve through phandle declarations. Missing or duplicate targets
|
||||
have null target paths. A node whose `phandle` and `linux,phandle` disagree
|
||||
adds a limitation, and references to either value stay unresolved. A present
|
||||
`phandle` that is not one cell also adds a limitation; `linux,phandle` cannot
|
||||
resolve that node when the canonical declaration is malformed. Binding-specific
|
||||
reference arrays and overlays are not resolved; an empty reference list does not
|
||||
prove absence of hardware links.
|
||||
|
||||
MCP `detail: summary` retains complete Evidence in the session. Follow its
|
||||
`parent_evidence_id` with `inspect_analysis_view`:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": { "kind": "retained-evidence", "evidence_id": "ev:<digest>" },
|
||||
"view": {
|
||||
"kind": "devicetree",
|
||||
"collection": "properties",
|
||||
"path": "/serial@1000",
|
||||
"offset": 0,
|
||||
"limit": 32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Collections are `nodes` (identity and property counts), `properties` (requires an
|
||||
exact node path), `reservations`, and `references`. Pages use retained parsed
|
||||
facts and do not reopen the file. Each page carries fixed-size context
|
||||
(artifact, header, coverage and counts) rather than the summary strings, so a
|
||||
large `bootargs` value does not repeat on every page. Source indices are scoped to the selected
|
||||
collection and parent Evidence; property indices are scoped to their node.
|
||||
|
||||
| Input budget | Default | Ceiling |
|
||||
| ---------------- | ------: | ------: |
|
||||
| `max_file_bytes` | 4 MiB | 16 MiB |
|
||||
| `max_nodes` | 8,192 | 65,536 |
|
||||
| `max_properties` | 32,768 | 262,144 |
|
||||
| `max_depth` | 64 | 256 |
|
||||
|
||||
Decoded names, paths, values and row overhead share a fixed 32 MiB representation
|
||||
allowance, charged before expansion. It has no runtime override.
|
||||
|
||||
The reservation count also uses `max_properties`. CLI flags use kebab case,
|
||||
for example `--max-nodes 16384`. View pages contain at most 256 rows.
|
||||
|
||||
## Verification
|
||||
|
||||
Synthetic tests cover v16/v17, malformed headers/blocks/names/tokens, resource
|
||||
limits, derived values, and CLI/MCP delivery including retained pages after
|
||||
removing the input. The optional real lane requires **dtc 1.8.1**:
|
||||
|
||||
```bash
|
||||
npm run build:cached
|
||||
node scripts/verify/firmware/devicetree.mjs
|
||||
```
|
||||
|
||||
It compiles a DTS with reserved-memory, chosen, aliases and phandles, compares
|
||||
REA's node paths against `dtc -I dtb -O dts`, and checks the derived report.
|
||||
`REA_DTC_PATH` selects the verification executable; it is not runtime setup.
|
||||
|
||||
The dtc 1.8.1 lane ran on macOS arm64 with Node 26.5.0. Its seven node paths
|
||||
matched the decompiled tree. The report included `model: "REA DTB verification"`,
|
||||
`bootargs: "console=ttyS0"`, alias `serial0 -> /serial@1000`, reservation
|
||||
`0x80000000 + 0x1000`, and a resolved reference from `/consumer` to
|
||||
`/serial@1000`. The deliberately minimal remote-endpoint fixture produces dtc
|
||||
graph-binding warnings; this lane verifies FDT structure and selected property
|
||||
derivations, not hardware-binding validity.
|
||||
|
||||
A repeat run of that complete compile/decompile/CLI verification took 2.13 s
|
||||
elapsed, 1.52 s user CPU and 0.27 s system CPU under `/usr/bin/time -l`. This is a
|
||||
small fixture with warm filesystem caches, not a cold-start or large-board
|
||||
benchmark. Peak process-family memory and whole-workflow token usage were not
|
||||
measured; the sandbox denied the memory-reporting system query. No pre-feature
|
||||
equivalent REA workflow exists for comparison. The pinned Node 24.22.1/npm
|
||||
11.16.0 toolchain was unavailable; dependency installation used the local cache
|
||||
with Node 26.5.0/npm 12.2.0 instead.
|
||||
@@ -305,8 +305,13 @@ capture provides them.
|
||||
|
||||
ASAR observation reads the header through one open file handle and validates its
|
||||
declared lengths against the archive size. Header/index admission is the same
|
||||
budget used by static ASAR reads: 16 MiB / 16777216 bytes by default, or
|
||||
`REA_ASAR_MAX_HEADER_BYTES` (at most 256 MiB) when set. An oversized header is
|
||||
budget used by static ASAR reads: 16 MiB / 16777216 bytes by default, seeded by
|
||||
`REA_ASAR_MAX_HEADER_BYTES` (at most 256 MiB). In MCP,
|
||||
`update_analysis_settings` can override `asar.max_header_bytes` for new
|
||||
operations without restarting REA. Cached headers are checked against each
|
||||
operation's admission, including after a decrease. See the
|
||||
[settings design](design/limits-and-recovery.md#failure-and-retry).
|
||||
An oversized header is
|
||||
not parsed; selecting a member path does not bypass admission, and the page
|
||||
stays unauthorized. The header cache separately retains at most that many bytes
|
||||
of already-admitted encoded headers across eight archives. Evicting that cache does not raise admission.
|
||||
+9
-2
@@ -24,12 +24,17 @@ requires an absolute filesystem path and preserves that exact selection:
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte length.
|
||||
`tables` lists each declared note program header or section, including the
|
||||
section name when a string table is present. Zlib-compressed section-name
|
||||
tables are decompressed within the selected file-size budget. An unsupported
|
||||
section name when a string table is present. Zlib- and Zstandard-compressed
|
||||
section-name tables are decompressed within the selected file-size budget. An unsupported
|
||||
compression type leaves section names unknown and adds a limitation; note bytes
|
||||
remain independently examined. Each `entries[]` item reports owner, type,
|
||||
descriptor SHA-256, and a hex preview for descriptors of 64 bytes or less.
|
||||
|
||||
A section name also stays null when its offset is outside the declared string
|
||||
table or its bytes lack a NUL terminator. A limitation explains that missing
|
||||
name. Note coverage remains complete when all declared note tables and entries
|
||||
were examined; an unavailable section name does not erase those note facts.
|
||||
|
||||
For GNU notes, `gnu.build_id_hex`, `gnu.abi_tag`, or `gnu.gold_version` are
|
||||
filled when the descriptor matches that type. Other owners keep `gnu` null.
|
||||
|
||||
@@ -58,6 +63,8 @@ numbering (`PN_XNUM`, including a section count stored when `e_shnum` is 0) is
|
||||
unsupported and returns an unsupported-target outcome rather than invalid-input
|
||||
recovery.
|
||||
|
||||
Zstandard section-name tables also use a 128 MiB decoder window limit.
|
||||
|
||||
`SHF_COMPRESSED` note sections return `unsupported_target` before their payload
|
||||
is interpreted or decompressed. Their compression header is storage metadata,
|
||||
not a note header. The current result requires physical file offsets for each
|
||||
|
||||
@@ -54,6 +54,72 @@ rules apply to the last occurrence of each chunk name; an empty final occurrence
|
||||
does not revive an earlier payload of that name. Nonempty truncated tables remain
|
||||
format failures.
|
||||
|
||||
## Select retained facts
|
||||
|
||||
Complete output remains the default. Request a summary with a `beam` view to
|
||||
read a few facts in the first call while retaining the complete inspection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_erlang_beam",
|
||||
"arguments": {
|
||||
"path": "/artifacts/app.beam",
|
||||
"detail": "summary",
|
||||
"view": {
|
||||
"kind": "beam",
|
||||
"collection": "exports",
|
||||
"names": ["module_info"],
|
||||
"fields": ["function_index", "function", "arity", "label"],
|
||||
"limit": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`normalized_result.page.items` contains the matching rows. `source_index` is
|
||||
zero-based in the original collection and scoped to `parent_evidence_id` and
|
||||
that collection. It does not replace the original one-based atom `index` or a
|
||||
lambda's own `index`. Every matching function name survives, including different
|
||||
arities. Names are exact retained display strings; raw indexes remain available
|
||||
when names are unresolved or displayed names collide.
|
||||
|
||||
Collections are `atoms`, `exports`, `imports`, `lambdas`, and `chunks`. `names`
|
||||
selects atom/chunk names or function names; imports additionally support exact
|
||||
`modules`. Filters intersect. `indices` selects original collection indexes;
|
||||
`fields` selects that collection's own fields. Empty selector arrays match
|
||||
nothing, and `fields: []` returns only `source_index`. Offset/limit page matching
|
||||
rows in original order (defaults 0/64). Unfiltered pages slice the retained
|
||||
collection; queries do not decode the file again.
|
||||
|
||||
For `chunks`, `names` matches the four-character IFF chunk tag (for example
|
||||
`"AtU8"`, `"Code"`, `"ExpT"`); available `fields` are `index`, `name`,
|
||||
`location`, and `payload`. For `lambdas`, `names` matches the resolved function
|
||||
name from the atom table; `null` names (unresolved atom indices) are never
|
||||
selected by a name filter. For `atoms`, `names` matches the decoded atom name
|
||||
string.
|
||||
|
||||
`beam` keeps the module, form/Code bounds, original source coverage, and table
|
||||
counts. A null count means no table was decoded; zero means a decoded empty
|
||||
table. Missing tables and unresolved atom names remain explicit, and an empty
|
||||
page does not establish runtime absence. Page coverage is separate from the
|
||||
source's examined chunks and parser budgets.
|
||||
|
||||
CLI summary delivery requires a destination for the complete Evidence bundle:
|
||||
|
||||
```sh
|
||||
rea inspect-erlang-beam /artifacts/app.beam --detail summary \
|
||||
--view '{"kind":"beam","collection":"exports","names":["module_info"],"fields":["function","arity"]}' \
|
||||
--evidence_output /reports/app-beam.evidence.json --json
|
||||
rea inspect-analysis-view '{"source":{"kind":"evidence-file","path":"/reports/app-beam.evidence.json"},"view":{"kind":"beam","collection":"imports","modules":["erlang"]}}' --json
|
||||
```
|
||||
|
||||
The bundle retains the complete report. Subsequent MCP queries may use
|
||||
`source: {kind: "retained-evidence", evidence_id: parent_evidence_id}` or an
|
||||
Evidence file. Retained and offline views still work after the original BEAM
|
||||
file is deleted. Supplying `view` requires `detail: "summary"`; omitting it
|
||||
returns only the structural summary. Selection changes delivery, not parsing or
|
||||
coverage, and executes no bytecode.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum). At most
|
||||
|
||||
@@ -285,3 +285,10 @@ REA_FIRMWARE_VERIFY_GHIDRA=1 npm run verify:firmware
|
||||
`scripts/rea.mjs` to verify the packaged CLI/MCP workflow. Real coverage here is
|
||||
generated gzip/USTAR/ext4 with a Linux x64 ELF child; SquashFS, UBIFS, proprietary
|
||||
firmware, other hosts and architectures remain unverified.
|
||||
|
||||
## Inspect extracted devicetrees
|
||||
|
||||
Use [`inspect_devicetree`](devicetree.md) / `rea inspect-devicetree` on an
|
||||
extracted DTB for its node/property tree, reservations, hardware summary and
|
||||
selected phandle relationships. FDT v16/v17 inspection is portable and requires
|
||||
no external tool or disassembler.
|
||||
@@ -0,0 +1,129 @@
|
||||
# GameCube DOL analysis through Ghidra
|
||||
|
||||
This lane imports 32-bit big-endian PowerPC GameCube/Wii DOL images through
|
||||
Ghidra. It does not execute the image. DOL is a headerless format with no magic
|
||||
number, so REA never detects it: the caller must select it explicitly.
|
||||
|
||||
Only the cached MEM1 window `0x80000000..0x81800000` is admitted. Wii MEM2
|
||||
and uncached aliases are outside this lane.
|
||||
|
||||
Not covered: small-data anchors (`r2`/`r13`), REL, RPX, and IDA or Hopper
|
||||
support. See [Not supported yet](#not-supported-yet).
|
||||
|
||||
## Select the format
|
||||
|
||||
CLI:
|
||||
|
||||
```bash
|
||||
rea inspect /absolute/path/to/main.dol --target-format gamecube-dol --provider ghidra --json
|
||||
rea function /absolute/path/to/main.dol 0x80003130 --target-format gamecube-dol --provider ghidra --json
|
||||
```
|
||||
|
||||
MCP, with the existing `open_binary` tool:
|
||||
|
||||
```json
|
||||
{
|
||||
"path": "/absolute/path/to/main.dol",
|
||||
"provider_id": "ghidra",
|
||||
"format": "gamecube-dol"
|
||||
}
|
||||
```
|
||||
|
||||
The architecture comes from the DOL header (`powerpc`). Do not pass
|
||||
`architecture` with `gamecube-dol`; it is rejected. `entry_point` is optional,
|
||||
and if given it must equal the header entry.
|
||||
|
||||
Omitting `format` never imports a file as a DOL. Detection does not run for DOL.
|
||||
|
||||
## What the import does
|
||||
|
||||
REA reads the 256-byte DOL header at admission. It checks every section's file
|
||||
range and load address. It records BSS/data overlaps and computes the exact
|
||||
uninitialized BSS gaps once. Malformed headers are refused before Ghidra starts.
|
||||
|
||||
Ghidra then runs in two steps:
|
||||
|
||||
1. The standard `BinaryLoader` maps the whole file at base `0x0`, with
|
||||
`-processor` and `-cspec` taken from the language selection below.
|
||||
2. The pre-script `bridge/ghidra/ReaGhidraPrepareDol.java` reads a section file
|
||||
that REA wrote from the parsed header, with versioned collection counts. It creates one initialized block per
|
||||
used text and data section at its load address, with file bytes from the
|
||||
section's file offset. The whole-file block is removed before the section
|
||||
blocks are created. Text is read-execute and data is read-write. It sets the
|
||||
entry point and labels the entry
|
||||
`__start`.
|
||||
|
||||
Sections that the header marks unused are not mapped. The 256-byte header and
|
||||
any bytes between sections are not mapped either.
|
||||
|
||||
## BSS
|
||||
|
||||
A DOL has one BSS range, and it is not always disjoint from the data sections.
|
||||
The domain parser computes the parts of BSS that no data section covers. Both
|
||||
the pre-script and load-image attestation consume those parsed ranges. The
|
||||
pre-script creates uninitialized read-write blocks only in those gaps. Where BSS overlaps a data slot, that slot
|
||||
keeps its file bytes. Overlapping slot indexes are reported by the parser.
|
||||
|
||||
## Bound language
|
||||
|
||||
The default language is `PowerPC:BE:32:default` with compiler spec `default`,
|
||||
which ships with Ghidra. The load-image attestation checks the language Ghidra
|
||||
reports, not only the requested one.
|
||||
|
||||
### Optional Gekko/Broadway override
|
||||
|
||||
`REA_GHIDRA_LANGUAGE_ID=PowerPC:BE:32:Gekko_Broadway` selects the Gekko/Broadway
|
||||
variant. The language is not in stock Ghidra. It comes from the GameCubeLoader
|
||||
extension, by Cuyler, licensed under Apache-2.0. The extension ships
|
||||
`ppc_gekko_broadway.ldefs` under its `data/languages` directory and must be
|
||||
installed in the Ghidra installation's `Ghidra/Extensions` directory. The stock
|
||||
lane never requires it.
|
||||
|
||||
Any other language id must start with `PowerPC:BE:32:`. Other languages are
|
||||
refused with a specific constraint.
|
||||
|
||||
## Paired-single limitation
|
||||
|
||||
The stock `PowerPC:BE:32:default` language does not decode the paired-single
|
||||
instructions that Gekko and Broadway add. Those words decode as bad or undefined
|
||||
instructions. Use the Gekko override to decode them.
|
||||
|
||||
## Verification
|
||||
|
||||
The source-owned fixture is built from `tests/conformance/c/ppc.c`,
|
||||
`tests/conformance/c/dol.c`, `tests/conformance/ghidra/ppc-probe.S` and the
|
||||
linker script `tests/conformance/ghidra/dol-fixture.ld`. It is converted to a DOL
|
||||
by `tests/conformance/ghidra/dol-fixture.mjs`. Its text is at `0x80003100`, and
|
||||
its single BSS range overlaps data slot 1 and leaves a gap. The fixture is
|
||||
never executed. The real GameCube or Wii game images are never used.
|
||||
|
||||
```bash
|
||||
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:dol
|
||||
```
|
||||
|
||||
The lane needs the same toolchain as the PowerPC ELF lane: `REA_PPC_CLANG`,
|
||||
`REA_PPC_READELF` and LLD. An independent DOL header reader and GNU readelf
|
||||
(run on the source ELF) check the section table, file bytes, entry and BSS gap
|
||||
before Ghidra starts. The checks never use REA's parser.
|
||||
|
||||
After import, the lane checks the load-image attestation (`verified`), the
|
||||
bound language, the `__start` entry procedure, a direct call to the leaf
|
||||
function, decompilation, and bytes at the data, tail, marker and BSS-gap
|
||||
addresses. It also checks CLI identity.
|
||||
|
||||
The Gekko pass runs only when `PowerPC:BE:32:Gekko_Broadway` is in the Ghidra
|
||||
installation's language catalog, the same catalog REA uses to admit
|
||||
`REA_GHIDRA_LANGUAGE_ID`. A language that exists only in a user extension under
|
||||
`~/Library/ghidra` is not admitted, so the lane prints
|
||||
`skipped: PowerPC:BE:32:Gekko_Broadway (not in the Ghidra installation catalog that REA admits); stock lane still verified`
|
||||
and still succeeds on the stock checks.
|
||||
|
||||
The ELF lane (`npm run verify:ghidra:ppc`) is separate. See
|
||||
[PowerPC ELF analysis through Ghidra](/ghidra-ppc).
|
||||
|
||||
## Not supported yet
|
||||
|
||||
- Small-data anchors: `r2` and `r13` are not seeded from the DOL header.
|
||||
- REL (relocatable modules) and RPX (Wii U) are not admitted.
|
||||
- IDA and Hopper refuse `gamecube-dol`. Ghidra is the only provider.
|
||||
- Disc images (ISO/GCM) are not supported. Pass an extracted DOL file.
|
||||
+12
-7
@@ -29,13 +29,18 @@ point using the available structural bytes and actual file length. It reports
|
||||
those DOS facts separately from Windows-header evidence. A recognized PE
|
||||
signature remains PE; recognized NE, LE, and LX headers are explicitly
|
||||
unsupported. A nonzero Windows-header pointer without a recognized signature
|
||||
remains an unresolved candidate, even when the DOS structure validates:
|
||||
automatic target selection fails closed and reports both observations.
|
||||
REA does not infer DOS intent from padding or infer a damaged Windows header
|
||||
from the pointer alone. Inventory classification is a bounded-prefix format
|
||||
hint; it returns `unknown` for that candidate or when its prefix cannot
|
||||
establish the format. That result is distinct from complete DOS validation and
|
||||
does not decide target admission.
|
||||
usually remains an unresolved candidate, even when the DOS structure validates:
|
||||
automatic target selection fails closed and reports both observations. When a
|
||||
nonempty relocation table ends inside a complete DOS header, the remaining
|
||||
header bytes belong to DOS padding; a nonzero dword there is not a Windows
|
||||
declaration. An unread signature beyond the current probe is requested before
|
||||
that padding rule applies. This avoids manufacturing a Windows header from
|
||||
original DOS padding while preserving rejection of damaged Windows
|
||||
declarations.
|
||||
Inventory classification is a bounded-prefix format hint; it returns `unknown`
|
||||
for an unresolved candidate or when its prefix cannot establish the format.
|
||||
That result is distinct from complete DOS validation and does not decide target
|
||||
admission.
|
||||
|
||||
Ghidra imports a private target snapshot with `MzLoader`, language
|
||||
`x86:LE:16:Real Mode`, and compiler specification `default`. These settings,
|
||||
|
||||
+13
-4
@@ -24,7 +24,8 @@ specific unsupported constraint rather than guessing a compatible profile.
|
||||
|
||||
A second admission covers recordless legacy firmware images
|
||||
([#1620](https://github.com/morluto/rea/issues/1620)): ELF32 `ET_EXEC` headers
|
||||
declaring `EF_MIPS_ARCH_32` or `EF_MIPS_ARCH_32R2` with an unspecified ABI
|
||||
declaring `EF_MIPS_ARCH_1` (MIPS-I, a zero ISA field), `EF_MIPS_ARCH_32` or
|
||||
`EF_MIPS_ARCH_32R2` with an unspecified ABI
|
||||
field, `EF_MIPS_ABI2` clear, and an _inspected_ absence of any ABI flags
|
||||
record (a target whose record was merely not observed stays refused). For
|
||||
these images o32 is an analysis assumption derived from the ELF32/ET_EXEC
|
||||
@@ -40,9 +41,17 @@ refusal. A header that declares an ABI field but carries no record is still
|
||||
refused. Two further boundaries apply: an inspection that could not examine
|
||||
every ABI declaration source (for example a carved ELF whose section table
|
||||
extends past the captured bytes without a program-header record) does not
|
||||
establish the recordless admission, and an `EF_MIPS_ARCH_32` header that
|
||||
_declares_ an ABI is refused rather than relabeled, because the declared-ABI
|
||||
lane is verified for `EF_MIPS_ARCH_32R2` headers only.
|
||||
establish the recordless admission, and an `EF_MIPS_ARCH_1` or
|
||||
`EF_MIPS_ARCH_32` header that _declares_ an ABI is refused rather than
|
||||
relabeled, because the declared-ABI lane is verified for
|
||||
`EF_MIPS_ARCH_32R2` headers only. The recordless MIPS-I lane pins the same
|
||||
generic 32-bit language, which also decodes later MIPS32 instructions; the
|
||||
session states that conformance to the MIPS-I subset is not established from
|
||||
the header alone, and names the committed language when the caller selected a
|
||||
variant instead of the pin. A committed profile is bound to the current
|
||||
target's lane and captured ELF metadata before startup; reusing a profile
|
||||
resolved for the other recordless lane is refused rather than exporting
|
||||
attribution for a target it did not describe.
|
||||
|
||||
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
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@
|
||||
This lane extends native ELF analysis to 32-bit big-endian PowerPC; it does
|
||||
not execute PowerPC code. It is the first milestone of
|
||||
[#1741](https://github.com/morluto/rea/issues/1741). GameCube/Wii DOL
|
||||
executables, PPC64 and other PowerPC variants are separate follow-ups.
|
||||
executables are covered by [GameCube DOL analysis](ghidra-dol.md). PPC64 and other
|
||||
PowerPC variants remain separate follow-ups.
|
||||
|
||||
## Admission boundary
|
||||
|
||||
|
||||
+20
-1
@@ -36,6 +36,18 @@ 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.
|
||||
|
||||
## Request payload ceiling
|
||||
|
||||
Ghidra requests use `REA_BRIDGE_MAX_REQUEST_BYTES`: default 16 MiB, with a
|
||||
configurable range of 7,464–536,870,887 bytes. REA measures UTF-8 JSON, including
|
||||
escaping, before allocating the serialized request or sending it. The framing
|
||||
newline is excluded. An oversized request returns `resource_constraint` with
|
||||
the effective setting, its source, and the exact payload byte count.
|
||||
|
||||
Set the value in the environment that starts REA, then restart REA to apply it.
|
||||
This setting is enforced by the REA client; the Java bridge has no corresponding
|
||||
request ceiling.
|
||||
|
||||
## Admitted inventory semantics
|
||||
|
||||
| Concern | Ghidra contract |
|
||||
@@ -175,7 +187,7 @@ profile stages before retrying their retained descriptors.
|
||||
|
||||
| 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 unless `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS` sets one; a decompile that reaches it fails only that request with `remote_code` `decompile_timed_out`, the Program and session stay open, and the next decompile uses a fresh decompiler process. External functions or functions without bodies return `null`; cancellation and native failure remain distinct. |
|
||||
| Decompiler lifetime | One persistent `DecompInterface` is opened for the imported Program and disposed during bridge shutdown. Native decompilation has no fixed per-function deadline unless the launch setting `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS` or runtime override `ghidra.decompile_timeout_seconds` sets one; a decompile that reaches it fails only that request with `remote_code` `decompile_timed_out`, the Program and session stay open, and the next decompile uses a fresh decompiler process. 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. |
|
||||
@@ -185,6 +197,13 @@ profile stages before retrying their retained descriptors.
|
||||
| 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. |
|
||||
|
||||
Runtime updates apply to newly accepted operations on the existing Program.
|
||||
They preserve accepted budgets and do not clear cleanup blockers or change the
|
||||
client deadline. Transient decompile timeout failures remain uncached so the
|
||||
same function can be retried after raising the limit. See the
|
||||
[settings design](design/limits-and-recovery.md) for snapshots, precedence,
|
||||
and provider integration.
|
||||
|
||||
Function extents and instruction completeness refer to Ghidra's analyzed body.
|
||||
An inferred no-return call can terminate that body before subsequent bytes.
|
||||
Pseudocode, assembly, procedure info, instruction windows, incoming and outgoing
|
||||
|
||||
@@ -7,6 +7,9 @@ releases have not been verified. Format 1 is unsupported.
|
||||
|
||||
Inspection retains the original header and directory facts, including engine
|
||||
version, flags, declared file count, source paths, offsets and declared MD5.
|
||||
For a member declared as `res://scenes/main.gd`, the occurrence's
|
||||
`source_path` retains that exact declaration while `logical_path` is
|
||||
`scenes/main.gd`, the relative path used for lookup and extraction.
|
||||
Observed plaintext bytes receive content-addressed SHA-256 identities. MD5 is a
|
||||
container integrity claim, separate from the observed SHA-256. A mismatch fails
|
||||
by default; `--integrity-policy record-and-continue` retains the observed bytes
|
||||
|
||||
@@ -140,7 +140,7 @@ Add the registration path to the **REA** MCP entry's environment, keeping the up
|
||||
}
|
||||
```
|
||||
|
||||
Use a package version that actually includes this adapter; repository main can be ahead of the npm release. After reconnecting, call:
|
||||
Use a package version that actually includes this adapter; repository main can be ahead of the npm release. After reconnecting, call the sequence below; the default `analyze_function` reply is a summary that retains the dossier, so add `"detail":"complete"` when the dossier itself must come back inline:
|
||||
|
||||
```json
|
||||
{"name":"open_binary","arguments":{"path":"/absolute/path/to/program","provider_id":"ida"}}
|
||||
|
||||
+156
-31
@@ -58,18 +58,22 @@ the original rows without reopening or decoding the file:
|
||||
|
||||
Collections are `sections`, `images`, `types`, `methods`, `fields`,
|
||||
`properties`, `events`, `parameters`, `string_literals`, `method_addresses`,
|
||||
`return_types`, `field_types`, `parameter_types` and `code_gen_modules`. Every returned row includes
|
||||
`return_types`, `field_types`, `parameter_types`, `code_gen_modules`,
|
||||
`generic_method_instances` and `generic_method_issues`. Every returned row includes
|
||||
its source `index`, scoped by artifact SHA-256 and collection. All collections
|
||||
accept batch `indices` and `fields`. Exact `names` filtering is supported for
|
||||
`sections`, `images`, `types`, `methods`, `fields`, `properties`, `events` and
|
||||
`parameters`; native `return_types`, `field_types` and `parameter_types` rows
|
||||
are selected by source indices (or `method_indices` for `parameter_types`),
|
||||
not rendered names. Types also accept `image_indices`, `namespaces` and
|
||||
`sections`, `images`, `types`, `methods`, `fields`, `properties`, `events`,
|
||||
`parameters`, `return_types`, `field_types`, `parameter_types` and
|
||||
`generic_method_instances`. Native type names match the retained rendered display value exactly; every same-name row
|
||||
keeps its source index, and an unavailable (`null`) name never matches a string.
|
||||
Types also accept `image_indices`, `namespaces` and
|
||||
`declaring_types`; methods, fields, properties and events accept
|
||||
`declaring_types`. Parameters accept exact `method_indices`, so a batch of
|
||||
method indices retrieves their parameters without reading the entire parameter
|
||||
table. `parameter_types` accepts the same `method_indices`, resolved through the
|
||||
retained `parameters` owners; Evidence without `parameters` refuses that filter. Filters intersect, duplicate indices are returned once, and
|
||||
retained `parameters` owners; Evidence without `parameters` refuses that filter. Generic method instances
|
||||
accept `method_indices` (definition indices) and `states`; generic method
|
||||
issues accept `rows` (the instance rows they leave unknown). Filters intersect, duplicate indices are returned once, and
|
||||
rows retain metadata order. An empty filter selects no rows; `fields: []`
|
||||
returns indices only. Omitted fields return the complete selected rows.
|
||||
|
||||
@@ -113,7 +117,9 @@ Historical Evidence that predates these member collections remains queryable.
|
||||
A missing collection has an unknown (`null`) summary count, and requesting it
|
||||
reports that it was not collected; it is never presented as an empty inventory. The same holds for Evidence that predates binary linking: its summary
|
||||
omits `binary`, and `method_addresses`, `method_address_states`,
|
||||
`return_types`, `field_types` and `parameter_types` counts are `null`.
|
||||
`return_types`, `field_types` and `parameter_types` counts are `null`. A link retained before
|
||||
generic instances existed omits `binary.generic_methods`, and the
|
||||
`generic_method_instances` and `generic_method_issues` counts are `null`.
|
||||
Existing empty collections retain a zero count. Full Evidence is preserved.
|
||||
|
||||
`offset` counts matching rows, not source indices. `limit` defaults to 64;
|
||||
@@ -146,8 +152,9 @@ in [CLI and Evidence](cli.md#run-a-command). Compact delivery requires
|
||||
`--evidence_output`; existing files are never overwritten. The full export
|
||||
preserves every decoded row for subsequent queries without the original file.
|
||||
|
||||
`--binary PATH` links method addresses and `--architecture arm64|amd64` selects
|
||||
exactly one slice of a universal Mach-O. The report retains the native reader's
|
||||
`--binary PATH` links method addresses, `--architecture arm64|amd64` selects
|
||||
exactly one slice of a universal Mach-O and `--generic-instances` adds generic
|
||||
method instances. The report retains the native reader's
|
||||
`amd64` spelling for x86-64; loader CPU checks use the corresponding `x86_64`
|
||||
identity. Multiple slices with the same architecture label are refused as
|
||||
`ambiguous-slice-selection`, including
|
||||
@@ -234,7 +241,7 @@ record addresses remain distinct candidates, and conflicting file mappings
|
||||
remain malformed.
|
||||
|
||||
Module records establish names through their declared NUL-terminated string pointers. NUL/0xFF padding, spaces, Unicode and suffix-shared storage are supported. A pointer to a longer string does not match just its suffix; a pointer directly into a shared suffix may name it. Exact reversed UTF-8 matching avoids rescanning the file for every name and retains duplicate-name owners until module records resolve them. A contributor investigated a Linux
|
||||
`GameAssembly.so` from Unity 2023.2.13f1 whose static registration was not located. When no static pair is resolved on x86-64, the reader searches executable ranges for bytes consistent with RIP-relative LEA/MOV references to module-array candidates. Exactly one referenced array candidate must remain. `code_gen_modules_field` is then `null`, and Evidence is **inferred**: instruction boundaries, the absence of a static registration elsewhere, and runtime use were not verified. The module records and slots themselves remain file observations. Static-table associations are **derived**. Otherwise the result is `code-registration-not-found`.
|
||||
`GameAssembly.so` from Unity 2023.2.13f1 whose static registration was not located. When no static pair is resolved on x86-64 or arm64, the reader searches executable ranges for bytes consistent with a reference to a module-array candidate: RIP-relative LEA/MOV on x86-64, an adjacent `adrp`/`add` pair on arm64. Exactly one referenced array candidate must remain. `code_gen_modules_field` is then `null`, and Evidence is **inferred**: instruction boundaries, the absence of a static registration elsewhere, and runtime use were not verified. The module records and slots themselves remain file observations. Static-table associations are **derived**. Otherwise the result is `code-registration-not-found`. Cpp2IL's StrippedCodeRegSupport plugin also recovers the module list of an inlined CodeRegistration from the module names; this fallback additionally requires the exact located module set and a single code reference. A Unity 2022.3.62f3 macOS Master build checked by a contributor keeps neither registration symbol; its type table is then inferred as described below.
|
||||
|
||||
The binary/metadata pair is caller-selected. Name/count/token agreement is structural evidence, not a cryptographic same-build proof. File-offset locations refer to the primary metadata artifact; linked virtual addresses refer to `binary.artifact`. Both SHA-256 identities remain available in compact native pages as `artifact` and `binary_source`.
|
||||
|
||||
@@ -292,6 +299,30 @@ The result adds:
|
||||
`Il2CppMetadataRegistration.typesCount` and its value. That record is found as
|
||||
the single place whose `fieldOffsetsCount` and `typeDefinitionsSizesCount` both
|
||||
equal the metadata type-definition count and whose type table is file mapped.
|
||||
Linking reads only that table. When no record on x86-64 or arm64 has both of
|
||||
those counts, the reader collects maximal runs of pointers to Il2CppType-shaped
|
||||
records (an assigned Il2CppTypeEnum kind from 0x01 to 0x1e; class and
|
||||
value-type data below the type-definition count) that are long enough for every
|
||||
type index the metadata references. Exactly one such run may exist in the
|
||||
image, it must start and end inside its mapping (a run touching either end may
|
||||
continue in a neighbouring mapping), and its start must be loaded by the same
|
||||
instruction forms as the module-array fallback. `types_field` is then `null`,
|
||||
`types_count` is that run's length rather than an observed `typesCount`, and
|
||||
Evidence is **inferred**. The run length is at least every referenced type
|
||||
index but can differ from `typesCount`: a type-shaped pointer after the table
|
||||
would lengthen it, and an unreadable slot (such as an unresolved relocation)
|
||||
would end it early. Only the type indices the metadata references are read. A
|
||||
second long-enough run anywhere, a run that a type-shaped neighbour extends
|
||||
before the loaded address, a run touching a mapping end or a slot the loader
|
||||
binds or leaves unresolved (its stored word is only a placeholder), and a covered
|
||||
128-byte record whose two counts match but whose other fields are unusable all
|
||||
leave `metadata-registration-not-found` rather than a guess; the search stops
|
||||
at the second run. The length requirement only separates the type table from
|
||||
other pointer runs when the metadata references most of it: on the one Master
|
||||
build checked, the highest referenced index is 6,031 of 6,576 entries. A
|
||||
metadata referencing few type indices usually
|
||||
leaves several short runs and fails closed.
|
||||
|
||||
Counts use their declared 32-bit width independently of alignment padding.
|
||||
The complete 128-byte registration must have unambiguous loader coverage. Its
|
||||
used fields through byte 112 must be file-backed; a trailing declared zero-fill
|
||||
@@ -306,6 +337,93 @@ fixtures; they do not add real Unity-build verification to the checks above.
|
||||
Without `binary_path`, `binary` is `null` and the four binary collections are
|
||||
empty in the complete producer report to indicate unrequested observations. Their summary counts, including state counts, are `null`, and native page requests report unavailable observations. This does not establish an empty native inventory. Missing native fields in historical Evidence remain unknown too.
|
||||
|
||||
### Generic method instances
|
||||
|
||||
`generic_instances: true` (CLI `--generic-instances`, needs `binary_path`) also
|
||||
links the instances in `Il2CppMetadataRegistration.genericMethodTable`, as
|
||||
Il2CppDumper does: each row's `genericMethodIndex` selects an `Il2CppMethodSpec`
|
||||
(generic method definition plus class and method `Il2CppGenericInst`), and its
|
||||
`methodIndex` selects a `genericMethodPointers` slot. Without the option both
|
||||
fields below are `null` (not linked, so unknown), as are the summary counts
|
||||
`generic_method_instances` and `generic_method_instance_states` and the seed
|
||||
counts. The result adds:
|
||||
|
||||
- `binary.generic_methods`: `generic_method_pointers_field` (the address of
|
||||
`genericMethodPointersCount`), the pointer, table, method spec and generic
|
||||
instance counts, `generic_method_table_stride` and `issues` (each with the
|
||||
`row` it leaves unknown, the `address` of the contradicting row, method spec
|
||||
or pointer slot record, and a `message`);
|
||||
- `generic_method_instances`: one row per table entry (row position is the
|
||||
table index) with `method_spec`, `method` (the recorded definition index,
|
||||
including invalid values, or `null` when the index cannot be read),
|
||||
`name`, and `state`, `address` and `rva` as in `method_addresses`: `code`,
|
||||
`no-body` for a zero pointer slot, or `unknown` exactly when an issue names
|
||||
the row.
|
||||
|
||||
Names follow Il2CppDumper's `GetMethodSpecName`, for example
|
||||
`System.Collections.Generic.Dictionary<int, string>$$TryGetValue` or
|
||||
`System.HashCode$$Add<int>`: namespaces only on the declaring type, nested types
|
||||
joined with `.`, the backtick arity cut, `IntPtr`/`UIntPtr`/`TypedReference`
|
||||
and no byref mark. These names do not depend on the byref bit, so version 27 is
|
||||
covered.
|
||||
|
||||
Header versions do not separate the CodeRegistration layouts (27.0, 27.1 to
|
||||
29 and 29.1/31 differ in the fields before `codeGenModulesCount`). Every layout for the header version is tried, and
|
||||
exactly one must have a `genericMethodPointers` count and an invoker count that
|
||||
bound every table row; the layout also fixes the row size (12 bytes, or 16 with
|
||||
an adjustor thunk index). No layout agreeing fails as
|
||||
`generic-method-registration-not-found`, more than one as
|
||||
`ambiguous-generic-method-registration`. An empty table selects no layout:
|
||||
the result has no rows, and `generic_method_pointers_field`,
|
||||
`generic_method_pointers_count` and `generic_method_table_stride` are `null`.
|
||||
A table of a few rows can still leave two layouts agreeing, which fails as
|
||||
ambiguous rather than picking one. Metadata versions 24 and 39 and builds
|
||||
without a static CodeRegistration (`code_gen_modules_field` `null`) or
|
||||
MetadataRegistration (`types_field` `null`) fail as
|
||||
`generic-methods-unsupported`: for version 24 the type-definition generic
|
||||
container offset and the generic class layout have not been checked against a
|
||||
real build, so it is refused rather than guessed.
|
||||
|
||||
After the layout is fixed, rows that contradict another table do not fail the
|
||||
whole link: a method spec naming a method or generic instance out of range,
|
||||
class or method arguments whose count differs from the generic container the
|
||||
owner declares (none for a non-generic type or method), an owner whose generic
|
||||
container index is out of range, a name that cannot be rendered, or a pointer slot that is unmapped, has an
|
||||
unresolved relocation or points outside unambiguous executable file data adds
|
||||
an `issues` entry, and that row is `unknown` with no address. A method spec
|
||||
issue also leaves `name` `null`, even when the pointer slot is valid: the slot
|
||||
would otherwise be reported under a definition nothing confirms. Capacity
|
||||
refusals are never turned into issues. Rows that share one method spec
|
||||
(Il2CppDumper refuses such a table) each get an issue at their row address that
|
||||
names one other sharing row, and all of them lose `name` and become `unknown`.
|
||||
A zero pointer slot is a `no-body` row and has no issue. Before any row is
|
||||
resolved, the smallest row for every table entry is checked against the
|
||||
remaining report budget; each row and issue is then admitted as it is retained.
|
||||
Compact summaries omit `binary.generic_methods.issues` and keep its count in
|
||||
`counts.generic_method_issues`; query `collection: "generic_method_issues"`
|
||||
with `rows`, `indices`, `fields` and pagination. Select only the instance and
|
||||
issue facts needed for the question. For a small report where both collections
|
||||
are needed, `detail: "complete"` can cost less than a summary followed by two
|
||||
pages. Paging saves irrelevant row text but adds calls and schema overhead; it
|
||||
does not imply lower total latency or memory. See the
|
||||
[completed-query measurements](verification/il2cpp-generic-instances-2026-10-24.md).
|
||||
Like method addresses, these rows are derived from static tables; layout agreement
|
||||
is structural evidence, not proof of runtime use.
|
||||
|
||||
Contributor-reported verification against Il2CppDumper's `script.json` (same
|
||||
`Address` and `Name`):
|
||||
macOS arm64 and x86_64 slices from Unity 2020.3.49f1, 2021.1.28f1 (version 27),
|
||||
2021.3.45f2, 2022.3.30f1 (29), 2022.3.62f3 and 6000.0.84f1 (31); Android arm64
|
||||
from 2022.3.62f3; and the Windows x64 build from 2023.2.13f1 named above
|
||||
(`GameAssembly.dll` SHA-256
|
||||
`a3ae7f6ecd1f671297b7d98d12713ef024062d93cd7a4205298102656c93b67a`). On every
|
||||
build each linked instance matches an Il2CppDumper entry by address and name,
|
||||
and Il2CppDumper lists no address-name pair that REA leaves out (Windows: 63,750
|
||||
linked rows, 142 without code; Android: 5,152 and 44). This does not establish
|
||||
names for versions 24 or 39, for type arguments that are open generic type
|
||||
definitions, or anything about instances created at runtime. The Linux build
|
||||
from 2023.2.13f1 keeps no static CodeRegistration and is refused.
|
||||
|
||||
For metadata version 27, type names are `null` and only type indices are
|
||||
reported: versions 27.0 to 27.2 share that header number but place the
|
||||
Il2CppType byref flag in different bits, so a rendered name could gain or lose
|
||||
@@ -313,22 +431,25 @@ Il2CppType byref flag in different bits, so a rendered name could gain or lose
|
||||
|
||||
The builds checked are listed after the module search rules above.
|
||||
|
||||
| Reason | Category | Meaning |
|
||||
| --------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `unsupported-container` | unsupported | Not a 64-bit little-endian Mach-O, PE or ELF image (ELF: AArch64 or x86-64 with dynamic section). |
|
||||
| `slice-selection-required` | unsupported | A universal Mach-O was given without `binary_architecture`. |
|
||||
| `ambiguous-slice-selection` | unsupported | More than one universal slice matches the selected architecture label; select an exact subtype externally. |
|
||||
| `slice-not-found` | unsupported | The requested slice is absent, or a thin binary was given an architecture. |
|
||||
| `unsupported-pointer-encoding` | unsupported | Mach-O chained fixups or Android packed (APS2) ELF relocations; pointers not decoded. |
|
||||
| `malformed-container` | input error | The container headers are damaged. |
|
||||
| `code-gen-modules-not-found` | input error | An image has no module record; often a binary from a different build. |
|
||||
| `ambiguous-code-gen-module` | input error | More than one module record matches an image. |
|
||||
| `code-registration-not-found` | input error | No unique module table or executable-byte array candidate was resolved. |
|
||||
| `invalid-method-token` | input error | A token is outside its module's method-pointer rows, or a MethodDef row is reused within one image. |
|
||||
| `invalid-method-pointer` | input error | A slot is unavailable or its nonzero address lacks unambiguous executable file coverage. |
|
||||
| `metadata-registration-not-found` | input error | No single MetadataRegistration matches the type-definition count. |
|
||||
| `invalid-type` | input error | A type index or `Il2CppType` record is out of range, unmapped or malformed. |
|
||||
| `unsupported-type-kind` | unsupported | A valid type kind has no implemented rendering. |
|
||||
| Reason | Category | Meaning |
|
||||
| --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `unsupported-container` | unsupported | Not a 64-bit little-endian Mach-O, PE or ELF image (ELF: AArch64 or x86-64 with dynamic section). |
|
||||
| `slice-selection-required` | unsupported | A universal Mach-O was given without `binary_architecture`. |
|
||||
| `ambiguous-slice-selection` | unsupported | More than one universal slice matches the selected architecture label; select an exact subtype externally. |
|
||||
| `slice-not-found` | unsupported | The requested slice is absent, or a thin binary was given an architecture. |
|
||||
| `unsupported-pointer-encoding` | unsupported | Mach-O chained fixups or Android packed (APS2) ELF relocations; pointers not decoded. |
|
||||
| `malformed-container` | input error | The container headers are damaged. |
|
||||
| `code-gen-modules-not-found` | input error | An image has no module record; often a binary from a different build. |
|
||||
| `ambiguous-code-gen-module` | input error | More than one module record matches an image. |
|
||||
| `code-registration-not-found` | input error | No unique module table or executable-byte array candidate was resolved. |
|
||||
| `invalid-method-token` | input error | A token is outside its module's method-pointer rows, or a MethodDef row is reused within one image. |
|
||||
| `invalid-method-pointer` | input error | A slot is unavailable or its nonzero address lacks unambiguous executable file coverage. |
|
||||
| `metadata-registration-not-found` | input error | No single MetadataRegistration or code-loaded type-table candidate was resolved. |
|
||||
| `invalid-type` | input error | A type index or `Il2CppType` record is out of range, unmapped or malformed. |
|
||||
| `unsupported-type-kind` | unsupported | A valid type kind has no implemented rendering. |
|
||||
| `generic-methods-unsupported` | unsupported | Generic instances were requested for metadata version 24 or 39, or a build lacks either static registration. |
|
||||
| `generic-method-registration-not-found` | input error | No CodeRegistration layout bounds every genericMethodTable row, or the generic tables are unreadable. |
|
||||
| `ambiguous-generic-method-registration` | input error | More than one CodeRegistration layout bounds every genericMethodTable row. |
|
||||
|
||||
Format and selection failures name `binary_path`; capacity refusals remain typed resource errors. Failed linking preserves the metadata source identity, validated counts, selected binary path/architecture and its SHA-256 when observed, plus prior producer observations. It never publishes an incomplete native table as complete. The binary input is bounded to 1 GiB.
|
||||
|
||||
@@ -338,7 +459,7 @@ ELF RELATIVE writes into zero-fill are kept as a private virtual-pointer overlay
|
||||
|
||||
ELF relocation tables and file-backed destinations may span adjacent load ranges when every range agrees on the file translation. Any overlapping zero-fill declaration makes those bytes ambiguous; REA refuses the table or relocation destination instead of choosing the stored file bytes. Missing file bytes remain distinct from conflicting owners: supported unresolved relocations outside file-backed memory retain their unknown overlay, while ambiguous destinations refuse linking. Registration coverage uses the same file/zero-fill ownership checks as pointer reads.
|
||||
|
||||
Native address queries batch exact 64-bit hexadecimal `addresses` and `states` (`code`, `no-body`, `unknown`), intersecting indices and pagination. Numerically equal address spellings match; original row indices and every shared-body alternative survive:
|
||||
Native address queries batch exact 64-bit hexadecimal `addresses` and `states` (`code`, `no-body`, `unknown`), intersecting indices and pagination; `generic_method_instances` accepts the same filters plus `method_indices` (generic definition indices). Numerically equal address spellings match; original row indices and every shared-body alternative survive:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -377,7 +498,10 @@ loaders place the binary: `0x100000` for an ELF linked at 0, and the link base
|
||||
for Mach-O and PE; `--seed-base 0x...` overrides it for a different import. When
|
||||
identical code folding gives several methods one address, the first method names
|
||||
the function and a `# folded <address> <kept> also <names>` comment line after
|
||||
the seeds lists the others, so the kept name is visibly one of several. Ghidra still names a seeded function that is a thunk after its
|
||||
the seeds lists the others, so the kept name is visibly one of several. With
|
||||
`--generic-instances`, linked generic instances are seeded after the method
|
||||
definitions under their Il2CppDumper-style names; an instance sharing an
|
||||
address with a definition or another instance is folded the same way. Ghidra still names a seeded function that is a thunk after its
|
||||
target. The file is atomically published with exclusive creation; an existing destination is never replaced. Failed staging retains its cleanup owner for retry. Source digest and link/seed-base comments make the mapping inspectable. Unknown slots are skipped separately from observed no-body slots. `--seed-base` requires `--ghidra-seeds`; overflowing rebased addresses and names/outputs beyond the existing Ghidra protocol limits (2,000 name characters, 32 MiB file, 1,000,000 entries) are refused before publication. The CLI and reusable service use one formatter and owned output workflow; ordinary MCP inspection remains read-only.
|
||||
|
||||
## Failures
|
||||
@@ -430,10 +554,11 @@ report limit can still require the summary and paging path.
|
||||
|
||||
- Decrypting or deobfuscating protected metadata.
|
||||
- Linking Mach-O binaries that use chained fixups, ELF images with Android
|
||||
packed (APS2) relocations, and 32-bit images; generic method instances,
|
||||
adjustor thunks and invokers.
|
||||
packed (APS2) relocations, and 32-bit images; adjustor thunks and invokers;
|
||||
generic method instances for metadata versions 24 and 39 or builds without a static
|
||||
CodeRegistration.
|
||||
- Full method signatures beyond the rendered field, parameter and return type
|
||||
names, generic method instances, and type names for metadata version 27.
|
||||
names, and type names for metadata version 27.
|
||||
- Running Ghidra or another disassembler. `--ghidra-seeds` only writes a seed
|
||||
file for [`REA_GHIDRA_SEED_FILE`](installation.md); use the
|
||||
[native workflow](native-investigation.md) for native code.
|
||||
|
||||
+14
-13
@@ -47,19 +47,20 @@ For runtime instrumentation, see the [Frida guide](./frida-instrumentation.md).
|
||||
|
||||
## Choose a guide
|
||||
|
||||
| Task | Guides |
|
||||
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Identify a desktop installation | [Runtime candidates, evidence and follow-up files](desktop-applications.md) |
|
||||
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [ELF notes](elf-notes.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
|
||||
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [Kuna](kuna-provider.md), [JEB](jeb-analysis.md) |
|
||||
| Analyze JavaScript or Electron artifacts | [Static analysis](javascript-artifact-reconstruction.md), [tracing and comparisons](javascript-application-workflows.md), [application graph](javascript-application-graph.md), [source recovery](javascript-recovery.md) |
|
||||
| Compare static JavaScript with runtime observations | [Runtime attribution](javascript-runtime-observation.md), [reconciliation](javascript-runtime-reconciliation.md), [Electron observation](electron-observation.md), [Electron fuses](electron-fuses.md) |
|
||||
| Inspect assemblies, packages, or firmware | [Godot PCK](godot-pck.md), [.NET](managed-code-analysis.md), [Python packages](python-packaged-applications.md), [Android](android-analysis.md), [APK signatures](apk-signature.md), [Apktool resources](apktool-resource-analysis.md), [ADB acquisition](adb-device-analysis.md), [Apple](apple-application-analysis.md), [Harmony](harmony-analysis.md), [firmware](firmware-analysis.md), [WASM](wasm-artifacts.md), [EVM](evm-bytecode.md) |
|
||||
| Observe or compare a browser scenario | [CDP observation](browser-observation.md), [scenarios](browser-scenario-contract.md), [runtime evidence](web-runtime.md), [historical captures](web-network-captures.md) |
|
||||
| Serve recorded behavior as an agent environment | [Agent environments](agent-environments.md) |
|
||||
| Trace captured website source | [Source locations](web-source-location.md), [module traces](website-module-trace.md), [script export](website-script-export.md) |
|
||||
| Capture and compare a command | [Process capture](process-capture.md) |
|
||||
| Use CLI/MCP and retain evidence | [CLI](cli.md), [MCP contracts](mcp-contracts.md), [agent prompts](mcp-prompts.md), [obligation ledgers](reconstruction-obligation-ledgers.md) |
|
||||
| Task | Guides |
|
||||
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Identify a desktop installation | [Runtime candidates, evidence and follow-up files](desktop-applications.md) |
|
||||
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Linux kernel modules](kernel-modules.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
|
||||
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
|
||||
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [GameCube DOL](ghidra-dol.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [Kuna](kuna-provider.md), [JEB](jeb-analysis.md) |
|
||||
| Analyze JavaScript or Electron artifacts | [Static analysis](javascript-artifact-reconstruction.md), [tracing and comparisons](javascript-application-workflows.md), [application graph](javascript-application-graph.md), [source recovery](javascript-recovery.md) |
|
||||
| Compare static JavaScript with runtime observations | [Runtime attribution](javascript-runtime-observation.md), [reconciliation](javascript-runtime-reconciliation.md), [Electron observation](electron-observation.md), [Electron fuses](electron-fuses.md) |
|
||||
| Inspect assemblies, packages, or firmware | [Godot PCK](godot-pck.md), [.NET](managed-code-analysis.md), [Python packages](python-packaged-applications.md), [Android](android-analysis.md), [APK signatures](apk-signature.md), [Apktool resources](apktool-resource-analysis.md), [ADB acquisition](adb-device-analysis.md), [Apple](apple-application-analysis.md), [Harmony](harmony-analysis.md), [firmware](firmware-analysis.md), [WASM](wasm-artifacts.md), [EVM](evm-bytecode.md) |
|
||||
| Observe or compare a browser scenario | [CDP observation](browser-observation.md), [scenarios](browser-scenario-contract.md), [runtime evidence](web-runtime.md), [historical captures](web-network-captures.md) |
|
||||
| Serve recorded behavior as an agent environment | [Agent environments](agent-environments.md) |
|
||||
| Trace captured website source | [Source locations](web-source-location.md), [module traces](website-module-trace.md), [script export](website-script-export.md) |
|
||||
| Capture and compare a command | [Process capture](process-capture.md) |
|
||||
| Use CLI/MCP and retain evidence | [CLI](cli.md), [MCP contracts](mcp-contracts.md), [agent prompts](mcp-prompts.md), [obligation ledgers](reconstruction-obligation-ledgers.md) |
|
||||
|
||||
For development, use [testing](testing.md), [client verification](client-verification.md),
|
||||
[tool design](tool-design.md), [admission limits and recovery](design/limits-and-recovery.md),
|
||||
|
||||
+65
-19
@@ -88,11 +88,11 @@ Setup also retains valid environment overrides in REA's existing server entry,
|
||||
such as `REA_MCP_INPUT_SCHEMA_PROFILE`, `REA_MCP_OUTPUT_SCHEMA_PROFILE`, and
|
||||
`REA_MCP_MAX_RESPONSE_BYTES`.
|
||||
Detected provider settings replace only matching environment keys.
|
||||
Setup manages REA's launcher, selected provider settings, and supported timeout
|
||||
defaults. Client approval policies remain user choices, but the current Codex
|
||||
refresh drops those policies inside the REA entry; see the
|
||||
[Codex preservation limitation](client-configuration.md#codex-and-devin) before
|
||||
refreshing a customized registration.
|
||||
Setup manages REA's launcher, selected provider settings, and recommended timeout
|
||||
defaults. Codex approval policies, tool selections, and other caller-owned server
|
||||
settings are preserved. Known malformed policy values block setup before it
|
||||
writes the configuration or a backup; see
|
||||
[Codex settings preservation](client-configuration.md#codex-and-devin).
|
||||
Setup and doctor report a malformed REA environment map or invalid runtime
|
||||
setting before setup writes files. Repair the named setting in the client
|
||||
configuration; setup does not silently discard the rest of the map.
|
||||
@@ -616,9 +616,12 @@ hosted connector; see [its configuration](client-configuration.md#other-client-s
|
||||
| WorkBuddy | `workbuddy` |
|
||||
| ZCode | `zcode` |
|
||||
| DeepSeek Harness | `dsh` |
|
||||
| FreeBuff | `freebuff` |
|
||||
|
||||
`droid`, `dsh`, `kimi`, `qoder`, `trae`, `workbuddy`, and `zcode` require
|
||||
`rea-agents@6.5.0` or later. The 6.4.0 registry check above does not cover them.
|
||||
`freebuff` is not in a release yet - `6.7.0` is the latest - so it also needs a
|
||||
release containing it.
|
||||
|
||||
See [client configuration and troubleshooting](client-configuration.md) for
|
||||
configuration paths, profiles, trust policies, and schema-limit workarounds.
|
||||
@@ -681,6 +684,12 @@ search permissions (`0700`) on a directory you own before retrying.
|
||||
|
||||
On supported Linux distributions, approved setup verifies Hopper's official
|
||||
`.deb`, `.rpm`, or Arch package before invoking the native package manager.
|
||||
On apt systems, Hopper's runtime dependencies are installed with
|
||||
`--no-upgrade` in their own transaction, so setup no longer names an
|
||||
already-installed dependency as an upgrade target. apt can still upgrade a
|
||||
package that the Hopper package or the Python library repair requires at a
|
||||
newer version. Arch's `pacman -S --needed` still updates an outdated
|
||||
dependency.
|
||||
The official release feed selects the current public demo without a version
|
||||
pin. REA verifies the package's detached PGP signature against Hopper's stable
|
||||
primary fingerprint `7C2D73BAFAF5B9A710A69DA1A26DF815099B1BCD`, then checks
|
||||
@@ -745,6 +754,18 @@ may conflict with Hopper's versioned `zlib` dependency. Resolve the package
|
||||
conflict yourself, install Hopper's official package manually, or use another
|
||||
provider such as Ghidra; rerun `rea setup` after installing Hopper.
|
||||
|
||||
If setup cannot finish releasing its resources, a normally returned structured
|
||||
result reports `needs_human` and includes `cleanup.reason` with the identified
|
||||
paths in `cleanup.resources`. A thrown typed failure reports the same retained
|
||||
paths in `details.resources`, preserving the primary failure separately. Reasons
|
||||
that do not identify a resource remain explicit without guessing paths from text.
|
||||
For in-process callers retaining REA's setup host, a successful retry of its close
|
||||
updates the original failure's cleanup state and removes released resource labels.
|
||||
Custom `SetupHost` implementations must bind returned or thrown cleanup errors
|
||||
to their resource owners to provide the same live recovery. An ownerless error
|
||||
remains an unconfirmed snapshot: `runSetup` does not observe later direct calls
|
||||
to the caller's port or replace that port's methods.
|
||||
|
||||
The supported Linux demo forwards additional launches into its existing
|
||||
application, even across private displays. REA therefore reserves one Linux
|
||||
Hopper application per user across cooperating REA processes. A competing
|
||||
@@ -791,7 +812,10 @@ Hopper startup allows 120,000 ms for launch, initial analysis, and authenticated
|
||||
bridge readiness. For large targets, set `REA_HOPPER_STARTUP_TIMEOUT_MS` to a
|
||||
decimal integer from 1 to 2,147,483,647 milliseconds in the environment that
|
||||
starts REA. CLI and MCP use the same setting; invalid values fail configuration
|
||||
validation. An MCP client's own request timeout must also allow enough time.
|
||||
validation. In MCP, `update_analysis_settings` can set
|
||||
`hopper.startup_timeout_ms` for the next startup attempt without restarting REA;
|
||||
accepted work keeps its budget and retained cleanup must still complete. An
|
||||
MCP client's own request timeout must also allow enough time.
|
||||
`open_binary` validates and selects a target without waiting for native provider
|
||||
readiness. During Hopper startup, `binary_session.provider_operation_health`
|
||||
reports `busy` at stage `launch`; `analysis_activity` describes bridge requests
|
||||
@@ -985,9 +1009,13 @@ Target admission preserves recognized PE/NE/LE/LX signatures separately from
|
||||
reader layout support. A Windows header overlapping the first 64 DOS-header
|
||||
bytes remains an unsupported layout in this release; it is not reported as an
|
||||
invalid offset. Tiny PE files with short optional headers have additional
|
||||
unverified loader requirements. Unconfirmed nonzero DOS padding remains an
|
||||
unresolved Windows-header candidate, with independently validated DOS facts in
|
||||
the target error diagnostics; those facts do not prove a Windows header absent.
|
||||
unverified loader requirements. A nonzero Windows-header pointer without a
|
||||
recognized signature remains an unresolved candidate, with independently
|
||||
validated DOS facts in the target error diagnostics; those facts do not prove a
|
||||
Windows header absent. When a nonempty relocation table ends inside a complete
|
||||
DOS header, the remaining header bytes are DOS padding, so a nonzero dword
|
||||
there is not a Windows declaration. An unread signature beyond the current
|
||||
probe is requested before that padding rule applies.
|
||||
On Linux and macOS, `annotate_native_function` also edits a function name and/or
|
||||
entry comments atomically and returns refreshed analysis, and `set_address_name`
|
||||
and `set_addresses_names` name a function entry or any other mapped address
|
||||
@@ -1157,19 +1185,25 @@ can time out earlier even when Ghidra would complete within its startup deadline
|
||||
See [Ghidra first-query deadlines and recovery](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
for client options and the close/reopen recovery flow.
|
||||
|
||||
The 330-second default is configurable. Configuration is read when REA starts:
|
||||
changing an environment variable in another shell, or closing and reopening a
|
||||
binary in the same MCP server, does not change that server's startup allowance.
|
||||
The 330-second default can be changed on a running MCP server by setting
|
||||
`ghidra.startup_timeout_ms` through `update_analysis_settings`. The next accepted
|
||||
operation that starts a provider uses that value; an accepted startup keeps its
|
||||
original budget. Changing an environment variable in another shell, or closing
|
||||
and reopening a binary, does not change the launch configuration already read
|
||||
by that server.
|
||||
For a CLI retry with an example 30-minute allowance:
|
||||
|
||||
```sh
|
||||
REA_GHIDRA_STARTUP_TIMEOUT_MS=1800000 rea analyze /absolute/path/to/app.exe --provider ghidra --json
|
||||
```
|
||||
|
||||
For MCP, export useful Evidence before restarting, close the binary and resolve
|
||||
any cleanup failure, update the environment in the client's REA server launch
|
||||
configuration, then restart REA and reconnect before reopening the target. Allow
|
||||
startup plus the query in the client's own tool-call deadline. Every retry uses
|
||||
For MCP, update the runtime setting and resolve any retained cleanup before the
|
||||
next startup attempt. Follow the error's close/reopen guidance where needed;
|
||||
the settings update does not clear cleanup blockers. To change the launch
|
||||
environment instead, export useful Evidence, close the binary and resolve any
|
||||
cleanup failure, update the client's REA server launch configuration, then
|
||||
restart REA and reconnect. Allow startup plus the query in the client's own
|
||||
tool-call deadline; runtime updates do not change that deadline. Each new startup attempt uses
|
||||
a fresh ephemeral import; smaller result requests do not reduce the prerequisite
|
||||
auto-analysis. A larger time allowance does not raise the JVM heap limit or
|
||||
guarantee completion. Keep [heap and host CPU controls](#ghidra-heap-and-cpu-controls)
|
||||
@@ -1196,9 +1230,14 @@ fails with `provider_timeout` and that message; other Ghidra tools stay
|
||||
available. If the caller also cancels while the timeout settles, the session
|
||||
still closes and the message says so. Session reuse concerns an active MCP or
|
||||
library session; a standalone CLI command still closes its own session when it
|
||||
finishes. The limit is read when a Ghidra session
|
||||
starts, and Codex/Kimi registrations derived by `rea setup` add it to the tool
|
||||
deadline as a single-decompile estimate. A bulk call can need that limit for
|
||||
finishes. In MCP, `ghidra.decompile_timeout_seconds` can override the launch
|
||||
value for newly accepted operations on the existing Program; explicit `null`
|
||||
removes the deadline. A transient timeout remains uncached so the same function
|
||||
can be retried after an update. See the
|
||||
[settings design](design/limits-and-recovery.md#runtime-settings-through-mcp).
|
||||
Codex/Kimi registrations derived by `rea setup` add the selected launch value
|
||||
to the tool deadline as a single-decompile estimate; a runtime update does not
|
||||
change that registration. A bulk call can need that limit for
|
||||
every attempted function plus listing and file work; select the client deadline
|
||||
for the workload, split batches, use `decompile_all` limit/resume, or reduce
|
||||
`trace_native_values` `max_functions` to select fewer serial decompiles. Ghidra's own interactive default is 30 seconds. Unresolved computed calls
|
||||
@@ -1446,6 +1485,13 @@ setup runs through `bunx`, and pins it to the exact version that performed
|
||||
setup. Run current setup to refresh an older registration, then restart the
|
||||
client.
|
||||
|
||||
Package runners key their package cache by the requested spec, so the entry
|
||||
installed for the `@latest` invocation that ran setup cannot serve the pinned
|
||||
registration. Setup therefore materializes the pinned entry once, best-effort
|
||||
with a bounded timeout, before finishing. When that step cannot run, for
|
||||
example offline, the first client start performs the one-time install inside
|
||||
the client's MCP startup deadline and may need one more restart.
|
||||
|
||||
## Package runners and global installation
|
||||
|
||||
A package-runner invocation can use a REA version installed in the current project. To
|
||||
|
||||
@@ -197,6 +197,14 @@ registrations/removals and dispatch, Node timers and cancellation handles, async
|
||||
`node:child_process` creation and ownership, configuration sources and direct
|
||||
defaults, request construction and response consumers, parse/coercion/
|
||||
validation boundaries, and built-in resource acquisition/release.
|
||||
Reassignments connect retained right-hand reads to the binding or property
|
||||
write. Compound assignments also retain the previous-value input; logical
|
||||
assignments keep conditional inputs as candidates. These edges describe
|
||||
influence without evaluating arithmetic or establishing execution order or the
|
||||
resulting value. Deferred callback bodies do not become inputs to the enclosing
|
||||
assignment. Computed method keys belong to the enclosing callable; parameter
|
||||
defaults and method bodies belong to the method. Uncertain later property reads
|
||||
remain opt-in through `include_ambiguous_dynamic_edges`.
|
||||
Global timer, `fetch`, `WebSocket`, `JSON.parse`, and coercion calls receive
|
||||
these built-in effects only when the file has no visible possible write to that
|
||||
global, including a computed write through a global object. The check does not
|
||||
@@ -419,8 +427,11 @@ value. Earlier `break`/`continue` paths can leave a var initializer unexecuted.
|
||||
Legacy non-strict block-function copies are indexed on their outer variable
|
||||
owner, while strict/module and lexical-shadowing boundaries keep their values.
|
||||
A catch-shadowed var declaration keeps declaration ownership separate from its
|
||||
initializer's lexical assignment. Ordinary functions own an implicit arguments
|
||||
object; arrows retain lexical arguments lookup. Promise source identity uses
|
||||
initializer's lexical assignment, including object and array destructuring slots.
|
||||
Projected initializer facts retain their source and alias identity on the lexical
|
||||
recipient, so a later mutation through that alias prevents reporting the original
|
||||
object field as an unchanged constant. Ordinary functions own an implicit
|
||||
arguments object; arrows retain lexical arguments lookup. Promise source identity uses
|
||||
the same read-position selection and requires an unmodified intrinsic factory.
|
||||
|
||||
Rebound values are evaluated at their read position: saving an incoming parameter
|
||||
@@ -437,8 +448,10 @@ 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
|
||||
and shared children in spread and rest copies retain that uncertainty. Exposing
|
||||
the copy alone does not invalidate copied primitive slots or unrelated containing
|
||||
properties. Dynamic child writes such as `copy[key].value = 2` remain conservative
|
||||
about which original slot was selected. 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
|
||||
@@ -455,6 +468,11 @@ Receiver projections follow known data fields initialized from `this` or earlier
|
||||
self-referencing fields; static fields retain their declaring class identity.
|
||||
An alias cycle that repeatedly selects deeper children retains escape uncertainty
|
||||
at its recovered roots rather than claiming a fixed number of loop iterations.
|
||||
Equivalent member reads in a repeating loop share unknown ordering instead of
|
||||
creating a distinct capture for every branch history. Straight-line captures and
|
||||
once-only loop inputs retain their own selection sites. When unobserved suffixes
|
||||
are widened, their exact observed prefixes stay separate so unrelated siblings
|
||||
remain known.
|
||||
|
||||
Writes through an object getter's returned receiver retain that uncertainty
|
||||
when the object is an array element, nested inside mixed object/array
|
||||
@@ -499,8 +517,13 @@ escape uncertainty. External prototype changes and unsupported runtime protocols
|
||||
remain unknown rather than supplying exact post-invocation values.
|
||||
Identifier references and closure captures share Babel syntax-role facts plus
|
||||
explicit binding/write roles; noncomputed declaration keys and import/meta names
|
||||
are not lexical reads. Provenance-only expression-depth omissions enter the same typed source coverage
|
||||
as value-evaluation bounds and remain visible in retained application Evidence.
|
||||
are not lexical reads. TypeScript type positions, including `typeof` type queries
|
||||
and computed keys in erased signatures, do not evaluate JavaScript bindings or
|
||||
create runtime calls or captures. Decorators on declared class fields can still
|
||||
run when the class is defined, and a decorated declared or abstract field can
|
||||
evaluate its computed key. Provenance-only expression-depth omissions enter
|
||||
the same typed source coverage as value-evaluation bounds and remain visible in
|
||||
retained application Evidence.
|
||||
Immediate synchronous function results also share the loader reference owner.
|
||||
An expression arrow returning the retained CommonJS `require` can preserve that
|
||||
loader identity. Possible loader results with opaque alternatives or block
|
||||
|
||||
@@ -101,6 +101,18 @@ caller's request and first-occurrence priority, analyzing the file once.
|
||||
Omit the selection for the existing complete
|
||||
application workflow.
|
||||
|
||||
For a long selection, pass the paths as a JSON array with
|
||||
`--source-paths-json`, either inline or as a JSON file path. A file keeps the
|
||||
command below host command-line limits, such as the 8,191-character limit of
|
||||
the `cmd.exe` shim that `npx` uses on Windows. Its entries follow any
|
||||
`--source-path` values and stay artifact-relative; they are not resolved
|
||||
against the working directory:
|
||||
|
||||
```bash
|
||||
rea analyze-javascript-application /absolute/path/to/app.asar \
|
||||
--source-paths-json /absolute/path/to/paths.json --json
|
||||
```
|
||||
|
||||
The result and summary retain `source_selection.requested_paths` and
|
||||
`source_selection.unselected_files`. Selecting every relevant file leaves this
|
||||
count at zero and adds no unselected-source caveat. Every relevant file keeps its
|
||||
@@ -109,8 +121,8 @@ original inventory identity; unselected files report `text_status:
|
||||
coverage is partial while any file remains outside scope. Selection does not
|
||||
claim whole-application completeness or change integrity policy. Summary detail
|
||||
only reduces delivery; source selection reduces text acquisition and analysis.
|
||||
Explicit native provider or snapshot routing rejects `--source-path` rather
|
||||
than ignoring it.
|
||||
Explicit native provider or snapshot routing rejects `--source-path` and
|
||||
`--source-paths-json` rather than ignoring them.
|
||||
|
||||
For directory input, a permission-denied child file remains an unavailable
|
||||
inventory occurrence, and an unreadable child directory records an unknown
|
||||
@@ -128,17 +140,24 @@ returns an unavailable error with the retained inventory, rather than claiming
|
||||
the selected source does not exist. Observed exact file candidates keep their
|
||||
identity; unknown traversal cannot establish a unique application root.
|
||||
|
||||
ASAR header/index admission defaults to 16 MiB / 16777216 bytes. Set
|
||||
`REA_ASAR_MAX_HEADER_BYTES` in the environment that starts REA to a decimal
|
||||
byte count of at most 268435456 (256 MiB) to raise or lower it; restart REA
|
||||
after changing it. Invalid values are configuration errors, never a silent
|
||||
fallback. The archive index is read before any member can be selected, so
|
||||
ASAR header/index admission defaults to 16 MiB / 16777216 bytes. In MCP, use
|
||||
`update_analysis_settings` to set `asar.max_header_bytes` to an integer byte
|
||||
count from 1 to 268435456 (256 MiB), then retry the same full-archive request.
|
||||
The update applies to new operations without restarting REA; cached headers
|
||||
must also satisfy the new admission. For CLI or future MCP processes, set
|
||||
`REA_ASAR_MAX_HEADER_BYTES` in the launch environment. Changing that environment
|
||||
requires a new REA process. Invalid launch values are configuration errors,
|
||||
never a silent fallback. See the
|
||||
[settings design](design/limits-and-recovery.md#failure-and-retry) for recovery
|
||||
metadata, precedence, and reset behavior.
|
||||
|
||||
The archive index is read before any member can be selected, so
|
||||
`source_paths`, `--source-path`, `detail: "summary"`, `max_heap_mb`, and
|
||||
available host memory do not bypass or raise it. When the header exceeds the
|
||||
effective allowance, the failure names it, whether it came from the default or
|
||||
the setting, and the setting's limits. Alternatively, analyze an extracted
|
||||
effective allowance, the failure reports the value, its known source, and the
|
||||
setting's limits. Alternatively, analyze an extracted
|
||||
application directory, which does not admit an ASAR header. Repeating the unchanged
|
||||
request fails the same way.
|
||||
request without changing admission fails the same way.
|
||||
|
||||
## Read the analysis
|
||||
|
||||
@@ -183,6 +202,27 @@ For supplied passive browser or Electron observations, use
|
||||
[runtime reconciliation](javascript-runtime-reconciliation.md). It compares
|
||||
existing Evidence without rerunning static analysis or contacting CDP.
|
||||
|
||||
Each newly analyzed JavaScript file retains `analysis_coverage` in its graph
|
||||
observation. `syntax` distinguishes complete parsing, recovered syntax errors,
|
||||
failed parsing and unexamined source. `semantics` records the number of observed
|
||||
unknown findings and typed uncertainty, including returned-reference widening
|
||||
and unavailable type-only compiler options. `examination` reports static semantic
|
||||
resource limits and Electron wrapper expansion limits independently. A completed
|
||||
pass does not establish complete runtime semantics. Route examination and result
|
||||
capacity remain in the separate route inventory.
|
||||
|
||||
Electron applicability is `observed` when a static Electron module reference is
|
||||
retained, and otherwise `unknown`: a source without such a reference does not
|
||||
prove that the application is inapplicable. Sources excluded by `source_paths`
|
||||
retain `not-examined` with a reason and null semantic counts. Historical Evidence
|
||||
without this facet remains unmeasured. The existing `parse_status` remains its
|
||||
conservative overall summary; finer facts do not relabel earlier partial results.
|
||||
|
||||
Summary delivery counts these facts under `summary.coverage.static_sources`.
|
||||
Read exact per-file measurements with `inspect_analysis_view`, selecting
|
||||
`kind: "javascript-facts"` and `property_keys: ["analysis_coverage"]`, or inspect
|
||||
the module item. Both views use retained Evidence and preserve source provenance.
|
||||
|
||||
## ASAR integrity
|
||||
|
||||
ASAR inventory checks Electron integrity metadata for embedded archive entries
|
||||
@@ -204,6 +244,13 @@ those missing bytes. New inventories preserve an ASAR companion declaration as
|
||||
unavailable bytes belonged to a companion. See [MCP integrity handling](mcp-contracts.md#integrity-record-and-continue)
|
||||
for the tool-result contract.
|
||||
|
||||
JavaScript whose syntax cannot be parsed retains unavailable semantic coverage
|
||||
with `incomplete-module` unknowns for each semantic family and unknown omitted
|
||||
node and relation extents. The source module is retained when node capacity
|
||||
permits. A parser failure alone does not imply resource truncation or a named
|
||||
resource limit. Decoding failures and deliberately
|
||||
unselected sources retain the same explicit semantic coverage gap.
|
||||
|
||||
HTML whose bytes are not valid UTF-8 retains its file observation and an unknown
|
||||
`parse-html-script-references` scope with artifact-byte authority. Reference
|
||||
discovery was unavailable; zero retained script links does not establish that
|
||||
@@ -294,7 +341,10 @@ Selected bounded text is then parsed as inert data to recover:
|
||||
- local HTML script entrypoints;
|
||||
- Webpack and Rspack chunk registrations and module factories represented as
|
||||
AST literals, plus esbuild `__commonJS` module tables; recovered esbuild
|
||||
CommonJS exports use its factory's `exports`-then-`module` parameter order;
|
||||
CommonJS exports use its factory's `exports`-then-`module` parameter order.
|
||||
Export receivers and loader helpers retain those calling-convention roles only
|
||||
while the binding at the read still holds its original parameter value;
|
||||
replacing a parameter does not give the replacement object that role;
|
||||
- static imports, dynamic imports, CommonJS `require` calls, workers, and
|
||||
service workers (only `new Worker(new URL(path, import.meta.url))` resolves
|
||||
relative to the calling module; string worker and service-worker paths use
|
||||
@@ -377,13 +427,19 @@ Bundler adapters own callback roles: Webpack supplies module, exports, then
|
||||
loader; esbuild CommonJS supplies exports, then module. Export extraction uses
|
||||
those binding identities for assignments and declarations, so renaming either
|
||||
parameter does not change the recovered names. Global property-definition
|
||||
intrinsics require lexical and visible-write proof. Computed writes through a
|
||||
standalone loader's exposed module/cache table use the shared value owner; an
|
||||
unknown key invalidates the original-slot proof rather than implying a fresh
|
||||
chunk installation. A function stored on a standalone loader member does not
|
||||
write the table merely by being defined: the bootstrap owner excludes its
|
||||
deferred writes only when that member is unread and the loader namespace stays
|
||||
confined. Calls, member aliases, dynamic member reads, namespace escapes, or
|
||||
intrinsics require lexical and visible-write proof. Factory export declarations
|
||||
also require the loader's `d` member to have no prior or unordered visible
|
||||
replacement, including writes through lexical aliases. Unrelated loader members
|
||||
do not invalidate declarations. Ordering describes declarations within one factory
|
||||
activation; helper integrity on entry, effects of earlier invocations, and
|
||||
arbitrary call side effects remain unproven.
|
||||
Computed writes through a standalone loader's exposed module/cache table use
|
||||
the shared value owner; an unknown key invalidates the original-slot proof
|
||||
rather than implying a fresh chunk installation. A function stored on a
|
||||
standalone loader member does not write the table merely by being defined:
|
||||
the bootstrap owner excludes its deferred writes only when that member is
|
||||
unread and the loader namespace stays confined. Calls, member aliases, dynamic
|
||||
member reads, namespace escapes, or
|
||||
receiver-based access retain uncertainty about those writes. Export names
|
||||
describe recognized declarations, not a proof
|
||||
of final runtime property lifetime or arbitrary helper behavior.
|
||||
@@ -420,6 +476,8 @@ member-mutation owners must establish the receiver before static API facts becom
|
||||
roles or storage observations. Path `join`, `resolve`, and `fileURLToPath` use
|
||||
proven Node imports; source-relative URL conversion additionally requires an
|
||||
unmodified global or proven Node `url.URL` constructor and `import.meta.url`.
|
||||
Native constructor aliases retain that identity; their local spelling does not
|
||||
determine URL semantics, and replaced exports or local constructors remain unknown.
|
||||
Relative results of native path operations retain filesystem-expression context;
|
||||
their spelling does not turn them into module specifiers. Other calls preserve
|
||||
their expressions. A property named `preload` outside a proven BrowserWindow
|
||||
@@ -686,6 +744,10 @@ deadline per source, including startup and fact transfer. Select
|
||||
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
|
||||
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
|
||||
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
|
||||
For defaults across new MCP operations, use `update_analysis_settings` with
|
||||
`javascript.max_heap_mb` or `javascript.analysis_timeout_ms`. Explicit per-call
|
||||
arguments take precedence, and accepted work keeps its original settings. See
|
||||
the [settings design](design/limits-and-recovery.md#precedence-and-lifetime).
|
||||
V8 old-space limits do not impose a process RSS limit. When REA runs on Bun,
|
||||
the analyzer ignores the V8 heap flags; resource failures then report
|
||||
`worker_heap_limit_bytes` as null instead of a requested or V8-reported limit.
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
# Linux kernel modules
|
||||
|
||||
`inspect_kernel_module` / `inspect-kernel-module` reads metadata from one
|
||||
selected local ELF32/ELF64 relocatable object (`.ko`) without executing it.
|
||||
That metadata is the `.modinfo` key/value strings, the `__versions` symbol
|
||||
CRCs, the presence of `.gnu.linkonce.this_module` and `__ksymtab*` sections,
|
||||
the observed file sizes of `.init.text` and `.exit.text`, and an optional
|
||||
appended signature trailer. It does not require a Linux host or the `modinfo`
|
||||
program.
|
||||
|
||||
```bash
|
||||
rea inspect-kernel-module /absolute/path/to/module.ko --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
requires an absolute filesystem path and preserves that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_kernel_module",
|
||||
"arguments": { "path": "/artifacts/demo.ko" }
|
||||
}
|
||||
```
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte
|
||||
length. `applicability` is `applicable` only for `ET_REL`. Other ELF types are
|
||||
`not_applicable`: header facts are filled and `.modinfo`, `__versions`, and
|
||||
the signature trailer are not examined.
|
||||
|
||||
`.modinfo` entries stay in file order. Duplicate keys such as `alias` and
|
||||
`parm` are preserved. Each entry keeps its key, value, file range, and
|
||||
SHA-256. Values are the bytes after the first `=`. NUL padding between
|
||||
strings is skipped. Keys and values use a byte-preserving Latin1 projection:
|
||||
each source byte becomes the same-numbered Unicode code point. They are not
|
||||
decoded as UTF-8. `raw_sha256` hashes the original entry bytes, including its
|
||||
terminating NUL when present; `raw_hex` shows those bytes when they fit the
|
||||
inline limit.
|
||||
|
||||
`__versions` entries are `struct modversion_info`: a 64-byte record whose CRC
|
||||
is an `unsigned long` and whose name occupies the remaining bytes. ELF32
|
||||
stores a 32-bit CRC and a 60-byte name. ELF64 stores a 64-bit unsigned long
|
||||
and a 56-byte name. CRCs are zero-padded lowercase hex, 8 or 16 characters,
|
||||
not a JavaScript number. The layout is reported from the ELF class even when
|
||||
the section is absent. Names use the same byte-preserving Latin1 projection
|
||||
as `.modinfo` keys and values. Only this classic `__versions` layout is
|
||||
decoded. `versions.status: "absent"` means no `__versions` section was found
|
||||
when section names were complete; it does not establish the absence of version
|
||||
metadata in `__version_ext_names` and `__version_ext_crcs`, which Linux uses
|
||||
with `CONFIG_EXTENDED_MODVERSIONS` and this workflow does not decode.
|
||||
|
||||
`.gnu.linkonce.this_module` is reported as present, absent, or unknown.
|
||||
`layout` is always `unknown` because `struct module` changes with the kernel
|
||||
version and is not decoded. File-backed `__ksymtab*` sections are listed in
|
||||
section-header order by name and file range; their records are not decoded.
|
||||
Sections that are `SHT_NOBITS` or leave the file are counted in one limitation
|
||||
without their names. `.init.text` and `.exit.text` report the
|
||||
observed file-backed size. A compressed payload reports the stored size and a
|
||||
limitation that the decoded size is unknown.
|
||||
|
||||
The signature trailer is the 27-byte magic `~Module signature appended~\n`
|
||||
preceded by a 12-byte `module_signature` (`algo`, `hash`, `id_type`,
|
||||
`signer_len`, `key_id_len`, three pad bytes, and big-endian `sig_len`). When
|
||||
those parameter fields are zero and `id_type` is PKCS#7 (`2`), the preceding
|
||||
`sig_len` bytes are the PKCS#7 range and its SHA-256. The range is not parsed
|
||||
and no certificate, signer, or digest-coverage claim is made. An absent
|
||||
trailer is observed absence, not proof the module is unsigned.
|
||||
|
||||
When section names are incomplete, a missing named section is `unknown`
|
||||
rather than `absent`. An empty file-backed section is present and empty.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum). At most
|
||||
8192 `.modinfo` and `__versions` entries plus listed `__ksymtab*` sections are
|
||||
examined by default (65536 maximum); `coverage.examined_entries` counts all
|
||||
three. Exceeding that budget fails with no partial success. Keys longer
|
||||
than 256 bytes and values longer than 4096 bytes stay malformed per entry;
|
||||
the field that fits is still copied. A `__ksymtab*` section name longer than
|
||||
256 bytes keeps its range with `name: null` and `ksymtab_name_exceeds_limit`. Inline raw hex stops at 4096 bytes and
|
||||
the SHA-256 remains.
|
||||
|
||||
A `.modinfo` span with no trailing NUL is `unterminated_modinfo_entry` and
|
||||
earlier entries are kept. A string with no `=` is `modinfo_missing_separator`.
|
||||
An empty key is `modinfo_empty_key`. A `__versions` name with no NUL is
|
||||
`version_name_unterminated`. A `__versions` section whose size is not a
|
||||
multiple of 64 bytes is closed with `versions_size_not_multiple` and no
|
||||
entries. `SHT_NOBITS` or a declared range that leaves the file is
|
||||
`modinfo_section_not_file_backed` or `versions_section_not_file_backed`.
|
||||
`SHF_COMPRESSED` payloads are not inflated
|
||||
(`modinfo_section_compressed`, `versions_section_compressed`).
|
||||
|
||||
An appended magic with fewer than 12 preceding bytes is
|
||||
`signature_trailer_truncated`. A `sig_len` that does not leave at least one
|
||||
module byte is `signature_length_inconsistent`. Nonzero `algo`, `hash`,
|
||||
signer, key-id, or pad fields for PKCS#7 are `signature_parameters_nonzero`.
|
||||
A parameter block whose `id_type` is not PKCS#7 is
|
||||
`signature_id_type_not_pkcs7` and is unsupported rather than a validated
|
||||
signature.
|
||||
|
||||
gzip (`1f 8b`), xz (`fd 37 7a 58 5a 00`), and zstd (`28 b5 2f fd`) whole-file
|
||||
containers are `unsupported`. The result names `external_decompression` as the
|
||||
next probe and does not claim the payload is a kernel module. This is an external
|
||||
step, not a REA operation: neither this tool nor `extract_artifact` decodes these
|
||||
containers. Use an external gzip, xz, or zstd utility to decompress into a separate
|
||||
file, then call `inspect_kernel_module` on that file to inspect the `ET_REL` image.
|
||||
|
||||
Malformed ELF headers return no partial kernel-module metadata. This workflow
|
||||
does not execute the module or validate an appended signature.
|
||||
|
||||
## Format references
|
||||
|
||||
The record layout follows Linux v6.12's
|
||||
[`modversion_info`](https://github.com/torvalds/linux/blob/v6.12/include/linux/module.h)
|
||||
and [`MAX_PARAM_PREFIX_LEN`](https://github.com/torvalds/linux/blob/v6.12/include/linux/moduleparam.h).
|
||||
The [Linux kbuild module versioning guide](https://docs.kernel.org/kbuild/modules.html#module-versioning)
|
||||
describes the separate extended version sections.
|
||||
Trailer fields and acceptance rules follow
|
||||
[`module_signature`](https://github.com/torvalds/linux/blob/v6.12/include/linux/module_signature.h)
|
||||
and [`mod_check_sig`](https://github.com/torvalds/linux/blob/v6.12/kernel/module_signature.c).
|
||||
These references establish the decoded layout, not runtime verification.
|
||||
|
||||
## Real-module verification lane
|
||||
|
||||
Run from a built checkout with Docker available. This downloads a Debian kernel
|
||||
package into a disposable container, extracts a filesystem module, decompresses
|
||||
it when necessary, and inspects it with REA. It never installs or loads that
|
||||
kernel module. The temporary output is outside the repository; record the
|
||||
printed package version and module digest with results.
|
||||
|
||||
```bash
|
||||
module_lane=$(mktemp -d)
|
||||
docker run --rm -i -v "$module_lane:/out" debian:stable bash -se <<'CONTAINER'
|
||||
apt-get update -qq
|
||||
apt-get install -y --no-install-recommends xz-utils zstd ca-certificates
|
||||
cd /tmp
|
||||
arch=$(dpkg --print-architecture)
|
||||
package=$(apt-cache depends "linux-image-$arch" | awk '/Depends: linux-image-[0-9]/{print $2; exit}')
|
||||
test -n "$package"
|
||||
apt-get download "$package"
|
||||
dpkg-deb -f ./*.deb Package Version > /out/package.txt
|
||||
dpkg-deb -x ./*.deb /tmp/kernel
|
||||
module=$(find /tmp/kernel -type f -path '*/kernel/fs/*' \( -name '*.ko' -o -name '*.ko.xz' -o -name '*.ko.zst' -o -name '*.ko.gz' \) | sort | head -1)
|
||||
test -n "$module"
|
||||
case "$module" in
|
||||
*.xz) xz -dc "$module" > /out/module.ko ;;
|
||||
*.zst) zstd -dc "$module" > /out/module.ko ;;
|
||||
*.gz) gzip -dc "$module" > /out/module.ko ;;
|
||||
*) cp "$module" /out/module.ko ;;
|
||||
esac
|
||||
cat /out/package.txt
|
||||
sha256sum /out/module.ko
|
||||
CONTAINER
|
||||
node scripts/rea.mjs inspect-kernel-module "$module_lane/module.ko" --json > "$module_lane/rea.json"
|
||||
python3 - "$module_lane" <<'PY'
|
||||
import json, pathlib, sys
|
||||
root = pathlib.Path(sys.argv[1])
|
||||
report = json.loads((root / 'rea.json').read_text())['normalized_result']
|
||||
entries = report['modinfo']['entries']
|
||||
assert entries and all(entry['status'] == 'observed' for entry in entries)
|
||||
keys = [entry['key'] for entry in entries]
|
||||
for key in ('license', 'vermagic', 'name'):
|
||||
assert key in keys, key
|
||||
print('Observed .modinfo entries:', len(entries), 'distinct keys:', len(set(keys)))
|
||||
print('Artifact:', report['artifact'])
|
||||
PY
|
||||
```
|
||||
|
||||
`parm` and `parmtype` are retained separately by REA. Synthetic tests cover
|
||||
their generic key/value representation and all four ELF class/byte-order
|
||||
combinations. A successful real lane verifies only the selected module and
|
||||
printed fields; it does not validate certificates. This lane has not run in the
|
||||
sandbox used for implementation because access to the Docker socket was denied.
|
||||
@@ -70,7 +70,7 @@ The assembly label index is scanned once per export reader. Cancelling a request
|
||||
|
||||
Regex procedure and string search uses ECMAScript Unicode matching in a cancellable worker with a matching deadline and a worker old-generation heap. Literal matching remains the default. Cancellation or a matching deadline leaves the session available. The deadline is `REA_REGEX_MATCHING_DEADLINE_MS`, a positive decimal integer from 1 to 2147483647 ms. Unset uses 5000 ms. A larger value is refused because Node schedules a delay past that signed 32-bit bound as 1 ms. Invalid values are configuration errors and do not fall back to the default. The setting is read from the environment that starts REA, so a change needs a restart. A deadline failure names the effective milliseconds, whether they came from the default or the setting, the default, and the maximum. The worker old-generation heap does not raise it. The worker heap request is `REA_REGEX_WORKER_HEAP_REQUEST_MIB`, a decimal integer from 7 to 16384 MiB. Unset uses 128 MiB. A request below 7 MiB aborts the worker during startup, and a larger value is refused. Invalid values are configuration errors and do not fall back to 128. The setting is read from the environment that starts REA, so a change needs a restart. A heap failure names the effective request, whether it came from the default or the setting, the default, the floor, and the maximum. A positive Node.js `--max-old-space-size` on the process that starts REA, including `NODE_OPTIONS`, overrides that request and sets the effective heap. `--max-old-space-size-percentage` takes precedence over that flag in either order. REA does not turn the percentage into a MiB, so the effective heap stays unestablished instead of the worker heap request or the absolute flag. The reported `NODE_OPTIONS` value is the process initial environment when that block can be read. A later edit to the environment is not the value Node applied, and an unreadable initial value leaves the effective heap unestablished. The launch Node options are the initial command line on Linux when that buffer still has a program entry, not a later edit to `process.execArgv`. A preload can clear that array after V8 has applied the flags. Setting `process.title` or `--title` overwrites the command line, so a buffer without a program entry leaves the effective heap unestablished. `--env-file` or `--env-file-if-exists` can supply `NODE_OPTIONS` when the initial environment has none. That file is not part of the initial environment block, so the effective heap stays unestablished instead of the worker heap request. An initial `NODE_OPTIONS` is still used, because Node does not let the file replace it. A positive `--max-heap-size`, including the underscore form and launch `NODE_OPTIONS` on Node versions that allow it, sets the total heap rather than the old generation and can be lower than the worker heap request. The effective old generation stays unestablished while that value is in effect. A zero or empty value clears it. `--experimental-config-file` or `--experimental-default-config-file` can set `nodeOptions`, including a heap percentage, from a file that is not read back. The effective heap stays unestablished when either flag is present, including when an absolute `--max-old-space-size` is also on the command line or in the recovered `NODE_OPTIONS`. Node accepts the config path as `=` or the next argument.
|
||||
|
||||
Single-function subprocess output and each cached source facet share a 16 MiB buffered-text capacity. Cached spans are checked before allocation; larger text remains in the local export and the error identifies the file and range. `analyze_function` initially returns the complete dossier, which can still be large; later retained views do not remove that first transfer. Prefer the individual text tools for a focused question.
|
||||
Single-function subprocess output and each cached source facet share a 16 MiB buffered-text capacity. Cached spans are checked before allocation; larger text remains in the local export and the error identifies the file and range. `analyze_function` with `detail: "complete"` (the CLI default) returns the complete dossier inline, which can still be large; later retained views do not remove that first transfer. The MCP default retains the dossier and returns its summary, so page the facets you need through `inspect_analysis_view`, or prefer the individual text tools for a focused question.
|
||||
|
||||
## Strings
|
||||
|
||||
|
||||
@@ -365,8 +365,9 @@ admitted digest, inspection and comparison report retryable `artifact_changed`;
|
||||
any completed hash retains the observed digest and byte count. Retry against a
|
||||
stable source. This differs from corrupted retained Evidence, which remains an
|
||||
Evidence-integrity failure. Malformed selected PE input has the same input-format
|
||||
classification in inspection and comparison, and a failed right-side comparison
|
||||
retains the completed left observation.
|
||||
classification in inspection and comparison. Its issue identifies the selected
|
||||
filename and argument: `path` for inspection, or `leftPath` / `rightPath` for CLI
|
||||
comparison. A failed right-side comparison retains the completed left observation.
|
||||
|
||||
## Member comparison
|
||||
|
||||
@@ -543,7 +544,11 @@ establish which library the runtime loaded.
|
||||
|
||||
Signatures retain their decoded fields, but a Field or MethodDef row whose
|
||||
signature has the other member kind is malformed and cannot establish an
|
||||
unchanged signature. Runtime-provided methods are counted separately in
|
||||
unchanged signature. Comparison retains exact byte-based pairs for malformed
|
||||
signatures, including empty, truncated, or invalid headers, but reports them as
|
||||
unknown with a `signature-malformed` limitation when no change is observed.
|
||||
This applies to historical Evidence without signature-resolution attestation as
|
||||
well. Runtime-provided methods are counted separately in
|
||||
`native_implementations.runtime_provided`; they have no file-backed native body
|
||||
for this workflow to map and do not increase `native_body_unresolved`. Historical
|
||||
verification Evidence without this separate count leaves it unknown (`null`).
|
||||
@@ -552,7 +557,12 @@ An empty declared import name remains unchanged in verification Evidence and
|
||||
produces no native-name candidates. With a supplied PE native context and
|
||||
`no_mangle: false`, an unspecified charset includes the ANSI `A` candidate;
|
||||
`auto` includes the Windows Unicode `W` candidate. Other native formats do not
|
||||
inherit these Windows defaults. These suffixes are static inferred candidates;
|
||||
inherit these Windows defaults. Known ELF and Mach-O contexts use the declared
|
||||
entry point without A/W suffixes or Windows stdcall decoration, including when
|
||||
the metadata declares an explicit ANSI or Unicode marshalling charset. The
|
||||
original charset and calling convention remain unchanged. This follows the
|
||||
[.NET runtime's platform-specific entry-point lookup](https://github.com/dotnet/runtime/blob/v10.0.0/src/coreclr/vm/method.cpp#L3134-L3177).
|
||||
Windows name decorations are static inferred candidates;
|
||||
exact spelling still suppresses decoration and no runtime binding is proven.
|
||||
The mapping follows [Microsoft's charset guidance](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/charset).
|
||||
Partial input coverage records a residual question even when no unresolved
|
||||
|
||||
+82
-17
@@ -21,11 +21,24 @@ as an upstream tool's original report, and is `null` when there is none. The sam
|
||||
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
|
||||
directly to a compatible comparison tool: `analyze_function` Evidence can be passed
|
||||
directly to `compare_functions`, and `inspect_artifact` Evidence to
|
||||
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
|
||||
directly to a compatible comparison tool: complete `analyze_function` Evidence
|
||||
can be passed directly to `compare_functions`, and `inspect_artifact` Evidence
|
||||
to `compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
|
||||
retained session history or an explicit bundle for transfer.
|
||||
|
||||
`analyze_function` does not deliver its complete record by default. Without
|
||||
`detail`, it retains the complete dossier in the session and returns
|
||||
`inspect_analysis_view` summary Evidence whose
|
||||
`normalized_result.parent_evidence_id` names that dossier; see
|
||||
[retained analysis Evidence](#retained-application-evidence-inputs). Page the
|
||||
dossier with `inspect_analysis_view`. Tools that consume function dossiers
|
||||
reject the summary record. Give `compare_functions` the retained dossier as
|
||||
`{"kind": "retained-evidence", "evidence_id": "<parent_evidence_id>"}`; give
|
||||
`match_native_functions` the same reference inside `left_observations` or
|
||||
`right_observations`, since its `left` and `right` take `list_procedures`
|
||||
Evidence. Request `detail: "complete"` for `build_call_path`, which accepts
|
||||
only inline complete dossiers.
|
||||
|
||||
Saved records from the pre-6.6 identity projection that omitted
|
||||
`relationship_coverage: null` from its digest remain incompatible, even when
|
||||
the serialized field is present. REA recognizes that exact previous commitment
|
||||
@@ -55,11 +68,14 @@ byte correspondence or decode the map's original source paths.
|
||||
Artifact inventories declare `coverage.scope` (`root` or `container-entries`)
|
||||
and `coverage.status` (`complete` or `unknown`) independently of diagnostic
|
||||
wording. Comparison requires matching scopes, complete graph members and complete
|
||||
traversal coverage before concluding equality. A fully observed root without
|
||||
container children can be `unchanged`; its scope notice stays in `limitations`
|
||||
without creating a gap. Content and executable metadata changes still produce
|
||||
root deltas. Missing graph members yield `truncated`; unknown traversal coverage
|
||||
or unavailable occurrence hashes retain uncertainty. Integrity mismatches remain
|
||||
traversal coverage before concluding equality. Fully observed roots can be
|
||||
`unchanged` within root scope; their scope notice stays in `limitations` without
|
||||
creating a gap. Root-scoped equality establishes equality of the observed root
|
||||
bytes. Child-container presence and unexamined format details remain unresolved,
|
||||
including when the root format is `unknown`. Content and executable metadata
|
||||
changes still produce root deltas. Missing graph members yield `truncated`;
|
||||
unknown traversal coverage or unavailable occurrence hashes retain uncertainty.
|
||||
Integrity mismatches remain
|
||||
contradictions. Static artifact equality does not establish unchanged runtime
|
||||
behavior.
|
||||
Source-map relation deltas include the content identity of the mapped source,
|
||||
@@ -161,6 +177,11 @@ visible. When a requested goal is not reached but an expansion is unresolved,
|
||||
`goal_status` is `unknown`; `not_reached` means traversal exhausted without
|
||||
unresolved relationship reads. Cancellation remains a tool error.
|
||||
|
||||
`trace_feature` validates each reference's containing-procedure resolution using
|
||||
the same contract as navigation context. Explicit absence remains a successful
|
||||
negative observation; malformed provider replies return `unreadable_output`
|
||||
for `resolve_containing_procedure` before successful-result projection.
|
||||
|
||||
REA prepares complete MCP results within the pinned stdio client's 10 MiB
|
||||
receive-buffer budget, including both text and structured representations and
|
||||
room for the JSON-RPC envelope. Tool errors omit `structuredContent` from the
|
||||
@@ -346,11 +367,13 @@ after target content was read.
|
||||
## Retained application Evidence inputs
|
||||
|
||||
`analyze_javascript_application`, `inspect_binary_layout`, `inspect_artifact`,
|
||||
`inspect_wasm_artifact`, `inspect_macho`, and `decode_interface_builder`
|
||||
accept `detail`:
|
||||
`complete` (default) returns the complete analysis Evidence; `summary` records
|
||||
`inspect_wasm_artifact`, `inspect_macho`, `decode_interface_builder`, and
|
||||
`analyze_function` accept `detail`:
|
||||
`complete` returns the complete analysis Evidence; `summary` records
|
||||
that complete Evidence in the session and returns the derived
|
||||
`inspect_analysis_view` summary Evidence instead. Its
|
||||
`inspect_analysis_view` summary Evidence instead. `complete` is the default
|
||||
except for `analyze_function`, whose dossier can reach several megabytes of
|
||||
value flow and references, so it defaults to `summary`. 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
|
||||
@@ -909,6 +932,25 @@ of a later null value. Inspect the slot's `xrefs` and the writer's assembly or
|
||||
pseudocode, retaining uncertainty about execution order and runtime values.
|
||||
These operations inspect static evidence and do not execute the target.
|
||||
|
||||
## Editable analysis settings
|
||||
|
||||
Agents can call `update_analysis_settings` to raise a curated admission,
|
||||
timeout or worker heap default on a connected server, then retry the same
|
||||
request. Errors carry `details.limit` with the setting and bounds when the
|
||||
failing owner supports runtime recovery; `inspect_analysis_settings` is optional
|
||||
when those facts are supplied. Updates are atomic, apply to new work, survive
|
||||
target close/open, and vanish when REA exits. Explicit per-call arguments take
|
||||
precedence. Neither tool changes host deadlines or resolves retained cleanup.
|
||||
See [runtime settings and recovery](design/limits-and-recovery.md#runtime-settings-through-mcp)
|
||||
for the full setting list, reset/revision semantics and ASAR retry example.
|
||||
For implementation ownership, accepted-operation snapshots, provider wiring,
|
||||
and extension guidance, see the
|
||||
[maintainer design](design/limits-and-recovery.md#ownership-and-data-flow).
|
||||
|
||||
Ghidra and Hopper startup updates apply to the next startup attempt without
|
||||
restarting REA. Ghidra decompile timeout updates apply on the existing Program.
|
||||
An operation already accepted retains its original budgets.
|
||||
|
||||
## Ghidra first-query deadlines and recovery
|
||||
|
||||
A successful MCP initialize handshake establishes the REA connection.
|
||||
@@ -1010,11 +1052,13 @@ the current client, so it is not a fresh-start recovery. On the same connection:
|
||||
`provider_id: "ghidra"`, then retry the first query with an appropriate client
|
||||
deadline. The connection and selected provider do not need to change.
|
||||
|
||||
If REA's provider startup allowance also needs raising, preserve Evidence and
|
||||
close as above, then update `REA_GHIDRA_STARTUP_TIMEOUT_MS` in REA's launch
|
||||
environment and restart the server. Reconnect the MCP client before reopening
|
||||
the target. Configuration is read at process startup; close/reopen on the same
|
||||
connection cannot apply a changed environment. See the
|
||||
If REA's provider startup allowance also needs raising, set
|
||||
`ghidra.startup_timeout_ms` through `update_analysis_settings` before the next
|
||||
startup attempt. This needs no REA restart and does not change accepted work,
|
||||
clear cleanup blockers, or extend the client's deadline. Alternatively, change
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` in REA's launch environment and restart the
|
||||
server, preserving Evidence and closing as above. Close/reopen on the same
|
||||
connection cannot apply a changed launch environment. See the
|
||||
[CLI retry example](installation.md#ghidra).
|
||||
|
||||
This close/reopen flow was exercised on one real Linux stdio connection after a
|
||||
@@ -1209,6 +1253,22 @@ Kimi-K3 backend, not the WorkBuddy MCP client. Set the profile on REA's
|
||||
registration in the actual MCP host; the host's name alone does not identify
|
||||
the downstream model or its schema constraints.
|
||||
|
||||
The compact profile also protects strict Anthropic-compatible gateways from
|
||||
known schema-translation failures reported in [#3800](https://github.com/morluto/rea/issues/3800):
|
||||
primitive `enum` properties without a sibling `type`, and `oneOf`/`allOf`
|
||||
inside a property listed in `required`. Affected schemas use the same reduced
|
||||
first-level projection described below, so the gateway receives a plain object
|
||||
shape while REA continues to validate the complete canonical contract locally.
|
||||
This is a compatibility projection, not a claim that the gateway reproduces
|
||||
the full union semantics.
|
||||
|
||||
For array items expressed as an untyped `oneOf`/`anyOf`, the compact profile
|
||||
adds a type when every branch has the same type. Mixed-type item unions use the
|
||||
reduced projection; selecting one branch's type would exclude valid calls.
|
||||
This addresses the emitted shape reported through a Gemini-backed gateway in
|
||||
[#5201](https://github.com/morluto/rea/issues/5201). Gateway conversion and
|
||||
live provider acceptance have not been verified for this projection.
|
||||
|
||||
The compact profile renders the same tool set, output schemas, annotations,
|
||||
and canonical server-side validation. It changes only the advertised input
|
||||
JSON Schema:
|
||||
@@ -1240,6 +1300,11 @@ Boundary tests pin every advertised compact schema to the budget, keep them
|
||||
valid JSON Schema that still accepts every canonical example. 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.
|
||||
The SDK catalog test checks that full-profile schemas retain nested ADB extra,
|
||||
managed selection, and WASM timeout and detail restrictions. Path-contract tests
|
||||
check full-profile local-path rules. Compact MCP workflow tests verify canonical
|
||||
rejection of invalid inputs before provider work, independent of how much detail
|
||||
the selected advertisement retains.
|
||||
|
||||
### Output schemas
|
||||
|
||||
|
||||
@@ -34,8 +34,10 @@ index. Re-select compatible observations; authentication or contradictory produc
|
||||
facts retain their separate integrity failures.
|
||||
|
||||
For unmatched candidates, optionally supply `left_observations` and
|
||||
`right_observations`. `procedure_info` or existing `analyze_function` Evidence
|
||||
gives exact inclusive body ranges; `read_bytes` supplies memory bytes. Observations
|
||||
`right_observations`. `procedure_info` or existing `analyze_function` dossiers
|
||||
give exact inclusive body ranges; `read_bytes` supplies memory bytes. An MCP
|
||||
`analyze_function` summary reply is not a dossier: pass its
|
||||
`parent_evidence_id` as a `retained-evidence` reference instead. Observations
|
||||
must belong to the side's exact target/provider/profile and document context.
|
||||
Adjacent, consistent overlapping and partially returned reads compose by their
|
||||
observed extent; conflicting intervals remain gaps. A byte match requires every
|
||||
@@ -86,9 +88,9 @@ inventory Evidence and the owning inventory’s `source_index`, preserving same-
|
||||
One validation, lazy member index and bounded recent filter are retained per
|
||||
immutable parent; no live target state is cached.
|
||||
|
||||
When both functions already have unambiguous `analyze_function` dossiers, a matched
|
||||
relation includes `compare_functions_input` with directly usable retained
|
||||
references. Otherwise analyze just the selected canonical addresses in their
|
||||
When both functions already have unambiguous `analyze_function` dossiers in the
|
||||
observations, a matched relation includes `compare_functions_input` with
|
||||
directly usable retained references. Otherwise analyze just the selected canonical addresses in their
|
||||
respective targets, then compare those dossiers. Matching never claims behavioral
|
||||
equivalence. Optional informative CFG/call/string fingerprints from supplied
|
||||
dossiers connect unresolved candidate groups only. They require observed CFG,
|
||||
|
||||
+112
-30
@@ -265,7 +265,11 @@ Undecodable objects retain native display text with `decoding.available: false`
|
||||
and a reason, so one uncertain object does not block unrelated inspections.
|
||||
Function dossiers and `trace_feature` string matches retain this same string
|
||||
evidence, including decoding uncertainty; procedure matches keep their own
|
||||
named observation fields without invented string qualifications. Native call edges retain
|
||||
named observation fields without invented string qualifications. Tracing keeps
|
||||
same-address search alternatives, including different string encodings, in their
|
||||
original search order and shares one reference read per target address within
|
||||
the call. Reference rows are emitted once per target address, preserving any
|
||||
duplicates in the provider's observation. Native call edges retain
|
||||
Hopper's partial `CallReference` classification and exact endpoints; detailed
|
||||
reference flags remain unavailable rather than being invented. Caller and callee
|
||||
procedure inventories come from independent Hopper APIs; REA retains observed
|
||||
@@ -280,17 +284,22 @@ stops matching while leaving the Hopper API available. The deadline is
|
||||
2147483647 ms. Unset uses 5000 ms. A larger value is refused because Node
|
||||
schedules a delay past that signed 32-bit bound as 1 ms. Invalid values are
|
||||
configuration errors and do not fall back to the default. The setting is read
|
||||
from the environment that starts REA, so a change needs a restart. A deadline
|
||||
failure names the effective milliseconds, whether they came from the default
|
||||
or the setting, the default, and the maximum. The worker old-generation heap
|
||||
does not raise it. Kuna regex search uses the same deadline. The worker
|
||||
from the environment that starts REA; changing that environment needs a restart.
|
||||
In MCP, `regex.matching_deadline_ms` overrides the deadline for newly accepted
|
||||
searches without restarting REA. A deadline failure names the effective
|
||||
milliseconds, known source, default, and maximum. The worker old-generation heap
|
||||
does not raise it. IDA and Kuna use these same regex controls; Ghidra's Java
|
||||
matcher does not. The worker
|
||||
heap request is `REA_REGEX_WORKER_HEAP_REQUEST_MIB`, a decimal integer from
|
||||
7 to 16384 MiB. Unset uses 128 MiB. A request below 7 MiB aborts the worker
|
||||
during startup, and a larger value is refused. Invalid values are
|
||||
configuration errors and do not fall back to 128. The setting is read from
|
||||
the environment that starts REA, so a change needs a restart. A heap failure
|
||||
names the effective request, whether it came from the default or the setting,
|
||||
the default, the floor, and the maximum. A positive Node.js
|
||||
the environment that starts REA, while MCP `regex.worker_heap_request_mib`
|
||||
can override it for workers belonging to newly accepted searches. Use
|
||||
`update_analysis_settings` for either runtime control; accepted work keeps its
|
||||
budget. See the [settings design](design/limits-and-recovery.md).
|
||||
A heap failure names the effective request, known source, default, floor, and
|
||||
maximum. A positive Node.js
|
||||
`--max-old-space-size` on the process that starts
|
||||
REA, including `NODE_OPTIONS`, overrides that request and sets the effective
|
||||
heap. `--max-old-space-size-percentage` takes precedence over that flag in
|
||||
@@ -422,8 +431,12 @@ Native target admission checks Mach-O slice headers before assigning FAT
|
||||
identity. A shared `CAFEBABE` prefix whose declarations do not identify Mach-O
|
||||
images receives the generic unsupported-format refusal, including JVM class
|
||||
files larger than the bounded admission probe. This does not identify a partial
|
||||
prefix as a validated JVM class. Malformed recognized FAT declarations retain
|
||||
their format-specific reasons.
|
||||
prefix as a validated JVM class. For files sharing `CAFEBABE`, target admission
|
||||
checks complete JVM framing within the same 16 MiB class identity bound as the
|
||||
Mach-O image reader. A complete class remains unsupported even if its constant
|
||||
pool resembles a known FAT CPU declaration. Above that bound, an ambiguous
|
||||
malformed FAT interpretation remains unresolved. Malformed recognized FAT
|
||||
declarations retain their format-specific reasons.
|
||||
|
||||
`inspect_artifact` and `extract_artifact` retain universal Mach-O slices under
|
||||
their exact `lipo` names, including 32-bit ARM implementations such as `armv7`,
|
||||
@@ -449,17 +462,37 @@ markup, including UTF-8 and BOM-marked UTF-16 sources. Unidentified text and
|
||||
OpenStep plists, including a data-only value such as `<deadbeef>`, report
|
||||
`unknown` even when plutil decodes their values through an XML conversion.
|
||||
|
||||
Binary plist inspection reads the original bytes through an owned file descriptor,
|
||||
so conversion cannot erase control characters, fractional dates, negative zero,
|
||||
or the high word of a 128-bit integer. It accepts at most 64 MiB of input and
|
||||
reserves an estimated 64 MiB decode budget before parsing; this estimate is not
|
||||
a hard process-memory bound. A refused input reports non-retryable
|
||||
`resource_constraint` with `reported_limits.maximum_input_bytes`,
|
||||
`maximum_decoded_bytes` or, for nesting deeper than 128 levels,
|
||||
`maximum_nesting_depth`. These are fixed allowances: worker limits and host
|
||||
memory do not raise them, and the unchanged request fails the same way.
|
||||
Binary-source provenance records the `file` classification without claiming a
|
||||
`plutil` conversion.
|
||||
Plist inspection reads bounded original bytes through an owned file descriptor.
|
||||
Binary and UTF-8/BOM-marked UTF-16 XML sources decode directly, retaining scalar
|
||||
facts without a mandatory `plutil` conversion. UTF-8 JSON containers also decode
|
||||
directly when their number facts need no further classification; explicitly
|
||||
identified JSON sources can have scalar roots. Unidentified primitive text keeps
|
||||
its existing conversion route, so OpenStep `123` remains a string. OpenStep,
|
||||
unsupported XML encodings such as UTF-32 and declared legacy encodings, and JSON
|
||||
numbers requiring XML type facts retain the `plutil` route. Invalid UTF-8 and
|
||||
encoding-declaration mismatches remain explicit failures. Direct-source
|
||||
provenance records `file` without claiming conversion; conversion limitations
|
||||
and invocations appear only when conversion actually ran.
|
||||
XML sources must also pass native format validation, with native refusals retaining
|
||||
their diagnostics and successful validation recorded in provenance. Original
|
||||
unknown scalar text, reasons and limitations survive successful validation;
|
||||
output-budget omissions remain omissions.
|
||||
|
||||
Source input is limited to 64 MiB. Binary and direct XML decoding reserve an
|
||||
estimated 64 MiB decode budget before parsing; this is not a hard process-memory
|
||||
bound. JSON decode memory has not been measured and has no equivalent decode
|
||||
estimate. A refused input reports non-retryable `resource_constraint` with
|
||||
`reported_limits.maximum_input_bytes` or `maximum_decoded_bytes` as applicable.
|
||||
Ordinary direct-source decoding has a ceiling of 998 source nesting levels,
|
||||
derived from the existing 1000-level JSON result capacity by reserving one level
|
||||
for typed scalar fields and one for the result's `value` field. Deeper input reports
|
||||
`resource_constraint` with `reported_limits.maximum_nesting_depth: 998` and names
|
||||
the fixed nesting allowance. XML admission also requires native validation, which
|
||||
can refuse input below this decoding ceiling. Compatibility conversions can
|
||||
likewise encounter an earlier native utility refusal; both retain native
|
||||
diagnostics. Archive and Interface Builder decoding retain their separate
|
||||
128-level allowance. Worker limits and host memory do not raise these fixed
|
||||
allowances, and the unchanged request fails the same way.
|
||||
|
||||
A plist explicitly selected through the path input or as the active plist target
|
||||
reports an unreadable or malformed selection as `invalid_request`. A missing or
|
||||
@@ -467,6 +500,12 @@ unreadable default plist of another target reports `capability_unavailable`.
|
||||
Permission failures remain `access_denied`; output and cleanup failures retain
|
||||
their own error categories.
|
||||
|
||||
Selected plist paths preserve filesystem resolution, including `..` after a
|
||||
directory symlink and trailing directory separators. Resource-only bundle
|
||||
sessions resolve relative selections from the bundle root with the same path
|
||||
semantics as executable sessions; the reported source path retains those
|
||||
selected segments.
|
||||
|
||||
A conversion refusal includes plutil's diagnostic from either output stream.
|
||||
`details.captured_output` retains bounded stdout/stderr excerpts, observed byte
|
||||
totals and exit status. `truncated: true` means those excerpts are incomplete.
|
||||
@@ -477,15 +516,25 @@ to the linked Mach-O. This classification requires both the recognized native
|
||||
refusal and an independently parsed dSYM Mach header; other tool failures keep
|
||||
their failure outcome.
|
||||
|
||||
Observed `dyld_info` diagnostics include `unknown mh.filetype 4` and
|
||||
`unknown filetype 4` for `MH_CORE`, and the corresponding `3` spellings for
|
||||
`MH_FVMLIB`. These refusals report `unsupported_target` when the independently
|
||||
parsed Mach header confirms the reported file type. The error retains the exact
|
||||
native diagnostic and recommends a linked Mach-O executable or relocatable
|
||||
object. This classifies the selected target's refusal; it does not establish
|
||||
support for core-dump analysis, historical FVMLIB layouts, or unobserved native
|
||||
diagnostic spellings. Unknown or contradictory header values and signalled
|
||||
commands remain failures.
|
||||
|
||||
`inspect_macho.selected_architecture` identifies the exact selected lipo slice
|
||||
and its `container_file_offset` in the input file. A thin Mach-O has a known
|
||||
offset of zero; an unknown universal-slice offset stays null. The Evidence
|
||||
subject format describes the input container: `mach-o-universal` for FAT files,
|
||||
including those with one slice. The normalized result describes the selected
|
||||
Mach-O image. Architecture
|
||||
`file_offset` values are container-relative. Entrypoint, segment and section
|
||||
`file_offset` values retain their source meaning and are relative to the
|
||||
selected Mach-O slice. Raw load-command fields retain their original values.
|
||||
including those with one slice. The normalized result also reports the container
|
||||
in `format`; `selected_architecture` identifies the selected Mach-O image.
|
||||
Architecture `file_offset` values are container-relative. Entrypoint, segment
|
||||
and section `file_offset` values retain their source meaning and are relative
|
||||
to the selected Mach-O slice. Raw load-command fields retain their original values.
|
||||
A field otool prints more than once, such as each `LC_BUILD_VERSION` tool, is
|
||||
keyed `name #n` in print order. Each `LC_LINKER_OPTION` string is keyed
|
||||
`string #n` and checked against the declared `count`. Evidence locations map the LC_MAIN entrypoint and nonempty file-backed segment
|
||||
@@ -522,6 +571,10 @@ complete observation.
|
||||
its outcome. Paths outside the analyzed root, including shared-cache system
|
||||
libraries, stay undetermined. See
|
||||
[Apple application analysis](apple-application-analysis.md#dylib-load-resolution).
|
||||
ARM64 slice labels distinguish `arm64v8`, `arm64e`, and `arm64e.x1` while
|
||||
retaining raw CPU subtype and capability bits. The `arm64` and `arm64e`
|
||||
request filters select their respective families; a shared family label
|
||||
does not establish dependency compatibility across different subtypes.
|
||||
Executable-root discovery preserves traversal uncertainty, including
|
||||
undecodable filenames and skipped symlinks, as partial coverage. Known
|
||||
executable roots remain available; unexamined names and symlink targets
|
||||
@@ -537,7 +590,12 @@ complete observation.
|
||||
when either source is incomplete. Resource wrappers retain their serialized
|
||||
class and authored runtime class, including AppKit `NSCustomResource` names.
|
||||
Invalid producer JSON and subprocess failures retain captured output with
|
||||
their typed failure reason. Catalog-reader cleanup retains the primary
|
||||
their typed failure reason and selected catalog path. A complete normal
|
||||
assetutil exit declaring that exact catalog path `is not a valid AssetCatalog`,
|
||||
or its observed `Undefined error: 0` / `invalid file` rejection, reports an
|
||||
invalid-artifact failure. Other tool failures retain their own
|
||||
classification; unrecognized diagnostics do not establish malformed bytes.
|
||||
Catalog-reader cleanup retains the primary
|
||||
integrity, utility or cancellation failure and its cleanup resources; the
|
||||
provider retains catalog, Interface Builder and keyed-archive readers until
|
||||
cleanup is confirmed. A catalog failure also retains cleanup failures from
|
||||
@@ -643,6 +701,14 @@ complete observation.
|
||||
registries use paired keys and parents; objects paired with `NSRoot` are
|
||||
top-level, while nested objects keep their recorded parent. Conflicting or
|
||||
unreadable registry pairs remain incomplete hierarchy evidence.
|
||||
`NSString` objects with the [recognized `NS.bytes` representation](https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/Foundation/NSString.swift#L201-L215) are decoded
|
||||
as UTF-8 without substituting malformed bytes. A failed conversion retains
|
||||
the source string object ID and `nibValues.NS.bytes` base64 data; dependent
|
||||
authored classes, titles and selectors remain unknown, and object, class,
|
||||
connection and archive-decode coverage is partial. Other decoded objects and
|
||||
connections remain available. Genuine U+FFFD and leading U+FEFF characters in
|
||||
valid UTF-8 retain their identity; opaque data fields are not interpreted as
|
||||
strings. This does not establish support for other NSString representations.
|
||||
Embedded `UINib` archive data remains retained and undecoded; affected
|
||||
object, connection, class and hierarchy coverage is partial. Recognized
|
||||
`UIStoryboardShowSegueTemplate` source records similarly qualify connection
|
||||
@@ -683,9 +749,10 @@ complete observation.
|
||||
examined type records and fully decoded declarations. Class vtable recovery
|
||||
reads the same descriptors, so an unreadable type record also keeps
|
||||
`swift_class_vtable_descriptors` partial.
|
||||
Nominal declarations, conformance type references and class vtables share one
|
||||
snapshot-scoped name/context reader. Conformance `type_name` and dispatch
|
||||
`owner` retain enclosing named types; conformances carry the known module.
|
||||
Nominal declarations, conformance type and protocol references, and class
|
||||
vtables share one snapshot-scoped name/context reader. Conformance `type_name`,
|
||||
`protocol_name`, and dispatch `owner` retain enclosing named types;
|
||||
conformances carry the known module.
|
||||
Unresolved parents preserve the leaf name and a partial identity reason,
|
||||
while independently readable witness implementations remain available.
|
||||
Protocol instance properties use the same property-list reader as classes.
|
||||
@@ -700,6 +767,21 @@ complete observation.
|
||||
arm64e formats;
|
||||
- legacy `LC_DYLD_INFO` rebase and bind opcodes.
|
||||
|
||||
[dyld symbol names are byte strings](https://github.com/apple-oss-distributions/dyld/blob/dyld-1330/mach_o/BindOpcodes.cpp#L203-L208),
|
||||
compared with [`strcmp`](https://github.com/apple-oss-distributions/dyld/blob/dyld-1330/mach_o/BindOpcodes.cpp#L42-L56).
|
||||
Dependent library install names likewise originate as
|
||||
[load-command byte strings](https://github.com/apple-oss-distributions/dyld/blob/dyld-1330/mach_o/Header.cpp#L1278-L1298)
|
||||
and are [compared byte for byte](https://github.com/apple-oss-distributions/dyld/blob/dyld-1330/dyld/DyldAPIs.cpp#L607-L618).
|
||||
When a symbol or applicable library name has no lossless UTF-8 text
|
||||
projection, the affected binding remains unresolved and pointer-fixup
|
||||
coverage is partial; later readable bindings and other metadata survive.
|
||||
The internal fixup reader retains the exact name bytes and parsed binding
|
||||
fields, while public Objective-C and Swift results retain the unresolved
|
||||
reason instead of publishing a guessed symbol, library or class name. A literal
|
||||
U+FFFD or leading BOM in valid UTF-8 remains part of the name. Legacy
|
||||
weak-bind lookup has no library-name scope, so an opaque dependency name
|
||||
does not prevent decoding an otherwise readable weak binding.
|
||||
|
||||
A Swift conformance whose type or protocol reference is an external bind
|
||||
keeps its name as `null` and carries the raw dyld identity in
|
||||
`type_binding` or `protocol_binding`; that record and its facet coverage are
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# Node.js single executable applications
|
||||
|
||||
REA inventories injected Node.js SEA blobs through `inspect-artifact` /
|
||||
`inspect_artifact` and materializes their contents through `extract-artifact` /
|
||||
`extract_artifact`. It never runs the application or deserializes V8 snapshots
|
||||
or code cache.
|
||||
|
||||
```sh
|
||||
rea inspect-artifact ./application --json
|
||||
rea inspect-artifact ./application --detail summary --evidence_output evidence.json --json
|
||||
rea extract-artifact ./application --json
|
||||
```
|
||||
|
||||
For MCP, open the carrier with `open_binary`, then call `inspect_artifact`.
|
||||
Summary delivery retains the complete Evidence: use `parent_evidence_id` with
|
||||
`inspect_analysis_view` to request particular inventory paths and fields.
|
||||
Extraction returns a fresh `output_root`; analyze that extracted directory with
|
||||
`analyze_javascript_application`. Snapshot-only applications have no recovered
|
||||
main script and receive no JavaScript next probe. Neither does a main script
|
||||
whose logical path lacks a JavaScript source suffix, such as `main`, because the
|
||||
analyzer selects extracted files by suffix.
|
||||
|
||||
## Recognition and evidence
|
||||
|
||||
The container format is `node-sea`. REA locates Mach-O sections named
|
||||
`__NODE_SEA_BLOB` in `NODE_SEA` or `__NODE_SEA`, ELF notes owned by
|
||||
`NODE_SEA_BLOB`, and PE RCDATA resources named `NODE_SEA_BLOB`. PE resource
|
||||
locations come from the shared PE resource parser. ELF program-header
|
||||
`PT_NOTE` segments are authoritative, as at runtime; `SHT_NOTE` sections are
|
||||
read only when no program-header table is readable, because injectors can
|
||||
leave stale section entries. A PE without a `NODE_SEA_BLOB` resource name is
|
||||
left to native classification. Universal Mach-O carriers
|
||||
with different slice blobs are rejected as ambiguous; identical blobs are
|
||||
inventoried once. Native carrier bytes keep their content hash and native
|
||||
classification while the root occurrence represents the SEA container.
|
||||
|
||||
Root `format_metadata` preserves raw flags, decoded flags, code path, blob
|
||||
location, exec arguments and fuse observations. Main and asset children retain
|
||||
their role and exact declared name in `source_path`. Safe, noncolliding names
|
||||
become logical paths after the shared NFC path normalization. Names that are
|
||||
unsafe as relative paths, have an exact or file-prefix collision with another
|
||||
entry, or occupy the reserved `__node_sea__`
|
||||
namespace receive deterministic logical paths: `__node_sea__/main.cjs` for the
|
||||
main CommonJS source and `__node_sea__/assets/<ordinal>` for assets, using their
|
||||
zero-based order in the blob. The original declared name remains
|
||||
in `source_path`, including an empty asset key. Snapshots and code caches use
|
||||
`__node_sea__/snapshot` and `__node_sea__/code-cache`. Extraction materializes
|
||||
the logical paths through the shared path-containment and collision rules and
|
||||
never overwrites existing files.
|
||||
|
||||
The fuse scan independently records `set`, `unset`, `absent`, or `conflicting`.
|
||||
An unset fuse with a present blob is reported as a limitation. These are static
|
||||
sentinel observations, not proof of runtime activation: sentinel-like text in
|
||||
script or asset bytes also participates in the scan.
|
||||
|
||||
## Supported layout and limits
|
||||
|
||||
The decoder follows the 64-bit little-endian layout in Node
|
||||
[v24.10.0 node_sea.cc](https://github.com/nodejs/node/blob/v24.10.0/src/node_sea.cc)
|
||||
and [node_sea.h](https://github.com/nodejs/node/blob/v24.10.0/src/node_sea.h),
|
||||
including the exec-argument extension byte. Older layouts without that byte,
|
||||
32-bit length fields, big-endian blobs and future flags are not supported.
|
||||
Carrier byte order is independent of blob byte order.
|
||||
|
||||
Malformed magic, truncation, unknown flags/extensions, invalid UTF-8, duplicate
|
||||
raw asset keys and conflicting blob declarations fail closed with named reasons.
|
||||
Zero padding after a complete blob is allowed. The blob read ceiling is 256 MiB;
|
||||
PE carriers also use the shared 512 MiB input, 65,536 directory-entry and 8 MiB
|
||||
resource-metadata ceilings. The decoder admits at most 100,000 assets whose
|
||||
names total at most 8 MiB, and 4,096 exec arguments totaling at most 1 MiB of
|
||||
text. These are fixed resource bounds, not Node format limits, checked before
|
||||
decoding names or creating records; a hit fails as a limit with no runtime
|
||||
override. Asset and argument decoding, padding scans, and inventory construction
|
||||
yield in bounded batches and honor caller cancellation. Asset count and name
|
||||
budgets bound retained metadata independently of stored member body sizes. The PE
|
||||
name probe reads headers from the first 64 KiB of the carrier; a PE whose
|
||||
headers extend beyond that is left to native classification. Snapshot and
|
||||
code-cache bytes remain opaque.
|
||||
|
||||
## Verification
|
||||
|
||||
Synthetic fixtures cover Mach-O, ELF and PE inventory/extraction, malformed
|
||||
blobs, collisions and fuse contradictions. CLI and MCP tests exercise the same
|
||||
artifact provider and advertised schemas. A CLI regression also generates a blob
|
||||
with the pinned local Node version, an absolute main path and an empty asset
|
||||
key, then inventories it inside a synthetic ELF carrier. This verifies the real
|
||||
blob producer, not a real injected executable.
|
||||
|
||||
The optional real ELF lane uses Docker's official Node v24.10.0 image and pinned
|
||||
postject to build a fixture, then verifies inventory and extracted script/asset
|
||||
bytes without running the injected application:
|
||||
|
||||
```sh
|
||||
npm run verify:node-sea
|
||||
```
|
||||
|
||||
This requires Docker and network access to fetch the producer image and
|
||||
postject. It creates and removes its own temporary fixture directory. A real
|
||||
macOS Mach-O or Windows PE run is separate coverage; synthetic carriers do not
|
||||
establish real-platform verification. No performance improvement is claimed;
|
||||
whole-task tokens, CPU, memory, and cold/warm timings have not been measured.
|
||||
@@ -76,6 +76,10 @@ associations are derivations. Capture Evidence has historical-reference authorit
|
||||
nanoseconds). Empty captures, malformed timestamps and instants outside years
|
||||
0000–9999 remain `null`; host-local timestamps without a zone are not inferred.
|
||||
|
||||
`snapshot_length` is the file-header packet size limit reported by `capinfos`.
|
||||
Its separate inferred truncation lengths do not replace that limit; an unset
|
||||
file-header limit remains `null`.
|
||||
|
||||
Addresses count once per packet, including loopback and nested IP occurrences.
|
||||
DNS addresses are associated only with one question in the same response packet;
|
||||
additional records may be included, so this does not prove final resolution.
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# PE import and delay-load tables
|
||||
|
||||
`inspect_pe_imports` / `inspect-pe-imports` answers whether one selected local
|
||||
PE32/PE32+ image declares an `IMAGE_DIRECTORY_ENTRY_IMPORT` table, which DLLs
|
||||
and functions that table names, which delay-load descriptors are present, and
|
||||
the pefile-compatible import hash of the standard import table. It reads the
|
||||
file without executing it and does not require a Windows SDK or disassembler.
|
||||
|
||||
```bash
|
||||
rea inspect-pe-imports /absolute/path/to/application.exe --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
and the advertised input schema require an absolute filesystem path and
|
||||
preserve that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_pe_imports",
|
||||
"arguments": { "path": "/artifacts/application.exe" }
|
||||
}
|
||||
```
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte length.
|
||||
`import_directory` and `delay_import_directory` report the data directory RVA
|
||||
and size, or `null` when a directory is absent or zero. Their `locations` are
|
||||
the file spans actually read for the descriptor array and its terminator. When
|
||||
consecutive descriptors map to discontiguous file bytes (for example across a
|
||||
section boundary), each span is reported separately, and each becomes its own
|
||||
Evidence file-offset range.
|
||||
If the first descriptor cannot be examined, the directory declaration remains
|
||||
present with no consumed `locations`, and coverage is partial. Descriptors,
|
||||
thunks and NUL-terminated names stay within PE's 32-bit RVA space, including
|
||||
PE32+ images; earlier valid rows survive an overflowing descriptor walk.
|
||||
|
||||
`machine` retains the original unsigned COFF value. `architecture` decodes
|
||||
known machines, including ReadyToRun OS overrides when a CLI directory is
|
||||
declared; that declaration does not establish valid CLR metadata or runtime
|
||||
compatibility. Unrecognized machines retain `pe-machine-<decimal>` while their
|
||||
import tables remain inspectable. A recognized machine whose width contradicts
|
||||
the optional header is malformed.
|
||||
|
||||
Each `imports[]` item reports the DLL name, descriptor RVAs, and named or
|
||||
ordinal functions with ILT/IAT RVAs. `delay_imports[]` reports RVA-based
|
||||
delay-load descriptors separately. `imphash` is pefile's `get_imphash()` over
|
||||
the standard import table only; delay-load rows do not participate. Ordinal
|
||||
imports use pefile's ordinal name tables and otherwise its `ord<decimal>`
|
||||
fallback.
|
||||
|
||||
`imphash.md5` is `null` with a `reason` whenever the value would not be
|
||||
pefile's hash of this image: the standard import table is partial, or pefile
|
||||
would read a different row sequence (names it treats as invalid or truncates,
|
||||
ordinal 0, descriptors without functions, or tables its bounds and import
|
||||
symbol cap truncate). Delay-load issues do not withhold the hash.
|
||||
|
||||
A missing import directory is observed absence of that table. It is not proof
|
||||
the image never imported APIs through another table or overlay.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum). At most
|
||||
256 import and delay-load descriptors are examined by default (4096 maximum),
|
||||
and at most 8192 functions across every table (262144 maximum). Malformed PE
|
||||
headers and exhausted DLL or function budgets fail without partial success.
|
||||
Decoded DLL and function names are limited to a fixed 16 MiB of retained text
|
||||
with no runtime override; `max_file_bytes`, `max_dlls` and `max_functions` do
|
||||
not raise it. Resource failures report the exhausted allowance as `limit`
|
||||
(`dlls`, `functions` or `retained_text`) with matching recovery.
|
||||
|
||||
Unreadable DLL names, hint/name entries, or thunks are reported as partial
|
||||
coverage with `issues`. A descriptor whose required table RVA is zero (a
|
||||
standard `FirstThunk`, or a delay-load import address or name table) is
|
||||
reported as `malformed_entry` with no functions, never as a complete empty
|
||||
inventory. Delay-load descriptors that store virtual addresses rather than RVAs
|
||||
are recorded as `unsupported_form` and are not decoded.
|
||||
|
||||
This workflow does not resolve bound imports, loaded IAT contents, or
|
||||
export-forward names in another DLL.
|
||||
@@ -0,0 +1,55 @@
|
||||
# PE TLS callbacks and load configuration
|
||||
|
||||
Use `inspect_pe_load_config` to locate declared TLS callbacks and inspect the load
|
||||
configuration of an explicit local PE32 or PE32+ image. No disassembler, Windows
|
||||
host, or target execution is required.
|
||||
|
||||
```sh
|
||||
rea inspect-pe-load-config /absolute/path/to/application.exe --json
|
||||
rea inspect-pe-load-config /absolute/path/to/application.exe --max-callbacks 256 --json
|
||||
```
|
||||
|
||||
MCP accepts `{ "path": "/absolute/path/to/application.exe" }`. CLI paths may be
|
||||
relative to the current directory; MCP paths must be absolute.
|
||||
|
||||
The complete Evidence includes the artifact path, SHA-256, directory file ranges,
|
||||
and callback-array file ranges. `tls` reports the raw data range, index address,
|
||||
zero-fill size, characteristics and null-terminated callback array. Callback VAs
|
||||
are hexadecimal strings to preserve 64-bit precision. RVA, mapped file offset,
|
||||
and section are derived locations; unknown mappings are `null`.
|
||||
|
||||
`load_config` reports fields only when its declared `Size` covers the entire
|
||||
field. MSVC x86 images often declare a 64-byte load-config data directory while
|
||||
the structure's own `Size` is larger; like the Windows loader, REA reads `Size`
|
||||
bytes when they are file-backed in one run, and reports both
|
||||
`directory.size` and `size`. `structure_location` is the file range of the
|
||||
`Size` bytes REA checked; Evidence locations include it beside the declared
|
||||
directory range when the two differ. Unavailable fields are `null`; a covered zero pointer remains `"0x0"`.
|
||||
The report includes the security cookie, PE32 SafeSEH table/count, CFG pointers
|
||||
and table/count, address-taken IAT and long-jump tables/counts, EH continuation
|
||||
table/count, and XFG check pointer. CHPE and dynamic relocation pointers are raw
|
||||
values. The dynamic relocation table offset (DWORD) and section (WORD) are
|
||||
reported separately when `Size` covers them, including zero values; REA does
|
||||
not infer a VA from that pair or decode the target and mitigation-table entries.
|
||||
|
||||
Guard flags retain the raw DWORD, recognized names, unknown bits, and the CFG
|
||||
entry stride. Mitigation claims derived from those flags carry
|
||||
`evidence_kind: "inferred"`; they do not prove runtime enforcement. The image is
|
||||
never executed. Missing directories are observed absence of those declarations,
|
||||
not proof that no callback or mitigation exists by another mechanism.
|
||||
|
||||
The default read budget is 64 MiB (`max_file_bytes`, ceiling 512 MiB). The default
|
||||
callback budget is 64 (`max_callbacks`, ceiling 4096). An exact-budget array is
|
||||
accepted if its next slot is null. Truncated, ambiguous or unmapped directory and
|
||||
callback-array storage fails closed, as does budget exhaustion; no partial
|
||||
success is returned. An unmapped callback **target** retains its VA/RVA with an
|
||||
unknown file offset. Load-config versions beyond the supported fields remain
|
||||
undecoded.
|
||||
|
||||
Layout references: [Microsoft PE format](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format),
|
||||
[IMAGE_LOAD_CONFIG_DIRECTORY32](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_load_config_directory32),
|
||||
and [IMAGE_LOAD_CONFIG_DIRECTORY64](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_load_config_directory64).
|
||||
|
||||
For a real cross-compiled fixture, run `npm run verify:pe:load-config` with Zig
|
||||
on PATH (or `REA_ZIG` set to its path). The script builds PE32 and PE32+ samples
|
||||
and inspects them through the public CLI without running them.
|
||||
@@ -482,7 +482,8 @@ Every capture requires `truncation_details`, with separate accounting for:
|
||||
input, so raw omissions also limit rendered coverage. `unknown_size_frames`
|
||||
counts frames whose complete size was not calculated; it does not by itself
|
||||
identify normalization as the cause. `normalization_over_budget_frames`
|
||||
identifies omissions caused by an ordered normalization stage.
|
||||
counts the subset of unknown-size frames stopped by an ordered normalization
|
||||
stage; it cannot exceed `unknown_size_frames`.
|
||||
`observed_bytes` includes only rendered frame sizes determined exactly.
|
||||
- `filesystem_before` and `filesystem_after`: file-count/depth limits,
|
||||
enumeration failures, whole-file hash budget and bytes successfully hashed.
|
||||
|
||||
@@ -25,8 +25,12 @@ metadata retains the original name, table index, type, compression flag,
|
||||
relative offset and known directory record extent. Logical paths follow the
|
||||
carrier's path dialect: backslashes separate components for PE carriers, while
|
||||
they remain literal filename characters for POSIX carriers. The source name
|
||||
always retains its stored spelling. If the carrier dialect is unconfirmed, REA
|
||||
preserves backslashes verbatim instead of inferring POSIX semantics.
|
||||
always retains its stored spelling in occurrence `source_path` and
|
||||
`format_metadata.source_name`. For PYZ rows, that source is the exact module or
|
||||
data key in the PYZ table, not a reconstructed filesystem name;
|
||||
`format_metadata.container_name` identifies the containing PYZ image. If the
|
||||
carrier dialect is unconfirmed, REA preserves backslashes verbatim instead of
|
||||
inferring POSIX semantics.
|
||||
`relative_offset` is relative to the CArchive start for CArchive rows, or to
|
||||
the decoded PYZ image for PYZ rows. A CArchive directory record starts at
|
||||
`archive_start + toc_offset + directory_record_offset`; its size is
|
||||
|
||||
@@ -20,6 +20,60 @@ requires an absolute filesystem path and preserves that exact selection:
|
||||
}
|
||||
```
|
||||
|
||||
## Selected code objects
|
||||
|
||||
Complete output remains the default. To read selected code objects from a large
|
||||
report, request MCP `detail: "summary"`. The summary contains artifact/header
|
||||
identity, source coverage and a limitation count; its
|
||||
`normalized_result.parent_evidence_id` identifies the complete retained report.
|
||||
Use that parent ID with `inspect_analysis_view` and:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "python-pyc",
|
||||
"collection": "code_objects",
|
||||
"names": ["parse_args", "parse_known_args"],
|
||||
"fields": [
|
||||
"name",
|
||||
"qualname",
|
||||
"filename",
|
||||
"firstlineno",
|
||||
"bytecode",
|
||||
"nested_code"
|
||||
],
|
||||
"offset": 0,
|
||||
"limit": 64
|
||||
}
|
||||
```
|
||||
|
||||
This is the request's `view` field. To receive these selected facts in the first
|
||||
call, include the same `view` directly in `inspect_python_pyc` alongside
|
||||
`detail: "summary"`. Later pages use the returned parent ID with
|
||||
`inspect_analysis_view`. `view` requires summary delivery; complete delivery
|
||||
rejects a view instead of ignoring it. `names` matches retained display strings and
|
||||
returns every same-name object. `indices` selects original `code_objects`
|
||||
indexes; combining names and indices intersects those selectors. Omitted
|
||||
selectors include all rows, while `[]` selects none. Each row always includes
|
||||
`source_index`, scoped to its parent Evidence; `fields: []` returns only that
|
||||
index. Filtering preserves source order, and paging counts matching rows.
|
||||
The view's `pyc.coverage` preserves source coverage independently of page
|
||||
coverage. Views preserve `nested_code` indexes and their code-constant semantics.
|
||||
|
||||
CLI summary delivery requires a durable destination for the complete Evidence:
|
||||
|
||||
```bash
|
||||
rea inspect-python-pyc module.pyc --detail summary --evidence_output module.evidence.json --json
|
||||
```
|
||||
|
||||
Add `--view '{"kind":"python-pyc","collection":"code_objects","names":["parse_args"],"fields":["name","bytecode"]}'`
|
||||
to select facts in that initial CLI call.
|
||||
|
||||
The output's `summary` is derived Evidence. Pass its parent ID and the saved
|
||||
bundle to `inspect-analysis-view --evidence-bundle module.evidence.json` for
|
||||
offline queries. MCP views read retained Evidence, and offline views read the
|
||||
bundle; neither requires the original pyc to remain present. Parse budgets and
|
||||
complete-source retention still apply to summary delivery.
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte length.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Headerless raw-binary analysis with Ghidra
|
||||
|
||||
Headerless images are covered here. GameCube/Wii DOL images have a header and
|
||||
use their own format selection; see [GameCube DOL analysis](ghidra-dol.md).
|
||||
|
||||
REA admits a headerless executable when the caller supplies the CPU family and
|
||||
the address where file offset 0 should be mapped. That interpretation is not
|
||||
inferred from a `.bin` suffix or from unrecognized bytes.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: هندسة عكسية لأي شيء
|
||||
|
||||
@@ -154,10 +154,13 @@ npx rea-agents@latest setup
|
||||
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](../native-investigation.md) |
|
||||
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](../recorded-crashes.md) |
|
||||
| تثبيتات سطح المكتب | عائلات وقت التشغيل، والملفات الداعمة، وعلامات المكونات، والخطوات التالية | فحص محدود للملفات والترويسات;[تطبيقات سطح المكتب](../desktop-applications.md) |
|
||||
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Alles reverse-engineeren
|
||||
|
||||
@@ -154,10 +154,13 @@ REA benötigt Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) oder 26+ (>=26.12.1) so
|
||||
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](../native-investigation.md) |
|
||||
| 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](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Desktop-Installationen | Laufzeitkandidaten, Quelldateien, Komponenten und nächste Schritte | Begrenzte Verzeichnis- und Headerprüfung;[Desktop-Anwendungen](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -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_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά** · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.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) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά** · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -156,7 +156,10 @@ npx rea-agents@latest setup
|
||||
| Δυαδικά αρχεία Go | Ενσωματωμένη έκδοση μεταγλωττιστή, modules, αντικαταστάσεις και ρυθμίσεις μεταγλώττισης | Ενσωματωμένη στατική εξέταση ELF/PE/thin Mach-O· δεν απαιτείται εγκατάσταση του Go |
|
||||
| Δυαδικά αρχεία Rust | Ενσωματωμένα ονόματα, εκδόσεις, πηγές και σχέσεις εξάρτησης των crates από το cargo-auditable | Ενσωματωμένη στατική εξέταση ELF/PE/thin Mach-O· [δυαδικά αρχεία Rust](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Αρχείο WASM | Έλεγχο εγκυρότητας, ενότητες, ακριβείς μορφές εισαγωγών/εξαγωγών σε WAT και αποκωδικοποιημένο WAT | WABT 1.0.42 που παρέχει ο χρήστης· `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selectors επιλογής συνάρτησης, μετατοπίσεις σε bytes, εκτιμώμενα ορίσματα και δυνατότητα μεταβολής της κατάστασης | Τοπική είσοδος σε ακατέργαστα bytes ή δεκαεξαδική μορφή σε Linux x64· [οδηγός EVM χωρίς εκτέλεση](../evm-bytecode.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Ingeniería inversa de cualquier cosa
|
||||
|
||||
@@ -154,10 +154,13 @@ REA requiere Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), adem
|
||||
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](../native-investigation.md) |
|
||||
| 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](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Instalaciones de escritorio | Posibles entornos de ejecución, archivos de evidencia, componentes y siguientes pasos | Inspección acotada de directorios y cabeceras;[Aplicaciones de escritorio](../desktop-applications.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](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · **فارسی** · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: مهندسی معکوس هر چیزی
|
||||
|
||||
@@ -146,9 +146,12 @@ REA به Node.js 22.x (>=22.23.4)، 24.x (>=24.22.1) یا 26+ (>=26.12.1)، به
|
||||
| باینریهای بومی | شبهکد، اسمبلی، رشتهها، نمادها، فراخوانیها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](../native-investigation.md) |
|
||||
| ساختار ELF آفلاین | بخشها، سگمنتها، نمادها و relocationهای اصلی و گزینههای احتمالی کاهش آسیبپذیری ایستا | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| بایتکد EVM | selectorهای dispatch، offsetهای بایتی، آرگومانهای استنباطشده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| کرشهای ثبتشدهٔ لینوکس | یادداشتهای خام، رجیسترها/سیگنالهای تمام threadهای ثبتشده و گزینههای احتمالی نگاشت | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرشهای ثبتشده](../recorded-crashes.md) |
|
||||
| نصبهای دسکتاپ | نامزدهای زمان اجرا، فایلهای شاهد، نشانههای مؤلفهها و مراحل بعدی | بررسی محدود پوشهها و سرآیندها;[برنامههای دسکتاپ](../desktop-applications.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA : rétro-ingénierie de tout
|
||||
|
||||
@@ -153,11 +153,14 @@ REA nécessite Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), ai
|
||||
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](../native-investigation.md) |
|
||||
| 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](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| Artefact WASM | Validation, sections, formes WAT exactes d'import/export et WAT décodé | WABT 1.0.42 fourni par l'utilisateur ; `inspect_wasm_artifact` |
|
||||
| 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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Installations de bureau | Environnements candidats, fichiers justificatifs, composants et étapes suivantes | Inspection bornée des répertoires et en-têtes;[Applications de bureau](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Rekayasa Balik Apa Pun
|
||||
|
||||
@@ -156,10 +156,13 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
|
||||
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](../native-investigation.md) |
|
||||
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| Artefak WASM | Validasi, bagian, bentuk WAT import/ekspor yang tepat, dan WAT yang didekode | WABT 1.0.42 yang disediakan pemanggil; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.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](../recorded-crashes.md) |
|
||||
| Instalasi desktop | Kandidat runtime, berkas pendukung, penanda komponen, dan langkah berikutnya | Pemeriksaan direktori dan header terbatas;[Aplikasi desktop](../desktop-applications.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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**
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -153,11 +153,14 @@ REA richiede Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), oltre
|
||||
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](../native-investigation.md) |
|
||||
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| Artefatto WASM | Convalida, sezioni, forme WAT di import/export esatte e WAT decodificato | WABT 1.0.42 fornito dal chiamante; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Installazioni desktop | Runtime candidati, file di supporto, componenti e passi successivi | Ispezione limitata di directory e intestazioni;[Applicazioni desktop](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA:あらゆるものをリバースエンジニアリング
|
||||
|
||||
@@ -154,9 +154,12 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
|
||||
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](../native-investigation.md) |
|
||||
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](../recorded-crashes.md) |
|
||||
| デスクトップのインストール先 | ランタイム候補、根拠ファイル、コンポーネントの目印、次の調査手順 | 上限付きのディレクトリ・ヘッダー検査;[デスクトップアプリ](../desktop-applications.md) |
|
||||
@@ -322,9 +325,7 @@ REA の利用、バグ報告、機能の要望、ビルドのテスト、修正
|
||||
|
||||
REA は、法令に従った研究、教育、相互運用性の確保、ソフトウェアの保存、および所有するソフトウェアや調査を許可されたソフトウェアの解析を目的としています。
|
||||
|
||||
The project's position on illegal or unauthorized use covers all REA
|
||||
versions, distribution channels, and platforms; each copy retains its
|
||||
applicable licenses.
|
||||
違法または無許可の利用に関するプロジェクトの立場は、REA のすべてのバージョン、配布チャネル、およびプラットフォームに適用されます。各コピーには、それぞれに適用されるライセンスが引き続き適用されます。
|
||||
|
||||
## 貢献する
|
||||
|
||||
@@ -336,14 +337,6 @@ REA への貢献を歓迎します
|
||||
|
||||
REA-authored code is licensed under MIT. Third-party material retains its own
|
||||
licenses and copyright notices; see [Third-party notices](../../THIRD_PARTY_NOTICES.md)
|
||||
for the dependency inventory, preserved license texts, and external-tool terms.
|
||||
REA が作成したコードは MIT ライセンスの下で提供されます。サードパーティの素材には、それぞれのライセンスと著作権表示が引き続き適用されます。依存関係の一覧、保存されたライセンス本文、および外部ツールの利用条件については、[サードパーティ通知](../../THIRD_PARTY_NOTICES.md)を参照してください。
|
||||
|
||||
**You must legally obtain and be authorized to use commercial tools**, including
|
||||
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
|
||||
REA grants no tool license, key, or activation entitlement. Trials and demos
|
||||
remain subject to vendor terms, including user, feature, automation, and output
|
||||
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
|
||||
and bypassing license restrictions are not authorized. This guidance does not
|
||||
amend MIT or third-party licenses.
|
||||
**IDA Pro / Hex-Rays デコンパイラ、Hopper、JEB を含む商用ツールは、適用されるライセンスに従って合法的に入手し、使用する権限を得ている必要があります。** REA はツールのライセンス、キー、またはアクティベーションの権利を一切付与しません。試用版やデモ版も、ユーザー、機能、自動化、および出力の共有に関する制限を含め、ベンダーの利用条件に従います。クラックされたコピー、盗まれたキー、無許可のキー共有、およびライセンス制限の回避は認められていません。このガイダンスは、MIT ライセンスやサードパーティのライセンスを変更するものではありません。
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: 무엇이든 리버스 엔지니어링
|
||||
|
||||
@@ -156,7 +156,10 @@ REA에는 Node.js 22.x(>=22.23.4), 24.x(>=24.22.1) 또는 26+ (>=26.12.1)와 npm
|
||||
| Go 바이너리 | 내장된 컴파일러 버전, 모듈, `replace` 지시어, 빌드 설정 | REA 내장 ELF/PE/thin Mach-O 정적 검사; Go 설치 불필요 |
|
||||
| Rust 바이너리 | cargo-auditable이 내장한 크레이트 이름, 버전, 소스, 의존성 관계 | REA 내장 ELF/PE/thin Mach-O 정적 검사; [Rust 바이너리](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| WASM 아티팩트 | 유효성 검사, 섹션, import/export의 정확한 WAT 형식, 디코딩된 WAT | 호출자 제공 WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](../evm-bytecode.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · **മലയാളം** · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · **മലയാളം** · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: എന്തും Reverse Engineer ചെയ്യുക
|
||||
|
||||
@@ -156,11 +156,14 @@ REA-യ്ക്ക് Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), അല്ല
|
||||
| Go binaries | ഉൾച്ചേർത്ത compiler version, modules, replacements, build settings | Built-in static ELF/PE/thin Mach-O പരിശോധന; Go installation ആവശ്യമില്ല |
|
||||
| Rust binaries | ഉൾച്ചേർത്ത cargo-auditable crate പേരുകൾ, versions, sources, dependency edges | Built-in static ELF/PE/thin Mach-O പരിശോധന; [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| WASM artifact | Validation, sections, കൃത്യമായ import/export WAT രൂപങ്ങൾ, decoded WAT | Caller നൽകുന്ന WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, അനുമാനിച്ച arguments, mutability | Linux x64-ൽ local raw/hex carrier; [offline EVM guide](../evm-bytecode.md) |
|
||||
| SQLite databases | Tables, columns, indexes, views, triggers, തിരഞ്ഞെടുത്ത സാധാരണ table rows | Local database/WAL snapshot; native SQLite പരിമിതികളോടെ Node.js 24.x >=24.15 അല്ലെങ്കിൽ 26+ |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Recorded Linux crashes | Raw notes, രേഖപ്പെടുത്തിയ ഓരോ thread-ന്റെയും registers/signals, ഐച്ഛിക mapping candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; ഐച്ഛിക GDB/pwndbg; [recorded crashes](../recorded-crashes.md) |
|
||||
| ഡെസ്ക്ടോപ്പ് ഇൻസ്റ്റലേഷനുകൾ | റൺടൈം സാധ്യതകൾ, തെളിവ് ഫയലുകൾ, ഘടക സൂചനകൾ, തുടർ നടപടികൾ | പരിധിയുള്ള ഡയറക്ടറി, ഹെഡർ പരിശോധന;[ഡെസ്ക്ടോപ്പ് ആപ്ലിക്കേഷനുകൾ](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC, native add-on ബന്ധങ്ങൾ | Node.js, npm; Linux: procps-compatible `ps`; [application analysis](../javascript-application-workflows.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -154,10 +154,13 @@ REA wymaga Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) lub 26+ (>=26.12.1) oraz n
|
||||
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](../native-investigation.md) |
|
||||
| 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](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Instalacje desktopowe | Kandydaci środowisk uruchomieniowych, pliki źródłowe dowodów, komponenty i dalsze kroki | Ograniczona inspekcja katalogów i nagłówków;[Aplikacje desktopowe](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Faça engenharia reversa de qualquer coisa
|
||||
|
||||
@@ -154,10 +154,13 @@ O REA requer Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), alé
|
||||
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](../native-investigation.md) |
|
||||
| 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](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Instalações desktop | Ambientes candidatos, arquivos de evidência, componentes e próximos passos | Inspeção limitada de diretórios e cabeçalhos;[Aplicações desktop](../desktop-applications.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](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
<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](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · **Română**
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
### Un singur server MCP pentru inginerie inversă: fișiere binare, aplicații și comportament în timpul execuției.
|
||||
|
||||
**Ai găsit o funcționalitate care îți place? Înțelege cum funcționează, până la nivel de cod binar.**
|
||||
|
||||
[](https://www.npmjs.com/package/rea-agents)
|
||||
[](../mcp-contracts.md#generated-catalog)
|
||||
[](#ce-poți-analiza)
|
||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||
[](../../LICENSE)
|
||||
[](https://discord.gg/GkcryMnJDM)
|
||||
|
||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&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>
|
||||
|
||||
**[Site web](https://rea.tools/) · [Ghiduri](https://rea.tools/guides/) · [Studii de caz](https://rea.tools/showcase/)**
|
||||
|
||||
[Pornire rapidă](#pornire-rapidă) · [Cum funcționează REA](#cum-funcționează-rea) · [Ce poți analiza](#ce-poți-analiza) · [Studii de caz](#studii-de-caz) · [Întrebări frecvente](#întrebări-frecvente) · [Documentație](#documentație)
|
||||
|
||||
<code>npx rea-agents setup</code>
|
||||
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Descarcă REA din [morluto/rea](https://github.com/morluto/rea),
|
||||
> de pe [rea.tools](https://rea.tools/) sau prin [pachetul npm rea-agents](https://www.npmjs.com/package/rea-agents).
|
||||
> Urmează linkurile de instalare și către versiunile publicate oferite de aceste surse oficiale.
|
||||
> Un nume de repository asemănător sau un README copiat nu dovedește că descărcarea provine dintr-o sursă oficială.
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<img src="../assets/rea-hopper-analysis.png" alt="REA pornește componenta de legătură pentru analiză în Hopper în timp ce inspectează un fișier binar nativ" width="1200" />
|
||||
|
||||
<br /><br />
|
||||
|
||||
<table aria-label="Comunitatea REA">
|
||||
<tr>
|
||||
<td align="center" width="360">
|
||||
<a href="https://discord.gg/GkcryMnJDM">
|
||||
<img src="../assets/discord.svg" height="42" alt="Discord" /><br />
|
||||
<strong>Alătură-te comunității de inginerie inversă</strong>
|
||||
</a><br />
|
||||
<sub>Discord · Întrebări și răspunsuri · Prezentări și demonstrații</sub>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
Ai văzut într-o aplicație o funcționalitate pe care ai vrea să o incluzi în propriul produs? Cere-i agentului tău să o investigheze cu REA. Poate inspecta aplicația fără codul ei sursă, poate explica modul în care funcționează acea funcționalitate, poate prezenta dovezile și poate construi o variantă pentru proiectul tău.
|
||||
|
||||
REA conectează agentul tău la unelte pentru inspectarea fișierelor binare native, a aplicațiilor JavaScript și Electron, a ansamblurilor .NET și a site-urilor web. Poți folosi aceleași unelte și din terminal. Analiza rulează local, iar rezultatele includ dovezile și limitările care stau la baza fiecărei concluzii.
|
||||
|
||||
Programul de configurare înregistrează REA în agentul tău și instalează instrucțiunile corespunzătoare pentru fluxul de lucru. Analiza nativă poate folosi o instalare existentă de Hopper, Ghidra sau IDA; programul de configurare poate instala opțional Hopper, cu aprobarea ta. Analiza statică JavaScript nu necesită un motor de analiză nativă.
|
||||
|
||||
> **[Vizitează site-ul REA](https://rea.tools/)** pentru instrucțiuni de configurare, ghiduri ilustrate și studii de caz reale.
|
||||
|
||||
## Pornire rapidă
|
||||
|
||||
Pe Linux, pornirea Ghidra, JADX și a uneltelor pentru firmware, precum și analiza
|
||||
statică JavaScript/Electron necesită un `ps` compatibil cu procps în `PATH`-ul REA,
|
||||
pentru a verifica dacă procesele îi aparțin. Pașii de remediere sunt în
|
||||
`docs/installation.md`, la secțiunea „Linux owned-process prerequisite”.
|
||||
|
||||
### Configurează agentul
|
||||
|
||||
Cu Node.js și npm instalate, rulează:
|
||||
|
||||
```bash
|
||||
npx rea-agents setup
|
||||
```
|
||||
|
||||
Alege agenții, verifică modificările propuse și aprobă-le. Configurarea adaugă
|
||||
serverul MCP REA și instrucțiunile corespunzătoare pentru fluxul de lucru,
|
||||
creând copii de siguranță ale configurației existente. Repornește apoi agentul.
|
||||
|
||||
Programul de configurare acceptă Claude Code, Codex, Cursor, Gemini CLI, Grok Build și
|
||||
[alți agenți](../installation.md#supported-agents). Consultă
|
||||
[instalarea și configurarea](../installation.md) pentru configurarea motoarelor
|
||||
de analiză și înregistrarea manuală a serverului MCP.
|
||||
|
||||
MCP folosește implicit scheme de intrare compacte, pentru a reduce spațiul ocupat
|
||||
în context. Setează `REA_MCP_INPUT_SCHEMA_PROFILE=full` în înregistrarea MCP când
|
||||
ai nevoie de îndrumările complete pentru câmpurile expuse și de detaliile
|
||||
validării structurilor imbricate. Ambele profiluri păstrează toate uneltele și
|
||||
validarea canonică a serverului. Consultă secțiunea „Compact input schema profile”
|
||||
din ghidul contractelor MCP.
|
||||
|
||||
### Cere-i agentului
|
||||
|
||||
```text
|
||||
Înțelege cum funcționează căutarea în aplicația Notes, arată-mi dovezile și
|
||||
construiește o funcționalitate similară pentru proiectul meu.
|
||||
```
|
||||
|
||||
Înlocuiește Notes cu aplicația vizată și precizează funcționalitatea pe care vrei să o înțelegi.
|
||||
|
||||
### Folosește terminalul
|
||||
|
||||
Inspectează directorul extras al unei aplicații JavaScript/Electron sau o arhivă ASAR:
|
||||
|
||||
```bash
|
||||
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
|
||||
```
|
||||
|
||||
Rezultatul include modulele, importurile, delimitările dintre componentele Electron
|
||||
și dovezile aferente. Înlocuiește calea cu cea a aplicației vizate, de exemplu
|
||||
`"D:/apps/example"` pe Windows.
|
||||
|
||||
Pentru a instala comanda `rea` și a o folosi în mod curent:
|
||||
|
||||
```bash
|
||||
npm install --global rea-agents
|
||||
rea --help
|
||||
```
|
||||
|
||||
Pentru analiza nativă, configurează mai întâi un motor de analiză. Consultă
|
||||
[ghidul CLI și Evidence](../cli.md) pentru comenzile de analiză nativă,
|
||||
selectarea motorului, instantanee și utilizarea în scripturi.
|
||||
|
||||
### Actualizează REA
|
||||
|
||||
REA evoluează rapid, iar versiunile noi includ frecvent corecții de erori.
|
||||
Menține instalarea la zi.
|
||||
|
||||
Pentru o interfață CLI instalată cu `npm install --global` sau `bun add --global`:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
`rea --update` este un alias pentru acest flux de actualizare verificat și acceptă
|
||||
aceleași opțiuni globale de ieșire. Folosește `rea update` când îl combini cu alte
|
||||
opțiuni de control al comenzii.
|
||||
|
||||
Comenzile de actualizare păstrează cel mult 4 MiB în total din stdout și stderr.
|
||||
Răspunsurile cu metadate prea mari sunt respinse după încheierea comenzii;
|
||||
instalările cu ieșire detaliată continuă cu un volum limitat de date de diagnostic.
|
||||
Afișarea progresului în terminal ține cont de ritmul în care acesta poate primi
|
||||
date și așteaptă finalizarea operațiilor de scriere deja trimise.
|
||||
|
||||
Actualizările instalărilor globale cu Bun necesită Bun 1.2.17 sau o versiune mai nouă.
|
||||
Dacă ai o versiune mai veche, actualizează Bun manual înainte de a rula `rea update`.
|
||||
|
||||
Pentru a actualiza înregistrările agenților și skill-ul, rulează comanda de
|
||||
configurare afișată de programul de actualizare.
|
||||
|
||||
Dacă folosești `npx`, actualizează configurarea agentului cu:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
Verifică modificările de configurare și repornește agentul. Pentru comenzi CLI
|
||||
ocazionale, folosește `npx rea-agents@latest` urmat de comandă. Cu Bun, folosește
|
||||
`bunx rea-agents@latest` în loc de `npx rea-agents@latest`.
|
||||
|
||||
## Cum funcționează REA
|
||||
|
||||
Agentul tău apelează REA prin MCP pentru a inspecta ținta și a urmări codul relevant.
|
||||
REA returnează constatările împreună cu dovezile aferente. Agentul le folosește
|
||||
pentru a pune întrebări suplimentare, a explica comportamentul sau a scrie și
|
||||
testa o implementare. Comenzile CLI folosesc aceleași fluxuri de lucru.
|
||||
|
||||

|
||||
|
||||
[Deschide figura la dimensiunea originală](../../website/public/assets/figures/rea-investigation-flow.svg).
|
||||
|
||||
<a id="current-status"></a>
|
||||
|
||||
## Ce poți analiza
|
||||
|
||||
REA necesită Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) sau 26.12.1+, plus npm.
|
||||
Uneltele suplimentare și platformele acceptate depind de ținta analizată:
|
||||
|
||||
| Țintă | Ce returnează REA | Cerințe și ghid |
|
||||
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Aplicații desktop instalate | Componente de execuție candidate, fișiere auxiliare, indicii despre componente și următoarele verificări | Inspectare integrată a directoarelor și antetelor, cu limite de resurse; [aplicații desktop](../desktop-applications.md) |
|
||||
| Fișiere binare native | Pseudocod, cod de asamblare, șiruri de caractere, simboluri, apeluri și referințe | Hopper, Ghidra sau IDA; [analiză nativă](../native-investigation.md) |
|
||||
| Structura ELF, offline | Secțiuni, segmente, simboluri și relocări originale, precum și indicii statice despre mecanismele de protecție | pwntools furnizat de utilizator, pe Linux x64; [diagnosticarea binarelor](../binary-diagnostics.md) |
|
||||
| Fișiere binare Go | Versiunea compilatorului încorporată în fișier, modulele, înlocuirile și setările de compilare | Inspectare statică integrată a fișierelor ELF/PE/Mach-O cu o singură arhitectură; nu necesită instalarea Go |
|
||||
| Obiecte de cod GPU | Ținte CUDA/HIP, parametri și resurse selectate ale kernelurilor GPU, textul PTX păstrat | Inspectare statică integrată a fișierelor ELF/PE/fatbin/CUBIN/PTX; [obiecte de cod GPU](../gpu-code-objects.md) |
|
||||
| Fișiere de model | Metadate GGUF / safetensors, declarații de tensori și totaluri calculate din acestea | Inspectare integrată a antetelor; opțional, hash al întregului fișier; [fișiere de model](../model-artifacts.md) |
|
||||
| Metadate IL2CPP | Imagini de ansambluri din global-metadata.dat al Unity, nume de tipuri și metode și intervale de indici | Decodare statică integrată a versiunilor 24, 27, 29, 31 și 39; nu necesită Unity |
|
||||
| Godot PCK | Inventarul și extragerea arhivei, informații originale din antet și director și identificatori ai conținutului selectat | Suport static integrat pentru formatele 2, 3 și 4; nu necesită Godot |
|
||||
| Fișiere binare Rust | Nume, versiuni, surse și relații de dependență ale pachetelor crate încorporate prin cargo-auditable | Inspectare statică integrată a fișierelor ELF/PE/Mach-O cu o singură arhitectură; [binare Rust](../rust-binaries.md) |
|
||||
| Certificate PE | Intrări Authenticode WIN_CERTIFICATE și câmpuri de identitate ale semnatarilor PKCS#7 și certificatelor X.509 | Inspectare statică integrată a fișierelor PE; [certificate PE](../pe-certificates.md) |
|
||||
| Importuri PE | Numele DLL-urilor importate și încărcate întârziat, ordinale, RVA-uri ale IAT și hash-ul importurilor calculat de pefile | Inspectare statică integrată a fișierelor PE; [importuri PE](../pe-imports.md) |
|
||||
| Note ELF | Proprietari și tipuri PT_NOTE/SHT_NOTE, câmpuri GNU build-id și ABI-tag | Inspectare statică integrată a fișierelor ELF; [note ELF](../elf-notes.md) |
|
||||
| Rapoarte Apple IPS de eroare fatală | Metadate .ips, fire de execuție, imagini binare, registre și clase documentate de erori fatale | Inspectare statică integrată a datelor JSON; [Apple IPS](../apple-ips.md) |
|
||||
| Module de kernel Linux | Chei .modinfo, CRC-uri din __versions, prezența this_module și structura semnăturii de la sfârșitul fișierului | Inspectare statică integrată a fișierelor ELF; [module de kernel](../kernel-modules.md) |
|
||||
| Erlang BEAM | Blocuri IFF, atomi, exporturi, importuri, funcții lambda și antetul Code | Inspectare statică integrată a fișierelor BEAM; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Fișiere WASM | Validare, secțiuni, forme WAT exacte ale importurilor și exporturilor și cod WAT decodat | WABT 1.0.42 furnizat de utilizator; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selectori de apel, poziții în octeți, argumente și mutabilitate deduse | Fișier local în format brut sau hexazecimal, pe Linux x64; [ghid EVM offline](../evm-bytecode.md) |
|
||||
| Baze de date SQLite | Tabele, coloane, indecși, vizualizări, declanșatoare și rânduri selectate din tabele obișnuite | Instantaneu local al bazei de date/WAL; Node.js 24.x >=24.15 sau 26+, cu limite SQLite native |
|
||||
| Erori fatale Linux înregistrate | Note brute, registrele și semnalele fiecărui fir înregistrat și, opțional, corespondențe candidate pentru mapările de memorie | pwntools furnizat de utilizator, pe Linux x64; opțional GDB/pwndbg; [erori fatale înregistrate](../recorded-crashes.md) |
|
||||
| JavaScript / Electron | Module, importuri, hărți de cod sursă, rute, IPC și relații cu extensiile native | Node.js și npm; pe Linux: `ps` compatibil cu procps; [analiza aplicațiilor](../javascript-application-workflows.md) |
|
||||
| Site-uri web | Structura paginilor, scripturi, observații de rețea și capturi de ecran solicitate | Un browser din familia Chrome; [analiză în browser](../browser-observation.md) |
|
||||
| Capturi de rețea salvate | Cereri, răspunsuri, conținuturi expuse ale mesajelor și pozițiile lor în sursă | HAR sau SAZ din Fiddler Everywhere; mitmdump pe Linux pentru formatul nativ mitmproxy; [ghidul capturilor](../web-network-captures.md) |
|
||||
| Ansambluri .NET | Metadate, instrucțiuni CIL, dependențe native declarate și comparații între compilări | Fără cerințe suplimentare (doar analiză statică); [ghidul codului gestionat](../managed-code-analysis.md) |
|
||||
| APK-uri Android | Declarații din manifest, clase, metode decompilate și referințe | JADX fără interfață grafică și un JDK complet, pe Linux/macOS/Windows x64; [ghidul Android](../android-analysis.md) |
|
||||
| Semnături APK | Semnatari v1/v2/v3/v3.1, amprente ale certificatelor, rotația cheilor și consistența internă a hash-urilor | Fără cerințe suplimentare (doar analiză statică); `inspect_apk_signature` |
|
||||
| Dispozitive Android | Dispozitive, pachete, procese, jurnale, dumpuri, capturi de ecran și transferuri de APK-uri și fișiere | adb furnizat de utilizator (emulator sau dispozitiv fizic); [ghidul ADB](../adb-device-analysis.md) |
|
||||
| Proiecte JEB | Unități de proiect analizate prin motor, hash-uri ale artefactelor și pseudocod pentru tipuri și metode | Un client JEB pornit de utilizator, care oferă un server MCP și este selectat prin REA_JEB_MCP_URL; [ghidul JEB](../jeb-analysis.md) |
|
||||
| Resurse Android | Manifest decodat, tabele de șiruri de caractere, localizări și informații despre versiune | Program de lansare Apktool furnizat de utilizator; [ghidul resurselor](../apktool-resource-analysis.md) |
|
||||
| Aplicații Flutter | Hash-ul instantaneului Dart, hash-uri ale bibliotecilor pentru fiecare ABI și proveniența compilării motorului | Fără cerințe suplimentare (parsare statică a APK-ului); [ghidul Flutter](../flutter-analysis.md) |
|
||||
| Firmware | Regiuni, rezultate ale extragerii și transferul către analiza nativă | Binwalk / Unblob pe Linux; [ghidul firmware](../firmware-analysis.md) |
|
||||
| Pachete de rețea înregistrate | Câmpuri selectate, valori repetate, filtre și reguli decode-as | Linux: TShark 4.x + prlimit; [ghidul capturilor](../packet-captures.md) |
|
||||
| Rezumate ale traficului de rețea | Puncte terminale, DNS, TLS SNI, distribuția protocoalelor și cereri HTTP | tshark și capinfos furnizate de utilizator (verificate pe Linux); [ghidul pcap](../pcap-analysis.md) |
|
||||
| Semnale logice înregistrate | Adnotări ale decodorului, intervale de eșantioane și date de diagnostic | Linux: sigrok-cli 0.7.2 + prlimit; [înregistrări de semnale](../signal-recordings.md) |
|
||||
| Pachete și resurse | Inventare de fișiere, hash-uri, fișiere plist, structura pachetelor de aplicație Apple și resurse extrase | [Ghidul artefactelor și JavaScript](../javascript-artifact-reconstruction.md), [aplicații Apple](../apple-application-analysis.md) |
|
||||
| Comportamentul proceselor | Ieșirea în terminal, interacțiuni, observații despre terminarea proceselor și sistemul de fișiere și comparații între rulări | Linux/macOS cu un PTY nativ; [capturarea proceselor](../process-capture.md) |
|
||||
| Executabile PyInstaller | Membri CArchive, versiunea Python, scripturi de intrare și bytecode extras | Fără cerințe suplimentare (doar analiză statică); [aplicații Python împachetate](../python-packaged-applications.md) |
|
||||
|
||||
Inspectarea statică JavaScript și .NET citește fișierele furnizate fără a rula
|
||||
aplicația. Capturarea în timpul execuției rulează ținta selectată sau interacționează
|
||||
cu aceasta folosind permisiunile contului tău; fiecare ghid de capturare descrie
|
||||
efectele acestor operații.
|
||||
|
||||
Pentru inspectarea offline a binarelor native, REA acceptă și GNU objdump și Rizin,
|
||||
furnizate de utilizator. Consultă [ghidul uneltelor de inginerie inversă](../reverse-engineering-tools.md)
|
||||
pentru configurare, comenzi CLI și limitările obiectelor Evidence. REA nu
|
||||
instalează și nu actualizează niciunul dintre aceste două instrumente.
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Formatele native și platformele acceptate diferă în funcție de motorul de analiză.
|
||||
Consultă [configurarea Hopper și Ghidra](../installation.md#hopper),
|
||||
[ghidul IDA](../ida-provider.md) (inclusiv o componentă opțională de legătură MCP nativă),
|
||||
[ghidul decompilatorului Kuna](../kuna-provider.md) și
|
||||
[suportul experimental Ghidra pe Windows](../windows-ghidra-p0.md).
|
||||
Ghidra acceptă și [analiza DOS pe 16 biți](../ghidra-dos.md).
|
||||
Pentru binare mari, mărește timpul maxim de pornire al motorului cu
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` sau `REA_HOPPER_STARTUP_TIMEOUT_MS`.
|
||||
Pentru selectarea motorului, consultă [ghidul CLI](../cli.md#choose-a-provider).
|
||||
Verifică [disponibilitatea în versiunile publicate](../installation.md#released-package-and-main)
|
||||
pentru funcționalitățile adăugate după cea mai recentă versiune npm.
|
||||
|
||||
## Studii de caz
|
||||
|
||||
<a href="https://rea.tools/showcase/">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="../assets/rea-showcases-dark.svg" />
|
||||
<img alt="Ilustrații pentru studiile de caz despre panoramarea sunetului în DX-Ball, legătura cu clipboardul în Notion și inelele de proiectile din TH04" src="../assets/rea-showcases.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
### DX-Ball: reconstruiește calculul panoramării sunetului
|
||||
|
||||
Urmărește un apel audio până la funcția auxiliară care transformă poziția în
|
||||
panoramare stereo, inspectează instrucțiunile și transformă pseudocodul incomplet
|
||||
în C. Reconstrucția trece 3.205 cazuri de test comparate cu originalul x86 și
|
||||
reproduce toți cei 63 de octeți ai funcției compilate.
|
||||
|
||||
[Citește studiul de caz](https://rea.tools/showcase/dx-ball/) ·
|
||||
[Repository-ul reconstrucției](https://github.com/N0zoM1z0/dx-ball)
|
||||
|
||||
### Notion: urmărește legătura Electron cu clipboardul
|
||||
|
||||
Găsește API-ul pentru clipboard din procesul de randare, urmărește-l prin preload
|
||||
și IPC până în procesul principal și inspectează formatul datelor cu formatare din clipboard.
|
||||
|
||||
[Citește studiul de caz](https://rea.tools/showcase/notion/)
|
||||
|
||||
### TH04: recuperează calculul unui inel de proiectile DOS
|
||||
|
||||
Inspectează instrucțiunile pe 16 biți ale jocului original pentru PC-98,
|
||||
recuperează calculele unghiurilor fixe și ale celor orientate spre țintă și
|
||||
compară codul C++ reconstruit cu rezultatul compilatorului folosit la acea vreme.
|
||||
|
||||
[Citește studiul de caz](https://rea.tools/showcase/th04/) ·
|
||||
[Repository-ul reconstrucției](https://github.com/N0zoM1z0/th04)
|
||||
|
||||
Dacă ai folosit REA pentru ceva interesant, ne-ar plăcea să vedem rezultatul.
|
||||
Prezintă cazul într-un [issue](https://github.com/morluto/rea/issues) sau într-un
|
||||
[pull request](https://github.com/morluto/rea/pulls), menționând ținta analizată,
|
||||
întrebarea ta, cum te-a ajutat REA și ce ai descoperit.
|
||||
|
||||
## Întrebări frecvente
|
||||
|
||||
<details>
|
||||
<summary><strong>Ce agenți pot folosi REA?</strong></summary>
|
||||
|
||||
Orice agent care acceptă servere MCP locale. Programul de configurare pregătește
|
||||
[agenții acceptați](../installation.md#supported-agents); pentru ceilalți clienți
|
||||
poți folosi [înregistrarea manuală MCP](../installation.md#mcp-registry).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Am nevoie de Hopper, Ghidra sau IDA?</strong></summary>
|
||||
|
||||
Analiza nativă aprofundată folosește unul dintre aceste instrumente. Inspectarea
|
||||
statică JavaScript și .NET funcționează fără un motor de analiză nativă.
|
||||
Programul de configurare poate instala Hopper după aprobare; pentru Ghidra și IDA
|
||||
folosește instalările existente. Consultă [configurarea motoarelor de analiză](../installation.md#hopper).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Trebuie să pornesc mai întâi Hopper?</strong></summary>
|
||||
|
||||
REA pornește Hopper când o operație are nevoie de el. Pe macOS, un dialog afișat
|
||||
la prima pornire îți poate cere să alegi modul demonstrativ sau să activezi licența.
|
||||
Finalizează acel pas în aceeași sesiune de utilizator înainte de prima operație
|
||||
CLI/MCP sau de prima sarcină nesupravegheată. Deschide Hopper manual dacă este nevoie.
|
||||
Consultă [pornirea Hopper și depanarea](../installation.md#launcher-paths-and-troubleshooting).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Ce face instalarea skill-ului de pe skills.sh?</strong></summary>
|
||||
|
||||
Skill-ul oferă agentului instrucțiuni de investigare. Folosește `npx rea-agents setup`
|
||||
pentru a înregistra serverul MCP REA și a instala instrucțiunile corespunzătoare,
|
||||
apoi repornește agentul. Consultă [instalarea doar a skill-ului](../installation.md#skill-only-installation).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Ce cod returnează REA?</strong></summary>
|
||||
|
||||
Analiza nativă returnează pseudocod și cod de asamblare. Analiza JavaScript/Electron
|
||||
recuperează modulele și relațiile dintre ele. Agentul tău folosește aceste
|
||||
constatări pentru a scrie și testa o implementare;
|
||||
[studiile de caz](#studii-de-caz) oferă exemple detaliate.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>REA îmi încarcă aplicația pe un server?</strong></summary>
|
||||
|
||||
REA analizează țintele local. Agentul tău primește rezultatele uneltelor, iar
|
||||
furnizorul modelului său are propria politică privind datele.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Ce fac dacă întâlnesc o eroare?</strong></summary>
|
||||
|
||||
Actualizează mai întâi; o versiune recentă ar putea să o fi remediat deja.
|
||||
|
||||
Pentru o interfață CLI instalată cu `npm install --global` sau `bun add --global`:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
Pentru configurarea agentului prin `npx`:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
Dacă folosești un agent, finalizează [actualizarea configurării](#actualizează-rea)
|
||||
și repornește-l. Reîncearcă aceeași sarcină. Dacă problema persistă,
|
||||
[deschide un issue](https://github.com/morluto/rea/issues) și include versiunea REA,
|
||||
tipul țintei analizate, pașii de reproducere și mesajele de eroare.
|
||||
|
||||
</details>
|
||||
|
||||
## Documentație
|
||||
|
||||
Începe cu [ghidurile practice](https://rea.tools/guides/) de pe site.
|
||||
Pentru opțiunile exacte, cerințele preliminare și contractele rezultatelor:
|
||||
|
||||
- [Instalare și configurare](../installation.md): înregistrarea agenților, configurarea motoarelor de analiză, actualizări și dezinstalare.
|
||||
- [Verificarea pregătirii și depanare](../installation.md#check-readiness-for-your-task): diagnosticarea unui agent sau motor de analiză.
|
||||
- [CLI și Evidence](../cli.md): comenzi, selectarea motorului, instantanee, import/export și coduri de ieșire.
|
||||
- [Contracte MCP](../mcp-contracts.md) și [prompturi pentru agenți](../mcp-prompts.md): rezultatele uneltelor, sesiuni și investigații ghidate.
|
||||
- [Catalogul uneltelor](../mcp-contracts.md#generated-catalog): inventarul generat al uneltelor, motoarelor de analiză și comenzilor CLI.
|
||||
- [Plan de dezvoltare](../roadmap.md): lucrări planificate și urmărirea progresului funcționalităților.
|
||||
|
||||
Raportează vulnerabilitățile conform [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Istoricul stelelor
|
||||
|
||||
🎉 **300.000 de stele pe GitHub — vă mulțumim!**
|
||||
|
||||
Mulțumim tuturor celor care folosesc REA, raportează erori, propun funcționalități,
|
||||
testează versiuni și contribuie cu remedieri.
|
||||
|
||||
<a href="https://www.star-history.com/?repos=morluto%2Frea&type=date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date&theme=dark&legend=top-left" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
<img alt="Istoricul stelelor REA pe GitHub" src="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
## Precizări privind utilizarea
|
||||
|
||||
Consultă [DISCLAIMER.md](../../DISCLAIMER.md) pentru îndrumări privind utilizarea responsabilă.
|
||||
|
||||
Poziția proiectului față de utilizarea ilegală sau neautorizată se aplică tuturor
|
||||
versiunilor REA, canalelor de distribuție și platformelor; fiecare copie își
|
||||
păstrează licențele aplicabile.
|
||||
|
||||
REA este destinat cercetării legale, educației, interoperabilității, conservării
|
||||
software-ului și analizei programelor pe care le deții sau pe care ai autorizarea
|
||||
să le examinezi.
|
||||
|
||||
## Contribuții
|
||||
|
||||
Ne-ar bucura să contribui la REA! [Deschide un issue](https://github.com/morluto/rea/issues)
|
||||
pentru a raporta o eroare sau a propune o funcționalitate ori
|
||||
[trimite un pull request](https://github.com/morluto/rea/pulls) pentru a îmbunătăți
|
||||
codul sau documentația.
|
||||
|
||||
Consultă [CONTRIBUTING.md](../../CONTRIBUTING.md) pentru pregătirea mediului de dezvoltare
|
||||
și verificări, [ghidul de testare](../testing.md) pentru categoriile de verificări
|
||||
și [diagrama arhitecturii](../architecture.mermaid) pentru anumite straturi și
|
||||
relații de dependență.
|
||||
|
||||
## Licență
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
|
||||
Codul scris în cadrul REA este licențiat sub MIT. Materialele terților își păstrează
|
||||
propriile licențe și mențiuni privind drepturile de autor; consultă
|
||||
[mențiunile privind terții](../../THIRD_PARTY_NOTICES.md) pentru inventarul
|
||||
dependențelor, textele licențelor păstrate și condițiile aplicabile uneltelor externe.
|
||||
|
||||
**Trebuie să obții legal uneltele comerciale și să ai dreptul să le folosești**,
|
||||
inclusiv decompilatoarele IDA Pro / Hex-Rays, Hopper și JEB, în condițiile
|
||||
licențelor aplicabile. REA nu îți acordă nicio licență, cheie sau drept de activare
|
||||
pentru aceste unelte. Versiunile de evaluare și demonstrative rămân supuse
|
||||
condițiilor furnizorilor, inclusiv restricțiilor privind utilizatorii,
|
||||
funcționalitățile, automatizarea și partajarea rezultatelor. Nu sunt autorizate
|
||||
copiile piratate, cheile furate, partajarea neautorizată a cheilor sau ocolirea
|
||||
restricțiilor de licențiere. Aceste îndrumări nu modifică licența MIT sau licențele terților.
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Реверс-инжиниринг чего угодно
|
||||
|
||||
@@ -156,8 +156,11 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
|
||||
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](../recorded-crashes.md) |
|
||||
| Установленные настольные приложения | Возможные среды выполнения, файлы с доказательствами, компоненты и дальнейшие шаги | Ограниченная проверка каталогов и заголовков;[Настольные приложения](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -154,10 +154,13 @@ REA ต้องใช้ Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) หรื
|
||||
| ไบนารีเนทีฟ | โค้ดเทียม แอสเซมบลี สตริง สัญลักษณ์ การเรียก และการอ้างอิง | Hopper, Ghidra หรือ IDA; [การวิเคราะห์เนทีฟ](../native-investigation.md) |
|
||||
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](../recorded-crashes.md) |
|
||||
| ไดเรกทอรีติดตั้งแอปเดสก์ท็อป | รันไทม์ที่เป็นไปได้ ไฟล์หลักฐาน ตัวบ่งชี้ส่วนประกอบ และขั้นตอนถัดไป | ตรวจสอบไดเรกทอรีและส่วนหัวโดยจำกัดขอบเขต;[แอปเดสก์ท็อป](../desktop-applications.md) |
|
||||
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Her şeyi tersine mühendislikle inceleyin
|
||||
|
||||
@@ -154,7 +154,10 @@ REA; Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) veya 26+ (>=26.12.1) ve npm gere
|
||||
| Go ikili dosyaları | Gömülü compiler sürümü, modüller, replacement'lar ve build ayarları | Yerleşik statik ELF/PE/thin Mach-O incelemesi; Go kurulumu gerekmez |
|
||||
| Rust ikili dosyaları | Gömülü cargo-auditable crate adları, sürümleri, kaynakları ve bağımlılık ilişkileri | Yerleşik statik ELF/PE/thin Mach-O incelemesi; [Rust ikili dosyaları](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| WASM artefaktı | Doğrulama, bölümler, tam import/export WAT biçimleri ve decode edilmiş WAT | Çağıranın sağladığı WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| 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](../evm-bytecode.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Реверс-інжиніринг будь-чого
|
||||
|
||||
@@ -154,10 +154,13 @@ REA потребує Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) або 26+ (>=26
|
||||
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](../native-investigation.md) |
|
||||
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](../binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](../recorded-crashes.md) |
|
||||
| Встановлені настільні програми | Можливі середовища виконання, файли доказів, компоненти та наступні кроки | Обмежена перевірка каталогів і заголовків;[Настільні програми](../desktop-applications.md) |
|
||||
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · **Roman Urdu**
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · **Roman Urdu** · [Română](README_ro.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -196,11 +196,14 @@ Mazeed tools aur host support target par depend karte hain:
|
||||
| Godot PCK | Archive inventory aur extraction, original header/directory facts aur selected content identities | Built-in static formats 2, 3 aur 4; Godot zaroori nahi |
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources aur dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries aur PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import aur delay-load DLL names, ordinals, IAT RVAs aur pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id aur ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, imports, lambdas aur Code header | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| WASM artifact | Validation, sections, exact import/export WAT forms aur decoded WAT | Aapka diya hua WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments aur mutability | Linux x64 par local raw/hex carrier; [offline EVM guide](../evm-bytecode.md) |
|
||||
| SQLite databases | Tables, columns, indexes, views, triggers aur selected ordinary-table rows | Local database/WAL snapshot; native SQLite limits ke saath Node.js 24.x >=24.15 ya 26+ |
|
||||
| Apple IPS crash reports | Apple .ips metadata, threads, images aur crash classification | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Recorded Linux crashes | Raw notes, har recorded thread ke registers/signals aur optional mapping candidates | Linux x64 par aapka diya hua pwntools; optional GDB/pwndbg; [recorded crashes](../recorded-crashes.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC aur native add-on relationships | Node.js aur npm; Linux: procps-compatible `ps`; [application analysis](../javascript-application-workflows.md) |
|
||||
| Websites | Page structure, scripts, network observations aur requested screenshots | Chrome-family browser; [browser analysis](../browser-observation.md) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA: Kỹ thuật dịch ngược cho mọi thứ
|
||||
|
||||
@@ -156,8 +156,11 @@ REA yêu cầu Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) hoặc 26+ (>=26.12.1)
|
||||
| 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](../evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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](../recorded-crashes.md) |
|
||||
| Thư mục cài đặt ứng dụng máy tính | Các runtime có khả năng được dùng, tệp bằng chứng, dấu hiệu thành phần và bước tiếp theo | Kiểm tra thư mục và phần đầu tệp có giới hạn;[Ứng dụng máy tính](../desktop-applications.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](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -157,7 +157,10 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](../recorded-crashes.md) |
|
||||
| 桌面安裝目錄 | 執行階段候選、支持檔案、元件標記與後續操作 | 有界的目錄與檔頭檢查;[桌面應用](../desktop-applications.md) |
|
||||
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -157,7 +157,10 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](../recorded-crashes.md) |
|
||||
| 桌面安装目录 | 运行时候选、支持文件、组件标记和后续操作 | 有界的目录与文件头检查;[桌面应用](../desktop-applications.md) |
|
||||
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](../javascript-application-workflows.md); Linux: procps `ps` |
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
# Reconstruction readiness conformance
|
||||
# Reconstruction readiness verification
|
||||
|
||||
Run the source-owned native, JavaScript CLI, Electron, Evidence, comparison,
|
||||
obligation, replay, and cleanup conformance verifier from a clean checkout:
|
||||
Run the public static-analysis journeys and synthetic report-evaluator checks
|
||||
from a clean checkout:
|
||||
|
||||
```sh
|
||||
npm ci
|
||||
npm run verify:readiness
|
||||
```
|
||||
|
||||
The command builds the redistributable native conformance fixtures, inventories
|
||||
the native executable through the public CLI, analyzes the generated JavaScript
|
||||
CLI and Electron fixtures through both CLI and MCP, evaluates an internal
|
||||
nine-stage conformance report, and proves stale/tampered replay rejection. The
|
||||
report evaluator is part of the repository verifier, not a public REA tool. It
|
||||
prints one compact JSON summary.
|
||||
The command builds the redistributable native conformance fixtures, inspects
|
||||
the native executable through the public CLI, and analyzes the JavaScript CLI
|
||||
and Electron fixture sources through both CLI and MCP. It checks matching
|
||||
CLI/MCP Evidence identities for those two application analyses. The fixture
|
||||
applications are not executed, and native MCP parity is not exercised.
|
||||
|
||||
Separately, the command evaluates a wholly synthetic nine-stage input and
|
||||
checks evaluator determinism, Evidence tampering rejection, and stale-source
|
||||
digest rejection. These checks concern report evaluation; they do not establish
|
||||
application runtime behavior, authority recovery, cancellation cleanup,
|
||||
behavioral equivalence, or reconstruction closure for the analyzed fixtures.
|
||||
The command prints one compact JSON summary.
|
||||
|
||||
Set `REA_READINESS_REPORT_PATH` to retain the complete machine-readable report:
|
||||
|
||||
@@ -24,15 +30,37 @@ REA_READINESS_REPORT_PATH=readiness-report.json npm run verify:readiness
|
||||
CI runs this command on Linux, publishes the compact summary, and retains the
|
||||
full report as the `reconstruction-readiness` artifact.
|
||||
|
||||
## Project conformance contract
|
||||
## Report scope and ownership
|
||||
|
||||
The verifier runs as `npm run verify:readiness`; it is not exposed as a public
|
||||
CLI command or MCP tool. The synthetic report input and evaluator exist to
|
||||
check project-owned conformance fixtures and fail-closed report behavior.
|
||||
CLI command or MCP tool. Its report separates two kinds of verification:
|
||||
|
||||
## Required stages
|
||||
- `observed_journeys` retains the actual static-analysis Evidence and the
|
||||
observed CLI/MCP identity checks, with their coverage limits.
|
||||
- `evaluator_conformance` retains the synthetic baseline report and the
|
||||
evaluator checks. Its nine-stage `pass` describes acceptance of supplied
|
||||
synthetic observations.
|
||||
|
||||
| Stage | Required proof |
|
||||
The verifier's overall success means its listed checks passed. It is not an
|
||||
end-to-end reconstruction-readiness verdict. Actual analysis Evidence is not
|
||||
grafted into the synthetic report or used to close its checks.
|
||||
|
||||
The retained artifact now uses `schema: "ReconstructionReadinessVerificationReport"`
|
||||
and `schema_version: 1`. The previous unversioned artifact was the nine-stage
|
||||
evaluator report itself. Consumers should read the two explicit sections; the
|
||||
synthetic nine-stage report now lives at `evaluator_conformance.baseline_report`.
|
||||
Observed CLI and MCP Evidence are retained in separate bundles under
|
||||
`observed_journeys.evidence_bundles`, preserving each surface's records.
|
||||
|
||||
The evaluator, schemas, synthetic input, and semantic tests live under
|
||||
`tests/conformance/readiness/report/`. They are development verification code,
|
||||
excluded from the compiled runtime package. The evaluator authenticates Evidence
|
||||
commitments and checks supplied observations for consistency; it does not
|
||||
independently observe the events described by those observations.
|
||||
|
||||
## Synthetic evaluator stages
|
||||
|
||||
| Stage | Required supplied observations |
|
||||
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `discover-classify` | target-free startup, artifact inventory, compatible workflow selection, and exact visible limits |
|
||||
| `diagnose-environment` | broken runtime separated from analysis failure, version skew detected, and revision changed after recovery |
|
||||
@@ -44,13 +72,13 @@ check project-owned conformance fixtures and fail-closed report behavior.
|
||||
| `verify-reconstruction-closure` | incomplete reconstruction detected, incremental verifier closure, and authority-delegating candidates rejected |
|
||||
| `export-replay` | CLI/MCP parity, process/structured failure parity, deterministic replay, tamper rejection, and stale-input rejection |
|
||||
|
||||
Every stage and required check must occur exactly once and link to Evidence in
|
||||
the embedded Evidence bundle. `fail`, `unknown`, `unsupported`, `truncated`,
|
||||
and `skipped` never aggregate to `pass`.
|
||||
Within the synthetic input, every stage and required check must occur exactly
|
||||
once and link to Evidence in its embedded bundle. `fail`, `unknown`,
|
||||
`unsupported`, `truncated`, and `skipped` never aggregate to `pass`.
|
||||
|
||||
## Fail-closed rules
|
||||
|
||||
The evaluator rejects or withholds readiness when:
|
||||
The evaluator rejects or withholds a passing synthetic report when:
|
||||
|
||||
- a bounded capability omits its effective numeric limits;
|
||||
- a fixture lacks exactly one compatible selected workflow;
|
||||
@@ -63,8 +91,8 @@ The evaluator rejects or withholds readiness when:
|
||||
- contradiction Evidence or its affected comparison is missing;
|
||||
- the reconstruction obligation ledger is not `ready`, has no required
|
||||
obligation, or retains an unowned/unverified required obligation;
|
||||
- a process exceeds its declared target/lifecycle, cancellation loses diagnostics, or owned
|
||||
resources remain;
|
||||
- a denied or cancelled grant reports a process launch, a cancelled cleanup
|
||||
observation omits diagnostic Evidence, or owned resources remain;
|
||||
- replay is nondeterministic, tampering/staleness is not detected, or the
|
||||
expected source digest differs.
|
||||
|
||||
@@ -95,19 +123,27 @@ Differing transport status is checked on each observation separately.
|
||||
|
||||
## Fixtures
|
||||
|
||||
The verifier uses only source-owned, redistributable fixtures:
|
||||
The static-analysis journeys use source-owned, redistributable fixtures:
|
||||
|
||||
- `tests/conformance` native executables with stable symbols and deliberate
|
||||
version divergence;
|
||||
- `build/conformance/c`, built from `tests/conformance/c/fixture.c`, with stable
|
||||
symbols and strings;
|
||||
- `tests/conformance/readiness/javascript-cli`, which exposes prompts,
|
||||
alternate-screen behavior, configuration precedence, child process,
|
||||
persistence, loopback HTTP, and signal teardown to static reconstruction;
|
||||
- `tests/conformance/readiness/electron`, which exposes main, preload,
|
||||
renderer, utility, IPC, renderer restart, blocked shell effect, and deep-link
|
||||
surfaces;
|
||||
- the shared incomplete reconstruction and broken-runtime observations in
|
||||
`RECONSTRUCTION_READINESS_EXAMPLE`.
|
||||
surfaces to static analysis.
|
||||
|
||||
The synthetic example is a public typed input, not a global equivalence claim.
|
||||
It demonstrates that every deliberate fault remains represented in the final
|
||||
report and that only comparable Evidence can close the associated obligation.
|
||||
The separate `RECONSTRUCTION_READINESS_EXAMPLE` supplies synthetic incomplete
|
||||
reconstruction, broken-runtime, authority, comparison, cleanup, and closure
|
||||
observations. Its semantic tests preserve malformed-Evidence rejection,
|
||||
fail-closed stage results, contradiction handling, repeated CLI/MCP outcomes,
|
||||
and closure-history consistency. Run those source tests independently:
|
||||
|
||||
```sh
|
||||
npm run test:local -- tests/conformance/readiness/report/reconstructionReadiness.test.ts
|
||||
```
|
||||
|
||||
Passing evaluator tests does not establish real-provider or fixture runtime
|
||||
behavior. Use the applicable [real-toolchain lanes](testing.md#real-toolchain-verification-lanes)
|
||||
for those claims.
|
||||
@@ -1,7 +1,8 @@
|
||||
# Recorded crash evidence
|
||||
|
||||
`inspect_recorded_crash` / `rea inspect-recorded-crash` inspect a caller-selected
|
||||
Linux ELF64 little-endian core independently of an active binary target. Two
|
||||
Linux ELF64 little-endian core independently of an active binary target. Apple
|
||||
`.ips` crash reports use the separate [Apple IPS](apple-ips.md) workflow. Two
|
||||
architecture profiles are interpreted, x86-64 and AArch64; each binds registers
|
||||
to its own `NT_PRSTATUS` layout, and any other `e_machine` is refused as
|
||||
`unsupported_target` before note interpretation.
|
||||
|
||||
@@ -90,6 +90,33 @@ releases are outside this recovery path.
|
||||
For a release that needs an independently frozen application checkpoint, use
|
||||
the optional manual path below. It retains explicit prepare and publish phases.
|
||||
|
||||
Automatic main proposals and manual checkpoint preparation use
|
||||
`scripts/release-proposal.mjs` with the pinned release-please dependency.
|
||||
The controller applies `patches/release-please+17.3.0.patch` only when invoked;
|
||||
normal dependency installation and published-package installation do not apply it.
|
||||
The patch avoids commit-file backfills, associated PR file lists and path splitting
|
||||
for a single root Node package with the default changelog, default or
|
||||
always-bump-minor versioning, no path exclusions and no explicit plugins. Other
|
||||
configurations retain the upstream file attribution workflow. Commit history and
|
||||
associated PR metadata still come from GitHub: release notes need the commits,
|
||||
and `BEGIN_COMMIT_OVERRIDE` needs the merged PR body. Skipped file lists remain
|
||||
unknown rather than being reported as empty. The controller sizes commit search
|
||||
from the complete selected Git history, and a missing known release boundary
|
||||
fails before proposal creation.
|
||||
|
||||
History-page reads retry GitHub's canonical internal GraphQL response error within
|
||||
the existing five-retry budget and exponential backoff. Each retry uses the same
|
||||
cursor; permission, validation and mixed errors fail immediately. Exhaustion
|
||||
stops preparation before proposal writes. The controller does not restart proposal
|
||||
creation or retry mutations. An internal GraphQL error does not establish API
|
||||
quota exhaustion or prove that query size caused the failure. Publication
|
||||
continues through the pinned release-please action.
|
||||
|
||||
When upgrading release-please, review the upstream manifest implementation,
|
||||
refresh the versioned patch and run the release proposal and workflow boundary
|
||||
tests. Version mismatch or a patch that neither applies cleanly nor matches an
|
||||
already-applied patch fails closed.
|
||||
|
||||
## Contributor-aware release notes
|
||||
|
||||
Use [the rea-changelog-update skill](https://github.com/morluto/rea/blob/main/.agents/skills/rea-changelog-update/SKILL.md)
|
||||
|
||||
@@ -42,6 +42,12 @@ Captured stdout and stderr are retained up to a 16 MiB combined limit; `output_t
|
||||
|
||||
Persistent GDB sessions, including the MCP workflow and one-shot `rea debug-with-gdb` CLI, are available only on Linux. REA verifies a live inferior's output descriptors through `/proc` before detaching it; it does not claim equivalent descriptor verification on macOS. Windows is also unsupported because owned Job Object cleanup can terminate debugger inferiors. On supported Linux hosts, `start_gdb_session`, `gdb_console`, `gdb_session_status`, and `close_gdb_session` manage a persistent GDB/MI session in MCP. The one-shot CLI requires a caller-selected durable TTY: `rea debug-with-gdb --inferior-tty /dev/pts/7 'file ./program'`. The TTY must remain available after GDB exits so a detached inferior can continue writing. MCP starts GDB with `--nx --quiet --interpreter=mi3`, retries initialization with MI2 if MI3 initialization returns an error and cleanup succeeds, waits for its prompt, and disables auto-loading. Pass optional `inferior_tty` to select the terminal that future inferior runs use; REA configures it before the session becomes ready and checks the exact value with GDB/MI. `gdb_session_status` reports the selected path, whether REA still considers the configuration verified, and whether invalid UTF-8 has been observed in MI bytes (`mi_invalid_utf8`) or stderr (`stderr_invalid_utf8`). Commands that can change the inferior TTY or redirect a run revoke that verification permanently for the session, so close retains GDB ownership if a live inferior remains. The complete built-in inspections `show inferior-tty` and `help inferior-tty` preserve verification; compound commands still use the conservative mutation checks. Closing a session with one live inferior and a verified TTY automatically detaches the target, which can resume execution; MCP clients receive destructive-operation annotations for this behavior. The console remains unrestricted and can run shell commands, change target state, access files, and use network in the REA process user's security context. Raw MI records and console/target/log streams are returned with Evidence; command output is retained up to 16 MiB and explicitly marked when truncated. GDB startup waits 10000 ms and each MI command waits 120000 ms. This release has no runtime override for those deadlines, the 16 MiB command output budget, session capacity, or the pending-command queue. `command_timeout_ms` does not change them.
|
||||
|
||||
With multiple live inferiors, or a live inferior without a verified TTY, manual
|
||||
close requests an explicit disposition and keeps the session ready. Use
|
||||
`gdb_console` to select and explicitly detach or terminate each remaining
|
||||
inferior, then retry `close_gdb_session`. After owned cleanup has started,
|
||||
console commands remain unavailable while that cleanup can be retried.
|
||||
|
||||
`completion_status` describes completion of the selected console command, not
|
||||
termination of its inferior. After a `^running` result, REA queues a read-only
|
||||
`-gdb-show mi-async` query and waits for its tokenized reply before releasing the
|
||||
@@ -88,6 +94,14 @@ Captured stdout and stderr are retained up to a 16 MiB combined limit; `output_t
|
||||
## Cutter bridge
|
||||
|
||||
Cutter commands use the local REA Python bridge and authenticated loopback messages.
|
||||
Discovery reads the session descriptors that the plugin publishes in the bridge
|
||||
directory. Set `REA_CUTTER_BRIDGE_DIR` in both REA's environment and the environment
|
||||
that starts Cutter to select a custom directory. Both expand `~` and `~/` paths
|
||||
against the current user's home, including `~\` paths on Windows. By default,
|
||||
they use `%LOCALAPPDATA%\REA\CutterBridge` on Windows when `LOCALAPPDATA` is set,
|
||||
and `~/.cache/rea/cutter-bridge` otherwise. The two processes must resolve the
|
||||
same directory for discovery to find the published sessions.
|
||||
|
||||
The client and plugin must support the current v2 handshake; older peers are
|
||||
rejected before dispatch because they cannot preserve cross-caller recovery proof.
|
||||
The client checks the final encoded request against
|
||||
|
||||
@@ -83,7 +83,8 @@ empty dependency set. Retained views describe the captured artifact digest;
|
||||
they do not assert that the current file or running application is unchanged.
|
||||
|
||||
ELF section names are resolved through the section-header string table.
|
||||
Zlib-compressed name tables are decoded within the native structural budget.
|
||||
Zlib- and Zstandard-compressed name tables are decoded within the native structural
|
||||
budget. Zstandard decoding also uses a 128 MiB window limit.
|
||||
If a name table uses unsupported compression, the result reports that
|
||||
limitation and leaves `.dep-v0` presence unknown rather than reporting the
|
||||
section absent.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Plan
|
||||
|
||||
1. Add `environmentCoverageView.ts`: the request schema, the result fields, the
|
||||
hint per write reason (`satisfies Record<WriteReason, string>`), a
|
||||
summarizer over state views and write plans, and the projector, which
|
||||
projects the environment-state view and summarizes it. Register the kind in
|
||||
the view unions, the grouping dispatch and the view service (state
|
||||
accumulator, inferred confidence).
|
||||
2. Split the export's input read into `readEnvironmentExportFile` and
|
||||
`environmentExportFile` (parse and seal bytes), both naming the calling
|
||||
operation, and let the export take an already prepared state.
|
||||
3. Add `environmentBuild.ts`: classify the capture, project the manifest from
|
||||
the in-memory Evidence, serialize it as `--format json` writes it to a file,
|
||||
authenticate the pair from those bytes, name the environment, prepare the
|
||||
state as the export does, summarize coverage, scan credential names, then
|
||||
plan (dry run) or export. `environmentBuildReport.ts` holds the scan and the
|
||||
naming helpers.
|
||||
4. Register `environment-build` in the CLI: inspect a HAR through the capture
|
||||
service as `inspect-web-network-capture` does, or read Evidence once as the
|
||||
export does, and log stages at info.
|
||||
5. Switch `scripts/verify-agentenv-environment.mjs` to the build command.
|
||||
6. Document the command, the report, the hints, what ships, and the view.
|
||||
7. Tests: coverage summary and hint completeness, the view against the state
|
||||
view, build equivalence with the three-step path in process and through the
|
||||
CLI, dry run, naming, refusals, the credential scan, and the view over MCP.
|
||||
@@ -0,0 +1,96 @@
|
||||
# Build an environment in one step
|
||||
|
||||
Issue: https://github.com/morluto/rea/issues/4933
|
||||
|
||||
## Outcome
|
||||
|
||||
Building an agent environment bundle takes three commands and a hand-written
|
||||
view request that embeds the whole capture inline, so large captures hit inline
|
||||
input accounting. The views apply no opt-in template rules by default, while the
|
||||
published capture-built environments all use the same four, and a local capture
|
||||
is named after its origin host (`127-0-0-1-3105`). Nothing reports which tools
|
||||
an environment serves from its state, or why a write tool is withheld.
|
||||
|
||||
`rea environment-build <capture> [directory]` builds the bundle in one offline
|
||||
step and reports what it serves. A new `environment-coverage` analysis view
|
||||
reports the same summary for any capture, so an agent can check a recording
|
||||
before building.
|
||||
|
||||
## Requirements
|
||||
|
||||
- The capture is a `.har` file, inspected as `inspect-web-network-capture`
|
||||
inspects it, or capture Evidence JSON from `inspect_web_network_capture` or
|
||||
`capture_browser_scenario`; any other extension is refused before it is
|
||||
read, and a HAR document saved as `.json` is refused with a hint.
|
||||
- The manifest is projected from the in-memory capture as retained Evidence,
|
||||
with the default rules `after-uid-literal`, `opaque-token`,
|
||||
`sibling-variance` and `prefix-variance` unless `--template-rule` or
|
||||
`--format-rules-only` selects others; rules apply in the views' order and a
|
||||
repeated rule is refused, as the views refuse it.
|
||||
- For the same capture path, every bundle file is byte-identical to what
|
||||
`inspect-web-network-capture --format json`, `inspect-analysis-view --format
|
||||
json` (the same rules in the views' order) and `environment-export` (the
|
||||
build's name) write, Evidence ids included. The Evidence is serialized once
|
||||
into one exactly sized buffer, whose bytes are both authenticated and shipped.
|
||||
- The name is `--name`, else the manifest's, unless the origin is a loopback
|
||||
name or IP literal: then the capture file's name, with a warning; a file name
|
||||
that yields no portable bundle name is refused, asking for `--name`.
|
||||
- The report carries the export's tool count, state, package source and files,
|
||||
plus the capture and manifest identities, `coverage`, warnings and the next
|
||||
command, shell-quoted. `coverage`
|
||||
counts read tools answered from the state and replayed (per view reason), and
|
||||
lists write tools as served or withheld with their reason, plan record, the
|
||||
contradicting read and a hint; it is null when the state is unavailable.
|
||||
- Every write reason has a hint; a reason without one fails to compile.
|
||||
- Credential-named header names, query parameter names and JSON or form body
|
||||
members that hold a value are reported as a count and the first 20 record or
|
||||
event pointers, never values, and never refuse a build; the scan cannot
|
||||
overflow the stack on deeply nested bodies. A body is read as a form
|
||||
(`application/x-www-form-urlencoded`, by `URLSearchParams`) or as JSON (the
|
||||
media types replay parses as JSON) by its recorded media type; a body with
|
||||
none, or one naming neither, is JSON when it starts with `{` or `[` and a form
|
||||
when it contains `=` and no whitespace, so plain text and empty bodies yield
|
||||
no pointers. A browser scenario is scanned by event rather than by record:
|
||||
every retained request and response network-content event's header values and
|
||||
body, including a response whose request began before the browser was attached
|
||||
and a transaction that cannot be attributed to one request and response, and
|
||||
each transaction URL's query parameters once; its pointers name the event's
|
||||
index in `events.items` (`event 4 response /token`). Each occurrence of a
|
||||
repeated form field counts, as each repeated header or query parameter does. A
|
||||
HAR request recorded with structured form parameters and no text, or the null
|
||||
text mitmproxy's SaveHar records, is scanned by those parameters. Text bodies
|
||||
over the 4 MiB scan limit, measured in UTF-8 bytes, including a response body
|
||||
decoded only as a prefix, are not scanned; they are reported as a
|
||||
`credential-scan-incomplete` warning with a count and the first 20 record or
|
||||
event and side pointers (`record 3 response`, `event 4 response`), never
|
||||
contents, and never refuse a build. Binary bodies hold no JSON or form text
|
||||
and are neither scanned nor reported.
|
||||
- The inspected HAR's Evidence and the projected manifest are admitted against
|
||||
the live heap headroom for parsing and sealing before either is serialized, as
|
||||
a capture Evidence file is before it is read; one that does not fit is refused
|
||||
as `resource_constraint` before anything is written.
|
||||
- An empty or NUL-containing capture, directory or package tarball argument is
|
||||
refused as invalid input; it is never resolved to the working directory.
|
||||
- Nothing is written before the bundle stage; `--dry-run` writes nothing,
|
||||
reports the files a build would write and refuses the package tarballs a build
|
||||
refuses, admitting, reading and hashing, and releasing the tarball as a build
|
||||
does before copying it, so a tarball whose contents cannot be read is refused:
|
||||
a close it cannot confirm is reported as incomplete cleanup that keeps its
|
||||
owner. The directory must be absent or empty.
|
||||
- SIGINT is checked between stages and after a dry run's last step: a build
|
||||
cancelled before the bundle stage writes nothing, and one cancelled during the
|
||||
write names the written bundle.
|
||||
- The `environment-coverage` view summarizes the environment-state view with
|
||||
the same rules, refuses what it refuses and is inferred. It does not apply the
|
||||
serve-time catalog and state admission checks, and says so in a limitation.
|
||||
- The `real-agentenv` lane builds its bundle with `environment-build`.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- No change to the three existing commands' contracts, or to what any view
|
||||
derives or any environment serves.
|
||||
- No browser launch or network access: scenarios are recorded with
|
||||
`capture-browser-scenario` first.
|
||||
- No `--replace`, no refusal on credential names, and no rewriting of the
|
||||
capture's absolute path, which Evidence identity includes.
|
||||
- No MCP export tool; that is a separate change.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Tasks
|
||||
|
||||
- [x] Record the outcome, requirements and non-goals.
|
||||
- [x] Add the environment-coverage view and register it.
|
||||
- [x] Split the export's input read and accept a prepared state.
|
||||
- [x] Add the build module, its report helpers and the CLI command.
|
||||
- [x] Switch the real-agentenv lane to the build command.
|
||||
- [x] Document the command, the report, the hints and the view.
|
||||
- [x] Add domain, service, CLI and MCP tests.
|
||||
- [x] Run static, formatting, duplication, documentation and test gates.
|
||||
- [x] Build the 50 published captures and compare them with the three-step path.
|
||||
- [x] Build environments end to end on Linux VMs and run them with agents.
|
||||
- [x] Address the independent review.
|
||||
@@ -0,0 +1,113 @@
|
||||
# Verification
|
||||
|
||||
Executed on macOS with Node v24.22.1 (the checkout's `.nvmrc`) on main `3d4f5565`, and on Ubuntu 24.04 VMs for the
|
||||
end-to-end runs.
|
||||
|
||||
## Gates
|
||||
|
||||
- `npm run -s check:fast`, `npm run -s format:check`, `npx knip`, `npm run -s scan:todos`, `npm run -s docs:check`,
|
||||
`npm run -s verify:test-discovery` and `npm run -s mcp-catalog:check`: passed.
|
||||
- `npm run jscpd`: 3.52% duplicated lines over 4348 files, as on main (3.52% over 4341).
|
||||
- `npx vitest run --project domain --project services`: 9537 passed, 6 skipped and 151 failed. The same 151 fail on main
|
||||
`3d4f5565` in this environment (9513 passed there); none is new.
|
||||
- `npm run -s test:prepare`, then `npm run -s test:focused --` the environment build, export, export-inputs and serve CLI
|
||||
boundaries, the analysis-view CLI and MCP boundaries and the environment serve MCP boundary: 7 files, 67 passed and 1
|
||||
failed, "projects portable artifact inventory after the original ZIP is removed", which fails the same way on main.
|
||||
- `npm run verify:agentenv:environment` (the `real-agentenv` lane) passed on Ubuntu 24.04 with `agent-env 0.9.1334`.
|
||||
|
||||
## Equivalence and coverage over the published captures
|
||||
|
||||
Each of the 50 published capture-built environments' captures (capture Evidence JSON) and four scoped HAR recordings
|
||||
(EspoCRM, Ghost, NocoDB, Sonarr) was built twice: once with `rea environment-build <capture> <dir> --json`, and once
|
||||
with the three CLI steps, `inspect-web-network-capture --format json` (HAR only), `inspect-analysis-view` with an
|
||||
`evidence-file` source and the four default rules, and `environment-export --name <the build's name>`. Every file of
|
||||
every bundle was compared by SHA-256.
|
||||
|
||||
| Inputs | Bundles identical | State served | Read tools from state / replayed | Write tools served / withheld | Build / three steps |
|
||||
| ------------------------- | ----------------- | ------------ | -------------------------------- | ----------------------------- | ------------------- |
|
||||
| 50 capture Evidence files | 50 of 50 | 50 | 1,100 / 290 | 50 / 143 | 32.9 s / 59.2 s |
|
||||
| 4 scoped HARs | 4 of 4 | 4 | 166 / 21 | 5 / 12 | 8.3 s / 12.4 s |
|
||||
|
||||
- The coverage of every capture equals an independent census of the environment-state view with the same rules (read
|
||||
views by shape, write plans by verdict and reason).
|
||||
- 43 of the 50 captures have a loopback origin and are named after their file (`grafana.capture.json` becomes `grafana`)
|
||||
with a `name-from-file` warning. 20 carry a `credential-named-members` warning; the published captures were scrubbed by
|
||||
their pipeline, whose placeholder strings still count.
|
||||
- The withheld writes' reasons: no-state-target 86, contradicted 16, unconfirmed 14, no-observation 13,
|
||||
unexplained-change 8, side-effect 4, body-unusable 1, incomplete-entities 1.
|
||||
|
||||
## End to end
|
||||
|
||||
Five environments last rebuilt on 10-23 were built again with this branch's packed CLI on disposable Ubuntu VMs, four
|
||||
from their scoped HAR recordings and Metabase from its capture Evidence, with `rea environment-build <capture> <dir>
|
||||
--name <app> --package-tarball <tarball>`. Each bundle then ran its smoke task, a retrieval eval generated from the
|
||||
bundle's own manifest and capture, and the write eval from its recorded write spec, with two models through a LiteLLM
|
||||
proxy (`fireworks_ai/gpt-oss-120b`, `fireworks_ai/glm-5p3-flash`), one run per task.
|
||||
|
||||
| App | Input | Served tools of manifest | Served writes (build report) | Smoke | Retrieval gpt-oss / GLM | Writes gpt-oss / GLM |
|
||||
| -------- | -------- | ------------------------ | -------------------------------------------------- | ------ | ----------------------- | -------------------- |
|
||||
| Ghost | HAR | 35 of 38 | 0 (3 no-state-target) | passed | 12/12 / 8/12 | 0/2 / 0/2 |
|
||||
| Metabase | Evidence | 40 of 42 | 1 (create contradicted, update unexplained-change) | passed | 12/12 / 12/12 | 1/2 / 1/2 |
|
||||
| EspoCRM | HAR | 85 of 88 | 0 (2 contradicted, 1 unexplained-change) | passed | 12/12 / 10/12 | 0/2 / 0/2 |
|
||||
| NocoDB | HAR | 23 of 28 | 0 (4 no-state-target, 1 unconfirmed) | passed | 6/6 / 5/6 | 0/3 / 0/3 |
|
||||
| Sonarr | HAR | 49 of 50 | 5 (1 side-effect) | passed | 12/12 / 12/12 | 3/3 / 3/3 |
|
||||
|
||||
- Every write task passed with both models when the build report listed its tool as served (Metabase's card delete and
|
||||
Sonarr's release-profile create, update and delete), and failed when it listed it as withheld: 8 of 24 write episodes
|
||||
passed, exactly the served ones. On main these apps' other writes are withheld; the published v0.2.0 versions were
|
||||
built with the state-target and write-rule changes, which serve more of them.
|
||||
- The retrieval misses are GLM answers on bundles byte-identical to the three-step path's; gpt-oss passed all 54.
|
||||
- The `real-agentenv` lane, switched to `environment-build`, passed from a fresh checkout on Ubuntu with
|
||||
`agent-env 0.9.1334` and the host's Docker: five public cases, the smoke task passed in 26.6 s, no new containers.
|
||||
|
||||
## Review
|
||||
|
||||
An independent review rebuilt the branch and tried to refute it. It confirmed byte-equality for pretty-printed,
|
||||
CRLF and newline-free Evidence, Unicode HARs across output part boundaries, inline and file view sources, browser
|
||||
scenario Evidence and relative or symlinked paths, and that the refactored export answers 16 success and refusal cases
|
||||
exactly as main does. Its findings, all addressed:
|
||||
|
||||
- The credential scan recursed and a 4 KB body nested 5,000 deep crashed the build; it now walks with its own stack, and
|
||||
also scans header names, query names and form bodies.
|
||||
- SIGINT after the capture was read was ignored; the build now checks the signal between stages and writes nothing when
|
||||
cancelled before the bundle stage.
|
||||
- The coverage view does not apply the serve-time catalog and state admission checks; a limitation and the docs now say
|
||||
so.
|
||||
- A dry run accepted a tarball the build refuses; it now opens it for reading.
|
||||
- Repeated `--template-rule` values were deduplicated; they are refused as the views refuse them. A HAR saved as `.json`
|
||||
gets a hint, file-derived names follow the bundle name rules, `localhost.` is anonymous, and the next command is
|
||||
shell-quoted.
|
||||
- The `no-observation` hint now covers updates and deletes of entities the state never held; the docs no longer claim
|
||||
the build launches no process, state the conditions of byte-equality, and name the headers inspection excludes; the
|
||||
MCP tool description names the view.
|
||||
|
||||
## Review round on main `584120e8`
|
||||
|
||||
The branch merged main `584120e8`: the export's file read now returns permission refusals through `Result`, as main
|
||||
does, under the build's operation name, and the `environment-coverage` sentence sits in main's `inspect_analysis_view`
|
||||
description. Four automated review findings were fixed, each with a test that fails on the merge:
|
||||
|
||||
- A browser scenario's retained header values and the query parameters of its recorded URLs are scanned for credential
|
||||
names as a HAR's are; the manifest and replay record projections are unchanged.
|
||||
- `--dry-run --package-tarball` admits and releases the tarball through the export's own regular-file scope, so a close
|
||||
it cannot confirm is retried and then reported as incomplete cleanup that keeps its owner.
|
||||
- A dry run checks for cancellation after reading the tarball, before it reports a plan.
|
||||
- Evidence is serialized into one exactly sized buffer instead of chunks joined by a copy. Those bytes are still parsed
|
||||
and sealed before authentication, so authentication reads exactly what ships.
|
||||
|
||||
On macOS with Node v22.23.1: the static gates passed (`npm run jscpd`: 3.53%), `npx vitest run --project domain
|
||||
--project services` passed (9753, 6 skipped), the environment boundary projects passed (102), and the focused build,
|
||||
export, export-inputs, serve and analysis-view boundaries with tool schema validity passed (9 files, 96). Rebuilt over
|
||||
the same 50 captures and four HARs, all 54 bundles are byte-identical to the three-step path's, with the same coverage,
|
||||
served writes and warnings as before the round.
|
||||
|
||||
## Review round on main `3d84215b`
|
||||
|
||||
The branch merged main through `3d84215b`: #6946, which carries this builder, in `27a4e3986`, then #7008. Integrating
|
||||
#6946 took main's event-based credential scan, which also answers the review finding that a scenario transaction with
|
||||
duplicate responses or content events hid their credential names; a test that both content events of a transaction
|
||||
recorded twice are scanned fails on `0895c89bc`. The integration had dropped `0895c89bc`'s tests for form text recorded
|
||||
without a media type and its `body-unusable` hint; both are restored, and main's scan passes the tests.
|
||||
|
||||
Rebuilt at `05566419e` over the same 50 captures and four HARs, all 54 bundles are byte-identical to the three-step
|
||||
path's, and their warnings and credential counts equal the previous round's.
|
||||
Loaded 100 of 2084 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user