[PR #4678] feat(ghidra): support raw SH-4 binaries #6356

Open
opened 2026-10-31 01:13:50 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4678
Author: @kmatzen
Created: 10/17/2026
Status: 🔄 Open

Base: main ← Head: codex/sh4-raw-binary


📝 Commits (10+)

  • 9700c0d feat(ghidra): support raw SH-4 binaries
  • 9abf245 feat(ghidra): support raw ARMv4T firmware
  • 1d2c2b4 feat(ghidra): admit unverified 12.3 builds
  • 192ed60 feat(ghidra): record SH-4 language artifact identity
  • 812eda9 feat(ghidra): expose instruction P-code
  • e10b6d5 feat(ghidra): export native machine evidence
  • e397f35 feat(ghidra): seed exact function bodies
  • a23d1e2 fix(ghidra): reconcile exact bodies after analysis
  • d0a4c87 fix(ghidra): preserve physical delay-slot gaps
  • 80aeb19 feat(ghidra): recognize SH-4 literal transfers

📊 Changes

40 files changed (+2067 additions, -99 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/references/native-and-artifacts.md (+8 -4)
📝 bridge/ghidra/ReaGhidraApplySeeds.java (+179 -12)
📝 bridge/ghidra/ReaGhidraBridge.java (+437 -0)
📝 docs/raw-binary.md (+48 -14)
📝 docs/testing.md (+13 -1)
📝 package.json (+1 -0)
📝 scripts/verify-real-ghidra-raw.mjs (+23 -11)
➕ scripts/verify-real-ghidra-sh4.mjs (+334 -0)
📝 scripts/verify/ghidra/seeds.mjs (+4 -3)
📝 src/application/DirectAnalysis.ts (+1 -0)
📝 src/cli/coreNativeCommands.ts (+83 -0)
📝 src/cliCommandNames.ts (+1 -0)
📝 src/contracts/officialToolContracts.ts (+6 -0)
📝 src/contracts/toolContractExamples.ts (+1 -0)
📝 src/contracts/toolEffects.ts (+4 -0)
📝 src/contracts/toolOutputSchemaGroups.ts (+4 -0)
📝 src/domain/binaryTargetTypes.ts (+4 -0)
📝 src/domain/native/nativeInstruction.ts (+6 -0)
➕ src/domain/native/nativeMachineEvidence.test.ts (+149 -0)
➕ src/domain/native/nativeMachineEvidence.ts (+187 -0)

...and 20 more files

📄 Description

Summary

Admit caller-selected little-endian SH-4 raw binaries through the existing Ghidra BinaryLoader workflow. This enables static analysis of headerless SH-4 firmware and console executables when the caller supplies the exact load address.

Problem and expected behavior

Ghidra already provides SuperH4:LE:32:default, but REA rejected sh4 before provider selection. A caller should be able to select --target-format raw-binary --architecture sh4 --entry-point 0x... and receive the same load-image, instruction, pseudocode, and Evidence workflows as other admitted raw architectures.

Change and scope

  • Adds sh4 as an explicit raw-only, 32-bit architecture with 2-byte entry alignment.
  • Binds it to SuperH4:LE:32:default, compiler spec default, address space ram.
  • Keeps big-endian SH-4, device emulation, cache behavior, exceptions, and boot sequencing out of scope.
  • Adds unit, CLI/MCP boundary, documentation, authored-skill, and real-provider coverage.

This extends an existing static-analysis capability and does not execute target code. No linked issue; this draft supplies the concrete implementation and real-provider evidence for maintainer scope review.

Contract and boundary impact

  • Semantic owner and earliest changed stage: raw-binary target admission in src/domain/rawBinary.ts.
  • Contribution scope fit and linked maintainer decision: ordinary static disassembly/decompilation extension; maintainer decision pending on this draft.
  • CLI and MCP/tool-catalog contract: architecture: sh4 becomes valid only with format=raw-binary and an entry point.
  • Provider compatibility: Ghidra on Linux/macOS; Windows Ghidra P0, Hopper, IDA, and Kuna remain unsupported for this raw target.
  • Evidence contract: existing raw mapping attestation records SH-4 target identity, language, mapped bytes, digest, and limitations.
  • Target authority and cleanup: caller-selected local file; ephemeral immutable Ghidra project; source bytes unchanged; verifier confirms no surviving descendants.
  • Generated metadata: authored skill updated; generated outputs remain ignored.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

The filesystem write is the existing owned ephemeral Ghidra project; original target bytes are never modified.

Evidence and regression coverage

  • Tests added or updated: raw admission/alignment/overflow, language binding, provider profile, CLI/MCP acceptance and rejection, plus verify:ghidra:sh4.

  • Base reproduction: REA 6.5.0 rejects architecture=sh4 with architecture_unsupported before provider startup.

  • User-visible result: the new lane verifies SuperH4:LE:32:default at 0x8c010000, decodes mov #42,r0; rts; nop, and decompiles a return value of 42.

  • Remaining gaps: real provider run used Ghidra 12.1.3 on macOS arm64; Linux and Ghidra 12.1.4 are not yet exercised. One pre-existing MCP boundary test repeatedly timed out while probing the unrelated Apktool provider; all 179 other selected tests passed.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm run verify:ghidra:sh4 — passed with real Ghidra 12.1.3 on macOS arm64; CLI/MCP parity, decoding, decompilation, rejection paths, source preservation, cleanup, and empty descendant lineage verified.
  • npm run check:fast — passed.
  • npm run docs:check — passed.
  • npm run verify:test-discovery — passed; all 1,465 test files discovered exactly once.
  • Focused suite — 179 passed, 2 Windows-only skipped, 1 unrelated existing MCP test failed twice with inspect_apktool_client timeout.

Compatibility, safety, and release

  • Breaking changes: none; additive raw-only architecture selection.
  • Real coverage: macOS arm64 and Ghidra 12.1.3.
  • Package impact: new architecture enum value and verifier command; no dependency changes.
  • Security/privacy: local static analysis only; existing immutable-snapshot and cleanup boundaries are unchanged.

Author readiness

Human owner: @kmatzen

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows the project convention.
  • Related issue is absent because this draft requests maintainer scope review with an implemented, verified example.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • The final diff was checked for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4678 **Author:** [@kmatzen](https://github.com/kmatzen) **Created:** 10/17/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `codex/sh4-raw-binary` --- ### 📝 Commits (10+) - [`9700c0d`](https://github.com/morluto/rea/commit/9700c0d371d62f0cfc8bdc8b1825dd08b83fcbb6) feat(ghidra): support raw SH-4 binaries - [`9abf245`](https://github.com/morluto/rea/commit/9abf24525fcd9eab5ea0ee411246d16aae8b9954) feat(ghidra): support raw ARMv4T firmware - [`1d2c2b4`](https://github.com/morluto/rea/commit/1d2c2b4ad33e097f7728537ac4957605c6e4f5e0) feat(ghidra): admit unverified 12.3 builds - [`192ed60`](https://github.com/morluto/rea/commit/192ed6046875855722b98fbb02c2014a1bcff1d1) feat(ghidra): record SH-4 language artifact identity - [`812eda9`](https://github.com/morluto/rea/commit/812eda9777d6ce83831ec2032a4b30f1ce155411) feat(ghidra): expose instruction P-code - [`e10b6d5`](https://github.com/morluto/rea/commit/e10b6d5e5313b03b0060e34e30df8c0fa1750842) feat(ghidra): export native machine evidence - [`e397f35`](https://github.com/morluto/rea/commit/e397f35f341b2102d882a0d7721248b11941bd65) feat(ghidra): seed exact function bodies - [`a23d1e2`](https://github.com/morluto/rea/commit/a23d1e2d8475183258e78e0532c62fcce8720294) fix(ghidra): reconcile exact bodies after analysis - [`d0a4c87`](https://github.com/morluto/rea/commit/d0a4c8735e7367b65b52c93db3db1dd31c11c39a) fix(ghidra): preserve physical delay-slot gaps - [`80aeb19`](https://github.com/morluto/rea/commit/80aeb197117accb58fe80defdf36f10dbb118844) feat(ghidra): recognize SH-4 literal transfers ### 📊 Changes **40 files changed** (+2067 additions, -99 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md` (+8 -4) 📝 `bridge/ghidra/ReaGhidraApplySeeds.java` (+179 -12) 📝 `bridge/ghidra/ReaGhidraBridge.java` (+437 -0) 📝 `docs/raw-binary.md` (+48 -14) 📝 `docs/testing.md` (+13 -1) 📝 `package.json` (+1 -0) 📝 `scripts/verify-real-ghidra-raw.mjs` (+23 -11) ➕ `scripts/verify-real-ghidra-sh4.mjs` (+334 -0) 📝 `scripts/verify/ghidra/seeds.mjs` (+4 -3) 📝 `src/application/DirectAnalysis.ts` (+1 -0) 📝 `src/cli/coreNativeCommands.ts` (+83 -0) 📝 `src/cliCommandNames.ts` (+1 -0) 📝 `src/contracts/officialToolContracts.ts` (+6 -0) 📝 `src/contracts/toolContractExamples.ts` (+1 -0) 📝 `src/contracts/toolEffects.ts` (+4 -0) 📝 `src/contracts/toolOutputSchemaGroups.ts` (+4 -0) 📝 `src/domain/binaryTargetTypes.ts` (+4 -0) 📝 `src/domain/native/nativeInstruction.ts` (+6 -0) ➕ `src/domain/native/nativeMachineEvidence.test.ts` (+149 -0) ➕ `src/domain/native/nativeMachineEvidence.ts` (+187 -0) _...and 20 more files_ </details> ### 📄 Description ## Summary Admit caller-selected little-endian SH-4 raw binaries through the existing Ghidra BinaryLoader workflow. This enables static analysis of headerless SH-4 firmware and console executables when the caller supplies the exact load address. ## Problem and expected behavior Ghidra already provides `SuperH4:LE:32:default`, but REA rejected `sh4` before provider selection. A caller should be able to select `--target-format raw-binary --architecture sh4 --entry-point 0x...` and receive the same load-image, instruction, pseudocode, and Evidence workflows as other admitted raw architectures. ## Change and scope - Adds `sh4` as an explicit raw-only, 32-bit architecture with 2-byte entry alignment. - Binds it to `SuperH4:LE:32:default`, compiler spec `default`, address space `ram`. - Keeps big-endian SH-4, device emulation, cache behavior, exceptions, and boot sequencing out of scope. - Adds unit, CLI/MCP boundary, documentation, authored-skill, and real-provider coverage. This extends an existing static-analysis capability and does not execute target code. No linked issue; this draft supplies the concrete implementation and real-provider evidence for maintainer scope review. ## Contract and boundary impact - Semantic owner and earliest changed stage: raw-binary target admission in `src/domain/rawBinary.ts`. - Contribution scope fit and linked maintainer decision: ordinary static disassembly/decompilation extension; maintainer decision pending on this draft. - CLI and MCP/tool-catalog contract: `architecture: sh4` becomes valid only with `format=raw-binary` and an entry point. - Provider compatibility: Ghidra on Linux/macOS; Windows Ghidra P0, Hopper, IDA, and Kuna remain unsupported for this raw target. - Evidence contract: existing raw mapping attestation records SH-4 target identity, language, mapped bytes, digest, and limitations. - Target authority and cleanup: caller-selected local file; ephemeral immutable Ghidra project; source bytes unchanged; verifier confirms no surviving descendants. - Generated metadata: authored skill updated; generated outputs remain ignored. Expected effects: - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [x] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. The filesystem write is the existing owned ephemeral Ghidra project; original target bytes are never modified. ## Evidence and regression coverage - Tests added or updated: raw admission/alignment/overflow, language binding, provider profile, CLI/MCP acceptance and rejection, plus `verify:ghidra:sh4`. - Base reproduction: REA 6.5.0 rejects `architecture=sh4` with `architecture_unsupported` before provider startup. - User-visible result: the new lane verifies `SuperH4:LE:32:default` at `0x8c010000`, decodes `mov #42,r0; rts; nop`, and decompiles a return value of 42. - Remaining gaps: real provider run used Ghidra 12.1.3 on macOS arm64; Linux and Ghidra 12.1.4 are not yet exercised. One pre-existing MCP boundary test repeatedly timed out while probing the unrelated Apktool provider; all 179 other selected tests passed. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm run verify:ghidra:sh4` — passed with real Ghidra 12.1.3 on macOS arm64; CLI/MCP parity, decoding, decompilation, rejection paths, source preservation, cleanup, and empty descendant lineage verified. - `npm run check:fast` — passed. - `npm run docs:check` — passed. - `npm run verify:test-discovery` — passed; all 1,465 test files discovered exactly once. - Focused suite — 179 passed, 2 Windows-only skipped, 1 unrelated existing MCP test failed twice with `inspect_apktool_client` timeout. ## Compatibility, safety, and release - Breaking changes: none; additive raw-only architecture selection. - Real coverage: macOS arm64 and Ghidra 12.1.3. - Package impact: new architecture enum value and verifier command; no dependency changes. - Security/privacy: local static analysis only; existing immutable-snapshot and cleanup boundaries are unchanged. ## Author readiness Human owner: @kmatzen - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows the project convention. - [x] Related issue is absent because this draft requests maintainer scope review with an implemented, verified example. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] The final diff was checked for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6356
No description provided.