[PR #1419] [MERGED] fix(ghidra): clear wrong no-return flags before serving a session #2871

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

📋 Pull Request Information

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

Base: main ← Head: fix/ghidra-wrong-noreturn-flags


📝 Commits (4)

  • c3e1db8 fix(ghidra): clear wrong no-return flags before serving a session
  • 7b5e36c fix(ghidra): refit in place and scope no-return call-site repair
  • bb08a33 fix(ghidra): constrain no-return repair to admitted return evidence
  • a962fbe Merge remote-tracking branch 'origin/main' into HEAD

📊 Changes

5 files changed (+126 additions, -5 deletions)

View changed files

➕ bridge/ghidra/ReaGhidraNoReturnFix.java (+89 -0)
📝 package.json (+1 -0)
📝 scripts/verify-packaged-ghidra-windows.mjs (+5 -1)
📝 src/ghidra/GhidraLauncher.ts (+8 -0)
📝 tests/boundary/providers/ghidra/ghidraLauncher.test.ts (+23 -4)

📄 Description

Problem

Ghidra's default auto-analysis can flag ordinary functions as no-return. In libpl2.so (Android x86 ELF, Ghidra 12.1.2) it flagged about 63 functions that all contain a real RET (stream readers, __cxa_guard_acquire, __release_weak). Every caller then treats the call as a terminator, so procedure_pseudo_code returns a body that stops at the first such call, often a thunk plus "Subroutine does not return". About 7,900 functions at 38,900 call sites were truncated.

Change

A new postScript, ReaGhidraNoReturnFix.java, runs before the bridge script:

  1. Clear the no-return flag on functions that contain a real RET (terminal, non-jump, non-call).
  2. Re-disassemble call sites that are still CALL_TERMINATOR but whose callee is no longer no-return.
  3. Rebuild the owning functions.

It does nothing when no function is wrongly flagged. It only edits the ephemeral analysis database, so executable bytes and the read-only import are unchanged.

Verification

  • tests/boundary/providers/ghidra/ghidraLauncher.test.ts updated (fix script ordered before the bridge); focused run passes.
  • Real provider: libpl2.so, decompile of the ZoneCompleteMessage deserializer before the change ended after the first stream-reader call. After the change it shows the full body (stat table loop and the 0x4c-byte reward loop). Other binaries and Windows were not tested.
  • The script is also packaged (package.json#files) and listed in the Windows packaged-script collision check.

Caveat: the scan covers all functions, and the re-disassembly runs only when wrong flags exist. I did not time the added cost.

🤖 Generated with Claude Code


🔄 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/1419 **Author:** [@JonahSimon](https://github.com/JonahSimon) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/ghidra-wrong-noreturn-flags` --- ### 📝 Commits (4) - [`c3e1db8`](https://github.com/morluto/rea/commit/c3e1db89e7390c5a4c10559cdb8517303e9b09ba) fix(ghidra): clear wrong no-return flags before serving a session - [`7b5e36c`](https://github.com/morluto/rea/commit/7b5e36c0591abc512f155c509113a9838514a12c) fix(ghidra): refit in place and scope no-return call-site repair - [`bb08a33`](https://github.com/morluto/rea/commit/bb08a33eede434509a590b59335369eb326c87f5) fix(ghidra): constrain no-return repair to admitted return evidence - [`a962fbe`](https://github.com/morluto/rea/commit/a962fbe5e6e56a133ac503c6ba2f70f5be314953) Merge remote-tracking branch 'origin/main' into HEAD ### 📊 Changes **5 files changed** (+126 additions, -5 deletions) <details> <summary>View changed files</summary> ➕ `bridge/ghidra/ReaGhidraNoReturnFix.java` (+89 -0) 📝 `package.json` (+1 -0) 📝 `scripts/verify-packaged-ghidra-windows.mjs` (+5 -1) 📝 `src/ghidra/GhidraLauncher.ts` (+8 -0) 📝 `tests/boundary/providers/ghidra/ghidraLauncher.test.ts` (+23 -4) </details> ### 📄 Description ## Problem Ghidra's default auto-analysis can flag ordinary functions as no-return. In `libpl2.so` (Android x86 ELF, Ghidra 12.1.2) it flagged about 63 functions that all contain a real `RET` (stream readers, `__cxa_guard_acquire`, `__release_weak`). Every caller then treats the call as a terminator, so `procedure_pseudo_code` returns a body that stops at the first such call, often a thunk plus "Subroutine does not return". About 7,900 functions at 38,900 call sites were truncated. ## Change A new postScript, `ReaGhidraNoReturnFix.java`, runs before the bridge script: 1. Clear the no-return flag on functions that contain a real `RET` (terminal, non-jump, non-call). 2. Re-disassemble call sites that are still `CALL_TERMINATOR` but whose callee is no longer no-return. 3. Rebuild the owning functions. It does nothing when no function is wrongly flagged. It only edits the ephemeral analysis database, so executable bytes and the read-only import are unchanged. ## Verification - `tests/boundary/providers/ghidra/ghidraLauncher.test.ts` updated (fix script ordered before the bridge); focused run passes. - Real provider: `libpl2.so`, decompile of the `ZoneCompleteMessage` deserializer before the change ended after the first stream-reader call. After the change it shows the full body (stat table loop and the 0x4c-byte reward loop). Other binaries and Windows were not tested. - The script is also packaged (`package.json#files`) and listed in the Windows packaged-script collision check. Caveat: the scan covers all functions, and the re-disassembly runs only when wrong flags exist. I did not time the added cost. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:15 +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#2871
No description provided.