[PR #246] [MERGED] feat(ghidra): implement read-only inventory operations #1896

Closed
opened 2026-10-16 21:12:17 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/246
Author: @N0zoM1z0
Created: 7/15/2026
Status: ✅ Merged
Merged: 7/15/2026
Merged by: @N0zoM1z0

Base: main ← Head: agent/add-ghidra-inventory-operations


📝 Commits (2)

  • 73d2300 feat(ghidra): implement read-only inventory operations
  • 7393c58 docs: refresh Ghidra inventory API links

📊 Changes

101 files changed (+3828 additions, -380 deletions)

View changed files

📝 README.md (+15 -10)
📝 bridge/ghidra/ReaGhidraBridge.java (+1047 -23)
📝 docs/adr/0001-provider-selection-and-analysis-profiles.md (+14 -10)
📝 docs/api/assets/hierarchy.js (+1 -1)
📝 docs/api/assets/navigation.js (+1 -1)
📝 docs/api/assets/search.js (+1 -1)
📝 docs/api/classes/application_PermissionAuthority.PermissionPathError.html (+1 -1)
📝 docs/api/classes/application_ProcessCaptureError.ProcessCaptureError.html (+1 -1)
📝 docs/api/classes/application_ProjectPermissionStore.ProjectPermissionStoreError.html (+1 -1)
📝 docs/api/classes/ghidra_GhidraClient.GhidraClient.html (+29 -11)
📝 docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html (+1 -1)
📝 docs/api/classes/ghidra_GhidraProvider.GhidraProvider.html (+11 -10)
📝 docs/api/classes/ghidra_GhidraResponseRouter.GhidraResponseRouter.html (+3 -3)
📝 docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html (+13 -7)
➕ docs/api/classes/ghidra_protocol.GhidraRemoteError.html (+87 -0)
📝 docs/api/functions/domain_hopperValues.addressDistance.html (+1 -1)
📝 docs/api/functions/domain_hopperValues.parseAddressedPage.html (+1 -1)
📝 docs/api/functions/domain_hopperValues.parseDocuments.html (+1 -1)
📝 docs/api/functions/domain_hopperValues.parseFunctionDossier.html (+1 -1)
📝 docs/api/functions/domain_hopperValues.parseListCount.html (+1 -1)

...and 80 more files

📄 Description

Why

PR #245 established a bounded, private Ghidra headless session, but deliberately advertised no binary-analysis operations. Linux users still could not perform even high-confidence inventory workflows without Hopper. This PR admits the first provider-neutral Ghidra operations only after defining their exact semantics and proving them against real source-owned binaries.

What changed

  • Upgrades the packaged Java bridge protocol to v2 and admits exactly ten authenticated, read-only operations:
    • address_name
    • list_documents
    • list_names
    • list_procedures
    • list_segments
    • list_strings
    • procedure_address
    • resolve_containing_procedure
    • search_procedures
    • search_strings
  • Adds strict provider-boundary input/output parsing, exact pagination, canonical default and named address spaces, primary/dynamic/external symbol facts, external/thunk procedure facts, string encoding/termination/length facts, and direct Ghidra memory-block permissions.
  • Bounds inventories, literal and regex search work, candidate/value sizes, request deadlines, and wire output. Limit exhaustion and analysis incompleteness fail explicitly instead of producing partial results labeled exhaustive.
  • Preserves authenticated remote failure codes and projects invalid/not-found/ambiguous input, unavailable methods, cancellation, and timeout into REA's tagged error algebra.
  • Publishes only the proved Ghidra capabilities. GUI, mutation, decompilation, call/xref, assembly, and CFG operations remain unavailable and never fall back silently to Hopper.
  • Enables shared Swift/Objective-C inventory workflows and binary_overview when their admitted dependencies are present, with equivalent CLI/MCP composition and Ghidra provider/profile Evidence.
  • Adds source-owned debug/stripped ELF conformance fixtures, a real Ghidra verifier, production-seam client/provider/MCP tests, catalog updates, architecture/roadmap documentation, and regenerated TypeDoc output.

Contract example

A Ghidra-backed list_procedures Evidence result now preserves normalized provider-neutral data plus provider observations:

{
  "provider": { "id": "ghidra", "name": "Ghidra", "version": "12.1.2" },
  "normalized_result": {
    "items": [
      {
        "address": "0x401000",
        "value": "main",
        "value_truncated": false,
        "procedure": {
          "external": false,
          "thunk": false,
          "thunk_target": null
        }
      }
    ],
    "offset": 0,
    "limit": 100,
    "total": 1,
    "next_offset": null,
    "has_more": false
  }
}

Compatibility and migration

This is additive at the public surface: provider-neutral tool names and the 78-tool inventory are unchanged, existing Hopper behavior is unchanged, and no configuration migration is required. The Ghidra client and packaged bridge upgrade together to internal protocol v2. Existing unsupported Ghidra operations remain truthfully unavailable.

Verification

  • npm run check — 120 test files, 832 tests
  • npm run docs:generate
  • npm run verify:package — packed CLI/setup/skill/78-tool target-free MCP artifact
  • GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.2_PUBLIC npm run verify:ghidra
  • npm run knip
  • npm run jscpd
  • npm run scan:todos

Real-provider status:

  • Real Ghidra: performed with Ghidra 12.1.2/JDK 21 on source-owned debug and stripped x86-64 ELF fixtures; all ten operations, malformed/unsafe request rejection, exact pagination, external/thunk/symbol/string/memory semantics, and process/project cleanup passed.
  • Real Hopper: not performed; no Hopper adapter or Hopper semantic claim changed.
  • Real Browser: not performed; no browser adapter or browser semantic claim changed.

🔄 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/246 **Author:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Created:** 7/15/2026 **Status:** ✅ Merged **Merged:** 7/15/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `agent/add-ghidra-inventory-operations` --- ### 📝 Commits (2) - [`73d2300`](https://github.com/morluto/rea/commit/73d2300b0fcb0aa2e1ac0c811ab8aed7e71d0ed2) feat(ghidra): implement read-only inventory operations - [`7393c58`](https://github.com/morluto/rea/commit/7393c58109d603c26394c035e5d3777d23655da8) docs: refresh Ghidra inventory API links ### 📊 Changes **101 files changed** (+3828 additions, -380 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+15 -10) 📝 `bridge/ghidra/ReaGhidraBridge.java` (+1047 -23) 📝 `docs/adr/0001-provider-selection-and-analysis-profiles.md` (+14 -10) 📝 `docs/api/assets/hierarchy.js` (+1 -1) 📝 `docs/api/assets/navigation.js` (+1 -1) 📝 `docs/api/assets/search.js` (+1 -1) 📝 `docs/api/classes/application_PermissionAuthority.PermissionPathError.html` (+1 -1) 📝 `docs/api/classes/application_ProcessCaptureError.ProcessCaptureError.html` (+1 -1) 📝 `docs/api/classes/application_ProjectPermissionStore.ProjectPermissionStoreError.html` (+1 -1) 📝 `docs/api/classes/ghidra_GhidraClient.GhidraClient.html` (+29 -11) 📝 `docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html` (+1 -1) 📝 `docs/api/classes/ghidra_GhidraProvider.GhidraProvider.html` (+11 -10) 📝 `docs/api/classes/ghidra_GhidraResponseRouter.GhidraResponseRouter.html` (+3 -3) 📝 `docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html` (+13 -7) ➕ `docs/api/classes/ghidra_protocol.GhidraRemoteError.html` (+87 -0) 📝 `docs/api/functions/domain_hopperValues.addressDistance.html` (+1 -1) 📝 `docs/api/functions/domain_hopperValues.parseAddressedPage.html` (+1 -1) 📝 `docs/api/functions/domain_hopperValues.parseDocuments.html` (+1 -1) 📝 `docs/api/functions/domain_hopperValues.parseFunctionDossier.html` (+1 -1) 📝 `docs/api/functions/domain_hopperValues.parseListCount.html` (+1 -1) _...and 80 more files_ </details> ### 📄 Description ## Why PR #245 established a bounded, private Ghidra headless session, but deliberately advertised no binary-analysis operations. Linux users still could not perform even high-confidence inventory workflows without Hopper. This PR admits the first provider-neutral Ghidra operations only after defining their exact semantics and proving them against real source-owned binaries. ## What changed - Upgrades the packaged Java bridge protocol to v2 and admits exactly ten authenticated, read-only operations: - `address_name` - `list_documents` - `list_names` - `list_procedures` - `list_segments` - `list_strings` - `procedure_address` - `resolve_containing_procedure` - `search_procedures` - `search_strings` - Adds strict provider-boundary input/output parsing, exact pagination, canonical default and named address spaces, primary/dynamic/external symbol facts, external/thunk procedure facts, string encoding/termination/length facts, and direct Ghidra memory-block permissions. - Bounds inventories, literal and regex search work, candidate/value sizes, request deadlines, and wire output. Limit exhaustion and analysis incompleteness fail explicitly instead of producing partial results labeled exhaustive. - Preserves authenticated remote failure codes and projects invalid/not-found/ambiguous input, unavailable methods, cancellation, and timeout into REA's tagged error algebra. - Publishes only the proved Ghidra capabilities. GUI, mutation, decompilation, call/xref, assembly, and CFG operations remain unavailable and never fall back silently to Hopper. - Enables shared Swift/Objective-C inventory workflows and `binary_overview` when their admitted dependencies are present, with equivalent CLI/MCP composition and Ghidra provider/profile Evidence. - Adds source-owned debug/stripped ELF conformance fixtures, a real Ghidra verifier, production-seam client/provider/MCP tests, catalog updates, architecture/roadmap documentation, and regenerated TypeDoc output. ## Contract example A Ghidra-backed `list_procedures` Evidence result now preserves normalized provider-neutral data plus provider observations: ```json { "provider": { "id": "ghidra", "name": "Ghidra", "version": "12.1.2" }, "normalized_result": { "items": [ { "address": "0x401000", "value": "main", "value_truncated": false, "procedure": { "external": false, "thunk": false, "thunk_target": null } } ], "offset": 0, "limit": 100, "total": 1, "next_offset": null, "has_more": false } } ``` ## Compatibility and migration This is additive at the public surface: provider-neutral tool names and the 78-tool inventory are unchanged, existing Hopper behavior is unchanged, and no configuration migration is required. The Ghidra client and packaged bridge upgrade together to internal protocol v2. Existing unsupported Ghidra operations remain truthfully unavailable. ## Verification - `npm run check` — 120 test files, 832 tests - `npm run docs:generate` - `npm run verify:package` — packed CLI/setup/skill/78-tool target-free MCP artifact - `GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.2_PUBLIC npm run verify:ghidra` - `npm run knip` - `npm run jscpd` - `npm run scan:todos` Real-provider status: - Real Ghidra: **performed** with Ghidra 12.1.2/JDK 21 on source-owned debug and stripped x86-64 ELF fixtures; all ten operations, malformed/unsafe request rejection, exact pagination, external/thunk/symbol/string/memory semantics, and process/project cleanup passed. - Real Hopper: **not performed**; no Hopper adapter or Hopper semantic claim changed. - Real Browser: **not performed**; no browser adapter or browser semantic claim changed. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:12:17 +00:00
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#1896
No description provided.