* feat(native): admit raw binaries with caller-supplied architecture and entry
* fix(native): honor raw-binary preparation and entry identity
* fix(ghidra): stream raw snapshot attestation with cancellation
* fix(native): preserve and validate raw lifecycle entries
---------
Co-authored-by: morluto <[email protected]>
Return the exact static initializer disassembly before Java projection can
lose field assignments. Retain byte limits and representation markers, and
verify fully folded and mixed initialization through the real CLI/MCP lane.
Closes#1846
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <[email protected]>
Share CLI boundary module evaluation in bounded forks while preserving fresh command instances and child processes. Keep module-mocked cleanup tests and source/compiled product catalog verification isolated, and update focused artifact selection.
Flameox full cohort with V8 coverage: 102.8s to 96.6s; 290 passed and two existing skips. Statement, function and branch coverage maps and hit sets match across all 1,153 source files. After syncing main, 75 focused tests, typecheck, lint, docs checks and formatting pass; all 834 test files are discovered exactly once.
* feat(harmony): project HarmonyOS package inventory evidence
First HarmonyOS increment from #1431: HAP, HSP, and App Pack roots are
classified through the hardened ZIP reader and projected into an
execution-free application graph with packaging-model hints, exact
component paths and hashes, App Pack children by path, runtime-family
hints, and path-based N-API bridge hypotheses. HarmonyOS .har stays
unclassified by suffix because .har also names HTTP Archive JSON.
Adds the project_harmony_application_graph tool (CLI and MCP), synthetic
composition coverage, a pinned real-package verify lane, and docs.
* refactor(domain): share application graph projection scaffolding
The HarmonyOS projection mirrors the Android and Apple projections by
design, which pushed jscpd duplication over its 2.5 percent budget.
Extract the identical pieces (inventory input schema, projected
component schema and occurrence flattening, bridge candidate schema
factory, coverage assembly, comparator, canonical digest) into
domain/mobileApplicationGraphProjection.ts and route all three
projections plus the composition fixtures through it. Duplication drops
from 2.52 to 2.49 percent with no behavior change: projection ids,
classifications, and limitations are byte-identical.
* fix(harmony): address review, stable app-pack roots, and rotated fixture
- rebased onto main; the shared projection scaffolding now keeps main's
nativeRuntimeConvention loop and the harmony runtime families adopt the
same react-native/flutter/unity path conventions
- the .app App Pack suffix is now a root-input rule only (verified ZIP
magic in classifyRootFormat and BinaryTargetResolver); nested .app ZIP
members inside other packages keep the generic zip classification, with
a regression test, so existing inventories do not change
- the signing limitation now states that an empty signing list does not
mean unsigned because packaging-tool signatures live in the ZIP signing
block, and the app-pack root rule is disclosed as suffix-based
- repinned the real-package fixture to the current VHome 2.6.14-beta asset
after the upstream deleted v5.0.111-beta and replaced the v2.6.14-beta
asset within hours; the pin records both observed digests
---------
Co-authored-by: morluto <[email protected]>
* feat(ghidra): admit bounded PSP ELF through installed Allegrex
Build on merged generic MIPS without weakening its policy. Bind caller-installed processor files into the analysis profile, check them again before launch, force and verify PSP language selection, retain limitations, and extend the public CLI/MCP verifier with source-owned PSP and target-switching checks. Local actual focused Vitest: 102 passed, one existing permission skip. Hosted static and real-provider results are pending.
* fix(ghidra): validate PSPSDK ABI records in PSP admission
* test(ghidra): bind PSP ABI verification to snapshot profiles
* test(ghidra): declare independent PSP ABI reader contract
* test(ghidra): retain the PSP fixture discriminated type
* test(ghidra): contextually type PSP metadata as the MIPS target variant
* test(ghidra): keep carved firmware checks scoped to generic MIPS fixtures
* style(ghidra): format PSP language-override guard
* style(test): format PSP language override regressions
* fix(ghidra): bound PSP extension enumeration before allocation
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: morluto <[email protected]>
* fix(bun): report the real runtime and enforce worker memory budgets on Windows
Under Bun, REA recorded Node/V8 identity it did not observe and its JavaScript helper processes ran without a memory bound, because Bun ignores the V8 heap flags REA passes. Source-map trace Evidence claimed runtime node-v8 with Bun's synthetic V8 heap limit (the decoder then rejected that limit, so trace_web_source_location always failed), analysis resource failures reported heap limits Bun does not enforce, the HAR decoder claimed a fixed 192 MiB heap, and doctor reported Bun's Node.js compatibility version as the Node version.
Identify the runtime once from process.versions. Source-map reports record id bun with the Bun and Node.js compatibility versions and a null v8_heap_limit_bytes; the decoder checks the heap budget only for V8 reports and rejects a report from a runtime other than the launching one. The analysis worker reports a null heap limit under Bun, HAR limitations and failures omit heap sizes under Bun, and the doctor node check reports Bun and passes when its Node.js compatibility version is supported.
On Windows under Bun, each helper's owned Job Object now carries a commit limit of its heap budget plus a measured 512 MiB Bun runtime reserve (704 MiB for the codec and HAR decoder, 1536 MiB for the default analyzer). The native addon accepts an optional page-aligned job memory limit on process_spawn, verifies it by readback, associates a private completion port before the child is created, and reports a sticky memoryLimitReached and peak job commit on each poll; inspect reports jobMemoryLimit. A requested limit with an artifact lacking the control refuses the launch, and non-Windows launchers refuse a limit.
Reaching the limit is classified by the job notification rather than Bun's exit status: the analyzer fails the current source with a memory resource failure reporting worker_process_memory_limit_bytes, the codec returns a memory resource failure, and the HAR decoder returns its memory failure with process_memory_limit_bytes. Bun source-map Evidence records process_memory_limit_bytes, verified against the launcher. Node.js launches and outputs are unchanged.
* fix(windows): drain memory notifications after observing exit
---------
Co-authored-by: morluto <[email protected]>
* feat(javascript): recover code-split bundles from multiple inputs
recover_javascript_sources accepted a single path, and
validateModuleSet bound every module's provenance to that one snapshot.
A code-split app (runtime + chunks, or an Electron main/preload/renderer
set) had to be recovered one file per call, and modules recovered alone
could not resolve imports across chunks: cross-chunk require(id)
references stayed as numeric ids with property reads.
Add an optional additional_paths input. The listed files are
concatenated, in order after path, into the single engine snapshot, so
one Wakaru run sees every module and cross-chunk imports resolve.
validateModuleSet's single-snapshot binding is unchanged. Module
provenance is attributed back to the input file its first extraction
range starts in, with byte ranges rebased to that file's own offsets;
a module whose ranges cross an input boundary keeps the concatenated
snapshot identity and offsets, recorded as an explicit limitation.
Single-path behavior is byte-for-byte unchanged (one segment,
offset 0).
Fixes#1605
* fix(javascript): preserve source identity in multi-input recovery
---------
Co-authored-by: JingHao-Leon <[email protected]>
Co-authored-by: morluto <[email protected]>
Use the website language inventory when comparing README links. Accept the matching localized page while retaining checks for wrong locales, changed destinations, fragments and query parameters.
Adapt CJK font stacks, original copy-button label restoration, accessibility wording and Traditional Chinese onboarding improvements from PR #1737. Protect the complete APK filename and correct setup terminology.
Co-authored-by: Kaoru0822 <[email protected]>
Join the admitted parent and generated child name without duplicating a drive-root separator. Reuse that name for handle-relative creation and path provenance.
Add native snapshot, readback, and cleanup coverage through the Ghidra dot-prefixed temp fallback, plus a session-root contract regression.
Fixes#1690
fix(windows): resolve Node-API imports from the host executable
Delay-load the Node-API import library and bind "node.exe" to the running
process, matching node-gyp's win_delay_load_hook. The addon now loads under
any Node-API host (Node.js, Bun) regardless of its executable file name.
Keep the configured launcher alive while its limited Python child runs so ownership checks retain the admitted executable identity. Trigger memory exhaustion with one oversized ELF zero-fill tail rather than racing section traversal against a timeout.
Adapted from #1357. JavaScript syntax, strict C syntax compilation, formatting, and static checks passed. The Linux pwntools verification lane was not run on this macOS host.
Co-authored-by: You Wish <[email protected]>
* feat(ghidra): recover signed AArch64 relative jump tables
Generalise the AArch64 relative-table matcher to signed byte/halfword entries, UXTW indexes, byte or LSL #2 offsets, B.CS/B.HS bounds and a CBZ route for zero entries. Cross-check it against Ghidra's own load table when one exists, and add a fixture modelled on the RenderScript blend kernel.
Refs #487
* fix(ghidra): preserve typed labels for normalized switch selectors
---------
Co-authored-by: morluto <[email protected]>
Edits to `release.yml` or `real-ghidra-windows.yml` selected only the
workflow lane, so the shards holding releaseWorkflow, releaseCheckpoint
and realGhidraWindowsWorkflow tests were skipped. Actionlint checks
syntax only, so a PR could drop the package-before-publish gate, the
registry canary or the default-branch-only self-hosted runner restriction
without CI noticing.
Conformance fixture sources under tests/ set only the code lane, so the
conformance-fixtures and reconstruction-readiness jobs, the only callers
of `verify:fixtures` and `verify:readiness`, never ran for them. Route
the directories that build-conformance-fixtures.mjs compiles to both
lanes, and readiness applications to the readiness lane.
Both were raised by the Codex review of #1660 after it merged.
Co-authored-by: Claude Opus 5.5 <[email protected]>
* feat(ghidra): configurable import language and analysis seeds
REA_GHIDRA_LANGUAGE_ID and REA_GHIDRA_COMPILER_SPEC_ID set the import
language when the header cannot identify the compiler (for example,
Borland C++ PE images).
REA_GHIDRA_SEED_FILE seeds functions, code and labels before
auto-analysis, for code reached only through computed jumps or data.
Both are validated before launch, recorded in the analysis profile and
verified in the bridge handshake.
* fix(ghidra): parse language XML and preserve seed ordering
* test(ghidra): use explicit platform paths for seed launch checks
* fix(javascript): retain cleanup failure reason in error causes
---------
Co-authored-by: morluto <[email protected]>
Retain source URLs, empty connections, and ordered frame streams. Compare same-URL streams without relying on transient request IDs, and compare selected shapes and byte counts only through common known coverage. Malformed binary frames retain known metadata with an unknown byte count.
BREAKING CHANGE: inspect_web_page network.websocket_events is replaced by network.websocket_connections, whose records contain request_id, url, and events. Frame payload_bytes is nullable when decoding cannot establish its size. No legacy alias is retained.
Validation: 78 domain/browser/MCP focused tests, check:fast, docs:check, and real Chrome 154 CDP capture passed. Real capture retained six connections and twelve frames with source URLs and selected shapes. Full browser verifier was interrupted during an unrelated slow scenario stage; its assertions were exercised by the bounded capture proof.
Preserve observed terminal-call sites and callee flags across function views, raw bridge responses, Evidence, and snapshot replay. Version analysis profiles so older unqualified results cannot be reused.
Qualify Ghidra function extents without changing external no-return flags or claiming recovery of excluded code.
Validation: 76 focused tests, check:fast, docs:check, formatting, and the full Ghidra 12.1.4 host lane pass. Real CLI and all five stdio MCP function views retain the terminal-call evidence; returning puts calls remain unflagged. The reported stripped Rust ELF and Windows host remain unverified.
Fixes#1658
Carry defined-data scope through list and search Evidence and bind it into the analysis profile so older snapshots cannot replay unqualified results. Clarify the tool contract and document known-address byte/reference inspection.
Validation: 36 focused tests, check:fast, docs:check, and real Ghidra 12.1.4 CLI/stdio MCP on macOS arm64. The Rust Mach-O fixture contains the phrase and Ghidra defines it; the reported Linux ELF omission was not reproduced.
Fixes#1659
Extend the existing real Electron public-tool fixture with assignment aliases for BrowserWindow, contextBridge, ipcMain, and ipcRenderer. Assert exact static recovery counts and observe the handler invocation after a real click.
Verified the public CLI/stdio MCP fixture, IPC invocation, cancellation, and owned-process cleanup against checksum-verified Electron 43.3.0 on macOS ARM64. Build and check:fast pass. The separate readiness reload/crash scenario still fails on a destroyed execution context; this commit does not claim the full verify:electron lane passes.
Check function and label ownership in the existing namespace before renaming. Keep same-address renames idempotent and reject duplicate batch members inside their individual transactions. Extend real-provider namespace checks for single and batch collisions without conflating function and label fixture names.
Validation: real Ghidra 12.1.4 host-native verification passed on macOS ARM64 with JDK 21.0.12.1, including public CLI/stdIO MCP, qualified-name round trips, rollback, source-byte immutability, and complete cleanup. Windows mutation authority remains unchanged.
Fixes#1649
Use password-store=basic for owned raw Chrome verification processes and document the same option for dedicated caller-owned Linux investigation profiles. Locked keyrings can stall navigation and leave placeholder frame URLs; keep the existing committed-URL authorization boundary.
Validation: real Chrome 154 CLI and stdio MCP browser verifier passed on macOS ARM64, plus docs freshness and check:fast. The locked Linux desktop keyring environment was not reproduced locally.
Place the imported control label inside a valid multi-byte NOP instead of suppressing Mach-O function-start metadata. Encode the supported ARM64 and x86-64 instructions explicitly and retain the load dependency so the control remains past the function entry. Assert that Ghidra imports a label and no procedure at the control address before checking name rejection and address containment.
Two real arm64 Ghidra 12.1.4 imports confirmed both fixture strategies produce labels; only default linking retains LC_FUNCTION_STARTS. The full native-value CLI/MCP verifier passed with 349 successful and 52 expected rejected boundary calls, including imported aliases, complete exports, and startup cancellation cleanup. Host ARM64 and Apple x86-64 fixture compilation passed; x86 provider execution remains unverified.
* fix(test): preserve Ghidra interior-label controls on Mach-O
* test: preserve selector semantics and accept signaled fixture exits
* test(javascript): exercise deep returns through the public CLI
Keep failed reader, root descriptor, and output-tree cleanup with the caller. Drain admitted work before close, retry the same retained owners, and block new resource work while cleanup is incomplete. Preserve primary failures and complete inventory observations.
Thread ownership through JavaScript reconstruction, the CLI's one-shot scope, MCP server shutdown, verifier scripts, and test fixtures. Remove redundant ownership flags and the unused validated test wrapper.
Validate with 850 passing focused tests across 90 suites (two skipped), targeted classification and cleanup retries, static and unused-code checks, and real macOS CLI/MCP directory, ZIP, and DMG workflows. Native Windows and deep-analysis providers were not verified.
BREAKING CHANGE: Direct artifact inventory/extraction and JavaScript analysis APIs require an explicit caller-owned ArtifactResourceScope. CLI and MCP input contracts are unchanged.