[PR #840] [MERGED] fix(ghidra): admit the 12.1 line and the install's JDK range #2278

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

📋 Pull Request Information

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

Base: main ← Head: cursor/ghidra-version-range-6404


📝 Commits (3)

  • a2b9a7a fix(ghidra): admit the 12.1 line and the install's JDK range
  • 52387c9 fix(ghidra): stop pinning the NativeAOT build to one version string
  • 440e3d2 fix(ghidra): report unverified builds on analysis results

📊 Changes

22 files changed (+572 additions, -85 deletions)

View changed files

📝 README.md (+1 -1)
📝 README_ar.md (+2 -2)
📝 README_ja.md (+1 -1)
📝 README_ko.md (+1 -1)
📝 README_zh.md (+1 -1)
📝 docs/firmware-analysis.md (+1 -1)
📝 docs/ghidra-dos.md (+3 -3)
📝 docs/ghidra-nativeaot.md (+4 -1)
📝 docs/installation.md (+7 -4)
📝 docs/native-investigation.md (+1 -1)
📝 docs/provider-evaluation.md (+9 -5)
📝 docs/roadmap.md (+4 -2)
📝 docs/testing.md (+5 -0)
📝 docs/windows-ghidra-p0.md (+2 -2)
📝 scripts/build-ghidra-nativeaot.mjs (+45 -7)
📝 src/android/JadxSession.ts (+1 -1)
📝 src/ghidra/GhidraInstallation.test.ts (+116 -1)
📝 src/ghidra/GhidraInstallation.ts (+66 -37)
➕ src/ghidra/GhidraInstallationPolicy.ts (+220 -0)
📝 src/ghidra/GhidraProvider.behavior.test.ts (+67 -0)

...and 2 more files

📄 Description

Summary

Fixes #821. The Ghidra provider refused to start unless the JDK major was exactly 21 and application.version was exactly 12.1.4. A working Ghidra 12.1.x install, including a distro package such as 12.1.2, and a newer JDK that Ghidra itself accepts, failed with provider_unavailable before analysis.

Admission now follows the verified release line and the installation's own Java bounds. The observed version stays on the provider identity. A compatible build other than 12.1.4 records that the bridge was verified against 12.1.4 on every analysis result, including ordinary CLI and MCP operations. Session open uses health only as a startup gate and discards that execution, so the limitation is not limited to health.

The NativeAOT build script had the same pin as two regular expressions (application.version=12.1.4 and javac 21). It now accepts Ghidra 12.1.x and javac 21 or newer, compiles with --release 21, and records the observed Ghidra version.

Problem and expected behavior

rea analyze and binary_session failed provider_unavailable when application.version was 12.1.2 or the selected JDK was 27 (or 17). Both checks used equality: providerVersion === "12.1.4" and major === 21.

Ghidra 12.1.x publishes application.java.min=21 and an empty application.java.max. The packaged bridge uses that release line's public API. The provider should accept Ghidra 12.1.x and a 64-bit full JDK inside the installation's declared range, and the failure text should name that range. Real-provider verifiers still require the verified 12.1.4 / JDK 21 build.

Change and scope

  • src/ghidra/GhidraInstallationPolicy.ts parses application.version, application.java.min, and application.java.max.
  • Ghidra 12.1.x is accepted. 12.1.4 is the verified build. Other 12.1 releases, including a distro suffix such as 12.1.2-2.1, are compatible and reported as observed. Other lines, such as 12.0, 12.2, and 11.4, stay unsupported.
  • JDK admission uses the installation's minimum and maximum majors. A missing minimum defaults to 21. An empty maximum means no upper bound, so JDK 27 passes a stock 12.1 install. The check still requires a 64-bit JDK, not a JRE.
  • Failed version and Java checks name the accepted line or JDK range.
  • Every Ghidra execution for a compatible unverified build includes that limitation and keeps the observed provider version. Health and ordinary operations share the same session limitation list.
  • scripts/build-ghidra-nativeaot.mjs no longer matches the exact version strings. It accepts the 12.1 line, requires javac 21 or newer, and passes --release 21.
  • The JADX session engine version now comes from JADX_RELEASE.version instead of a second hardcoded "0.7.1". The server version check stays exact because that JAR is an audited, SHA-256-pinned producer.
  • User-facing docs now describe the 12.1.x admission rule. Verification lanes still document Ghidra 12.1.4 and JDK 21 because those scripts still require the verified build.

Contract and boundary impact

  • Semantic owner and earliest changed stage: Ghidra installation probe, before headless launch. NativeAOT build admission is the same line.
  • CLI and MCP/tool-catalog contract: none. Tool schemas are unchanged. Doctor and provider diagnostics text now names the accepted range. Analysis evidence limitations include the unverified-build note.
  • Provider, bridge, target-format, or platform compatibility: Ghidra admission widens from exact 12.1.4 and JDK 21 to the 12.1 line and the installation's declared JDK range. The Java bridge is unchanged.
  • Evidence, artifact, provenance, or reconstruction contract: the provider version remains the observed application.version. Compatible unverified builds add one limitation on each analysis execution. The NativeAOT build manifest records the observed Ghidra version.
  • Process execution, authorization, cleanup, or containment impact: none.
  • Generated metadata (docs/product-catalog.json), package, or installation impact: none.

Evidence and regression coverage

  • Tests added or updated: src/ghidra/GhidraInstallation.test.ts covers 12.1.2, a distro suffix, JDK 25 and 27, a declared Java maximum, an unreadable Java minimum, an unparseable version, another Ghidra line, and remediation text. src/ghidra/GhidraProvider.behavior.test.ts covers a 12.1.2 / JDK 27 session and asserts the unverified limitation on both health and list_procedures.
  • Base reproduction or other evidence: the reported failure was version/java checks with unsupported_version for 12.1.2 and JDK 17 or 27. Those equality checks are what the new tests replace.
  • User-visible CLI/MCP output (if applicable): a rejected 12.0.4 install reports Install a Ghidra 12.1.x release (verified with 12.1.4), or update REA for another Ghidra line. A JDK below the declared minimum reports Install a 64-bit full JDK 21 or newer, or set JAVA_HOME before starting REA. An admitted 12.1.2 analysis result includes This session uses Ghidra 12.1.2. The bridge is verified against 12.1.4; other 12.1.x builds are accepted and the observed version is reported.
  • Remaining proof gaps: this environment has no Ghidra installation, so npm run verify:ghidra and npm run build:ghidra:nativeaot were not run. JDK 17 still fails on a stock 12.1 install because that release declares application.java.min=21.

For evidence-bearing changes:

  • 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

  • npx vitest run src/ghidra/GhidraInstallation.test.ts src/ghidra/GhidraProvider.behavior.test.ts — 50 tests passed.
  • node --check scripts/build-ghidra-nativeaot.mjs — syntax check passed.
  • npm run check:fast during pre-push — typecheck and lint passed.
  • Real Hopper/Ghidra verification was not performed. No local Ghidra or JDK 21 toolchain is available here.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Installs that already passed still pass. Previously rejected 12.1.x installs and newer JDKs inside the declared range now pass.
  • Real Hopper/Ghidra, browser, or OS coverage: not run. The bridge behavior on 12.1.2 and JDK 27 is accepted from the installation contract and is not re-proven against a live Ghidra process in this change.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: none. The provider still does not install Ghidra or Java, and it still requires a 64-bit JDK with javac.

Review checklist

  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • 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.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.
Open in Web Open in Cursor 

🔄 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/840 **Author:** [@morluto](https://github.com/morluto) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `cursor/ghidra-version-range-6404` --- ### 📝 Commits (3) - [`a2b9a7a`](https://github.com/morluto/rea/commit/a2b9a7ab38ff9b75ed804d880e37df49ca91d79d) fix(ghidra): admit the 12.1 line and the install's JDK range - [`52387c9`](https://github.com/morluto/rea/commit/52387c9ce38d7927aa7542c3e556217ff2f32472) fix(ghidra): stop pinning the NativeAOT build to one version string - [`440e3d2`](https://github.com/morluto/rea/commit/440e3d263b2dc32127a6302cf2d444992d66dfed) fix(ghidra): report unverified builds on analysis results ### 📊 Changes **22 files changed** (+572 additions, -85 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+1 -1) 📝 `README_ar.md` (+2 -2) 📝 `README_ja.md` (+1 -1) 📝 `README_ko.md` (+1 -1) 📝 `README_zh.md` (+1 -1) 📝 `docs/firmware-analysis.md` (+1 -1) 📝 `docs/ghidra-dos.md` (+3 -3) 📝 `docs/ghidra-nativeaot.md` (+4 -1) 📝 `docs/installation.md` (+7 -4) 📝 `docs/native-investigation.md` (+1 -1) 📝 `docs/provider-evaluation.md` (+9 -5) 📝 `docs/roadmap.md` (+4 -2) 📝 `docs/testing.md` (+5 -0) 📝 `docs/windows-ghidra-p0.md` (+2 -2) 📝 `scripts/build-ghidra-nativeaot.mjs` (+45 -7) 📝 `src/android/JadxSession.ts` (+1 -1) 📝 `src/ghidra/GhidraInstallation.test.ts` (+116 -1) 📝 `src/ghidra/GhidraInstallation.ts` (+66 -37) ➕ `src/ghidra/GhidraInstallationPolicy.ts` (+220 -0) 📝 `src/ghidra/GhidraProvider.behavior.test.ts` (+67 -0) _...and 2 more files_ </details> ### 📄 Description <!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Summary Fixes #821. The Ghidra provider refused to start unless the JDK major was exactly 21 and `application.version` was exactly `12.1.4`. A working Ghidra 12.1.x install, including a distro package such as 12.1.2, and a newer JDK that Ghidra itself accepts, failed with `provider_unavailable` before analysis. Admission now follows the verified release line and the installation's own Java bounds. The observed version stays on the provider identity. A compatible build other than 12.1.4 records that the bridge was verified against 12.1.4 on every analysis result, including ordinary CLI and MCP operations. Session open uses health only as a startup gate and discards that execution, so the limitation is not limited to health. The NativeAOT build script had the same pin as two regular expressions (`application.version=12.1.4` and `javac 21`). It now accepts Ghidra 12.1.x and javac 21 or newer, compiles with `--release 21`, and records the observed Ghidra version. ## Problem and expected behavior `rea analyze` and `binary_session` failed `provider_unavailable` when `application.version` was `12.1.2` or the selected JDK was 27 (or 17). Both checks used equality: `providerVersion === "12.1.4"` and `major === 21`. Ghidra 12.1.x publishes `application.java.min=21` and an empty `application.java.max`. The packaged bridge uses that release line's public API. The provider should accept Ghidra 12.1.x and a 64-bit full JDK inside the installation's declared range, and the failure text should name that range. Real-provider verifiers still require the verified 12.1.4 / JDK 21 build. ## Change and scope - `src/ghidra/GhidraInstallationPolicy.ts` parses `application.version`, `application.java.min`, and `application.java.max`. - Ghidra 12.1.x is accepted. `12.1.4` is the verified build. Other 12.1 releases, including a distro suffix such as `12.1.2-2.1`, are compatible and reported as observed. Other lines, such as 12.0, 12.2, and 11.4, stay unsupported. - JDK admission uses the installation's minimum and maximum majors. A missing minimum defaults to 21. An empty maximum means no upper bound, so JDK 27 passes a stock 12.1 install. The check still requires a 64-bit JDK, not a JRE. - Failed version and Java checks name the accepted line or JDK range. - Every Ghidra execution for a compatible unverified build includes that limitation and keeps the observed provider version. Health and ordinary operations share the same session limitation list. - `scripts/build-ghidra-nativeaot.mjs` no longer matches the exact version strings. It accepts the 12.1 line, requires javac 21 or newer, and passes `--release 21`. - The JADX session engine version now comes from `JADX_RELEASE.version` instead of a second hardcoded `"0.7.1"`. The server version check stays exact because that JAR is an audited, SHA-256-pinned producer. - User-facing docs now describe the 12.1.x admission rule. Verification lanes still document Ghidra 12.1.4 and JDK 21 because those scripts still require the verified build. ## Contract and boundary impact - Semantic owner and earliest changed stage: Ghidra installation probe, before headless launch. NativeAOT build admission is the same line. - CLI and MCP/tool-catalog contract: none. Tool schemas are unchanged. Doctor and provider diagnostics text now names the accepted range. Analysis evidence limitations include the unverified-build note. - Provider, bridge, target-format, or platform compatibility: Ghidra admission widens from exact `12.1.4` and JDK 21 to the 12.1 line and the installation's declared JDK range. The Java bridge is unchanged. - Evidence, artifact, provenance, or reconstruction contract: the provider version remains the observed `application.version`. Compatible unverified builds add one limitation on each analysis execution. The NativeAOT build manifest records the observed Ghidra version. - Process execution, authorization, cleanup, or containment impact: none. - Generated metadata (`docs/product-catalog.json`), package, or installation impact: none. ## Evidence and regression coverage - Tests added or updated: `src/ghidra/GhidraInstallation.test.ts` covers 12.1.2, a distro suffix, JDK 25 and 27, a declared Java maximum, an unreadable Java minimum, an unparseable version, another Ghidra line, and remediation text. `src/ghidra/GhidraProvider.behavior.test.ts` covers a 12.1.2 / JDK 27 session and asserts the unverified limitation on both health and `list_procedures`. - Base reproduction or other evidence: the reported failure was `version`/`java` checks with `unsupported_version` for `12.1.2` and JDK 17 or 27. Those equality checks are what the new tests replace. - User-visible CLI/MCP output (if applicable): a rejected 12.0.4 install reports `Install a Ghidra 12.1.x release (verified with 12.1.4), or update REA for another Ghidra line.` A JDK below the declared minimum reports `Install a 64-bit full JDK 21 or newer, or set JAVA_HOME before starting REA.` An admitted 12.1.2 analysis result includes `This session uses Ghidra 12.1.2. The bridge is verified against 12.1.4; other 12.1.x builds are accepted and the observed version is reported.` - Remaining proof gaps: this environment has no Ghidra installation, so `npm run verify:ghidra` and `npm run build:ghidra:nativeaot` were not run. JDK 17 still fails on a stock 12.1 install because that release declares `application.java.min=21`. For evidence-bearing changes: - [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 - `npx vitest run src/ghidra/GhidraInstallation.test.ts src/ghidra/GhidraProvider.behavior.test.ts` — 50 tests passed. - `node --check scripts/build-ghidra-nativeaot.mjs` — syntax check passed. - `npm run check:fast` during pre-push — typecheck and lint passed. - Real Hopper/Ghidra verification was not performed. No local Ghidra or JDK 21 toolchain is available here. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Installs that already passed still pass. Previously rejected 12.1.x installs and newer JDKs inside the declared range now pass. - Real Hopper/Ghidra, browser, or OS coverage: not run. The bridge behavior on 12.1.2 and JDK 27 is accepted from the installation contract and is not re-proven against a live Ghidra process in this change. - Package or release metadata impact: none. - Security, privacy, process, or containment review: none. The provider still does not install Ghidra or Java, and it still requires a 64-bit JDK with `javac`. ## Review checklist - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [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] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-44a88d98-6d9b-4da2-a464-22f0c2a36404?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-44a88d98-6d9b-4da2-a464-22f0c2a36404&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:16:39 +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#2278
No description provided.