[GH-ISSUE #1783] [Bug] Ghidra provider times out on a 1.85 MB Swift/ObjC arm64 Mach-O: auto-analysis stalls in ObjcMessageAnalyzer and cannot be skipped #603

Closed
opened 2026-10-15 18:26:32 +00:00 by bsakaguchi · 5 comments
Owner

Originally created by @okz247 on GitHub (Oct 11, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1783

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Observed behavior

With the Ghidra provider, the first query against a 1.85 MB thin arm64 Mach-O (a Swift/Objective-C macOS app executable) never returns. Both search attempts ended in provider_timeout: one at the default 330,000 ms startup deadline and one with REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000 (40 minutes).

During the 40-minute run, Ghidra's default auto-analysis was stuck in one analyzer. Two thread dumps taken about 2.3 minutes apart show the same single worker thread inside ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer, recursing through getNameForVarnode / getAddressFromVarnode:

  • That thread had used 1,985 s of CPU at 2,226 s elapsed, and 2,116 s at 2,365 s elapsed.
  • The 11 native decompile processes had each used between 0.06 s and 11.4 s of CPU in total and were idle.
  • ghidra.log had no new lines after the first 35 seconds of analysis when checked about 35 minutes in.

Two controls with plain analyzeHeadless, outside REA, on the same file:

  • Default analyzers, -analysisTimeoutPerFile 300: Analysis timed out at 300 seconds. Ghidra's own timing table attributes 259.5 s of the 299 s to Objective-C Message Analyzer.
  • Same command plus one pre-script that sets Objective-C Message Analyzer to false: Analysis succeeded, Total Time 76 secs.

So the stall reproduces in Ghidra 12.1.4 without REA, and REA's part is that it gives a caller no way around it and no indication of what stalled.

None of REA 6.4.0's Ghidra settings (install directory, startup deadline, import language and compiler spec, seed file, NativeAOT jar) changes analyzer options, and the analysis profile records analyzer_preset: "ghidra-default", so a caller cannot select that outcome through REA.

Reproduction

  1. Install Ghidra 12.1.4 and JDK 21, and set GHIDRA_INSTALL_DIR and JAVA_HOME. rea doctor --provider ghidra --json reports healthy.

  2. Take the main executable of coconutBattery 4.4.0 for macOS (com.coconut-flavour.coconutBattery, universal x86_64 + arm64) and thin it, since Ghidra v1 rejects universal Mach-O:

    lipo coconutBattery.app/Contents/MacOS/coconutBattery -thin arm64 -output coconutBattery-arm64
    

    Resulting slice: 1,854,496 bytes, SHA-256 a20f773dbb13d23e782d6771906f8fa83abe5c52b3145c4e77ddb0d44cf120a9.

  3. Run any Ghidra-backed query:

    rea search /abs/path/coconutBattery-arm64 "AppleSmartBattery" --provider ghidra --json
    

    Result after about 5.5 minutes: provider_timeout, timeout_ms: 330000.

  4. Repeat with a longer deadline:

    REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000 rea search /abs/path/coconutBattery-arm64 "AppleSmartBattery" --provider ghidra --json
    

    Result after 2,402 s: provider_timeout, timeout_ms: 2400000.

  5. Control, outside REA, with default analyzers:

    analyzeHeadless /abs/tmp-project ctl -import /abs/path/coconutBattery-arm64 \
      -readOnly -deleteProject -analysisTimeoutPerFile 300
    

    Result: Analysis timed out at 300 seconds; Objective-C Message Analyzer 259.543 secs in the timing table.

  6. Control, outside REA, with only the one analyzer disabled:

    analyzeHeadless /abs/tmp-project ctl -import /abs/path/coconutBattery-arm64 \
      -readOnly -deleteProject -scriptPath /abs/scripts \
      -preScript DisableObjcMessageAnalyzer.java
    

    where the pre-script body is setAnalysisOption(currentProgram, "Objective-C Message Analyzer", "false");. Result: Analysis succeeded, Total Time 76 secs.

For comparison, a thin arm64e copy of /bin/ls through the same REA + Ghidra installation returns a search result in 11 seconds.

Expected behavior

A caller can obtain Ghidra-backed results for this target, or at least learn why not. Either of these would do it:

  • A supported way to choose a non-default analyzer preset (or skip a named analyzer) for a session, recorded in the analysis profile so snapshots and Evidence stay bound to the analysis that actually ran.
  • When the startup deadline expires during auto-analysis, an error that reports the stage and what Ghidra was doing, rather than only provider_timeout.

Impact and scope

  • Affected: Ghidra-backed search on this target. I expect every Ghidra-backed operation, through CLI and MCP, to behave the same, since the documentation says operations begin only after default auto-analysis completes, but search is the only one I ran. Raising the deadline does not help within 40 minutes. I have not tested longer.
  • Likely affected: other Mach-O targets that trigger the same analyzer path. I have only observed this one binary.
  • Not affected: provider admission and doctor (both healthy), small targets (/bin/ls slice works), and cleanup. After the 40-minute timeout no Ghidra or decompile processes remained and the session's private temp directory was removed; after the 330 s timeout no Ghidra processes remained (I did not check the temp directory that time).
  • Evidence integrity is not affected; no partial result is returned.
  • Hopper analyzes the arm64 slice of the universal original through REA without this problem.

REA version

6.4.0 (npm rea-agents@6.4.0). The source lines cited below are the same at the 6.4.0 release commit a56f7bb6 and on main at 713db4dc.

Runtime and platform

Node 22.22.0; macOS 27.0 (26A428) arm64, Apple M4 Pro (12 cores); Ghidra 12.1.4 (Homebrew formula); OpenJDK 21.0.12.1 (Homebrew openjdk@21)

Target and artifact context

Thin Mach-O 64-bit arm64 executable, 1.85 MB, Swift + Objective-C macOS app (SwiftUI/AppKit), lipo-thinned from a universal binary

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

# REA result, default deadline
{"error":"Analysis failed","code":"provider_timeout","category":"timeout","message":"Analysis took too long. Try a smaller request, then run `rea doctor` if it continues.","retryable":true,"details":{"operation":"search_strings","timeout_ms":330000}}

# REA result, REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000
{"code":"provider_timeout","message":"Analysis took too long. Try a smaller request, then run `rea doctor` if it continues.","details":{"operation":"search_strings","timeout_ms":2400000}}

# Tail of the session's ghidra.log (still the last lines when checked ~35 minutes in)
INFO  (HeadlessAnalyzer) ANALYZING all memory and code: file:///.../target-a20f773dbb13.bin
INFO  (DecompilerSwitchAnalyzer) hit non-returning function, restarting decompiler switch analyzer later
ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0e3c for: x16-1000a0e3c

# jstack of the Ghidra JVM at ~2226 s elapsed (frames repeated in the dump are collapsed here)
"main" waiting on condition
	at ghidra.app.util.DecompilerConcurrentQ.waitForResults(DecompilerConcurrentQ.java:105)
	at ghidra.app.decompiler.parallel.ParallelDecompiler.doDecompileFunctions(ParallelDecompiler.java:116)
	at ghidra.app.decompiler.parallel.ParallelDecompiler.decompileFunctions(ParallelDecompiler.java:68)
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.added(ObjcMessageAnalyzer.java:153)
	at ghidra.app.plugin.core.analysis.AnalysisScheduler.runAnalyzer(AnalysisScheduler.java:186)
	...
	at ghidra.app.util.headless.HeadlessAnalyzer.analyzeProgram(HeadlessAnalyzer.java:1052)

"Parallel Decompiler-pool-4-thread-10" cpu=1984988.14ms elapsed=2226.33s RUNNABLE
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getAddressFromVarnode(ObjcMessageAnalyzer.java:561)   [x10]
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getNameForVarnode(ObjcMessageAnalyzer.java:610)
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getNameForVarnode(ObjcMessageAnalyzer.java:646)       [x9]
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.findMessages(ObjcMessageAnalyzer.java:327)
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.fixMsgSendCalls(ObjcMessageAnalyzer.java:370)
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer$1.process(ObjcMessageAnalyzer.java:148)
	at ghidra.app.decompiler.parallel.DecompilerCallback.process(DecompilerCallback.java:80)

# Same thread at ~2365 s elapsed
"Parallel Decompiler-pool-4-thread-10" cpu=2116348.63ms elapsed=2364.89s RUNNABLE
	at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getAddressFromVarnode(ObjcMessageAnalyzer.java:565)
	...

# Control: analyzeHeadless, default analyzers, -analysisTimeoutPerFile 300
ERROR (InternalResultListener) Unexpected exception getting Decompiler result java.util.concurrent.ExecutionException: ghidra.util.exception.CancelledException: Operation cancelled
    Decompiler Switch Analysis                14.862 secs
    Decompiler Switch Analysis - One Time     15.693 secs
    Objective-C Message Analyzer             259.543 secs
    Objective-C Type Metadata Analyzer         3.111 secs
    Swift Type Metadata Analyzer               0.207 secs
     Total Time   299 secs
ERROR (HeadlessAnalyzer) REPORT: Analysis timed out at 300 seconds. Processing not completed for file: file:///.../coconutBattery-arm64

# Control: analyzeHeadless with "Objective-C Message Analyzer" = false
INFO  (HeadlessAnalyzer) ANALYZING all memory and code: file:///.../coconutBattery-arm64
ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0e3c for: x16-1000a0e3c
ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0d34 for: x10-1000a0d34
     Total Time   76 secs
INFO  (HeadlessAnalyzer) REPORT: Analysis succeeded for file: file:///.../coconutBattery-arm64

Typed outcome or recovery expected

On a startup deadline during auto-analysis, a timeout error whose details identify the stage (import, auto-analysis, bridge readiness) and, where Ghidra exposes it, the active analyzer or the last log line. The current remediation text ("Try a smaller request, then run rea doctor") does not apply: the request is already minimal and doctor is healthy.

Analysis or suspected cause

Observed: one ObjcMessageAnalyzer worker consumes essentially all CPU for the whole run while every other worker is idle; plain analyzeHeadless with default analyzers stalls in the same analyzer; and disabling that analyzer lets analysis finish in 76 s. The stall itself is therefore Ghidra 12.1.4 behavior, not something REA's launch environment introduces.

Also observed: Ghidra's own -analysisTimeoutPerFile cancelled the stuck analyzer at 300 s and printed per-analyzer timings, which is the diagnostic REA's provider_timeout currently lacks.

Hypothesis, not verified: the recursive varnode walk in ObjcMessageAnalyzer.getNameForVarnode / getAddressFromVarnode revisits the same definitions without memoization on some function in this binary, so its cost grows exponentially. I have not identified the specific function, tested other Ghidra versions, or searched the Ghidra tracker.

The VarnodeContext: out of address spaces error appears in both the failing run and the successful control, so it is probably unrelated.

Source-derived: src/ghidra/GhidraAnalysisProfile.ts sets analyzer_preset: "ghidra-default", and src/ghidra/GhidraLauncher.ts passes -preScript only for DOS COM preparation and seed files, and bridge/ghidra/ReaGhidraPrepareCom.java is the only packaged script that touches analysis options (DOS COM only). I found no caller path to change analyzer options for a Mach-O target.

Additional context

The full thread dumps and both Ghidra logs are available if useful. A possible regression fixture would need a redistributable binary that triggers the same analyzer path; I do not have a reduced one.

Originally created by @okz247 on GitHub (Oct 11, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1783 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Native analysis or decompilation ### Observed behavior With the Ghidra provider, the first query against a 1.85 MB thin arm64 Mach-O (a Swift/Objective-C macOS app executable) never returns. Both `search` attempts ended in `provider_timeout`: one at the default 330,000 ms startup deadline and one with `REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000` (40 minutes). During the 40-minute run, Ghidra's default auto-analysis was stuck in one analyzer. Two thread dumps taken about 2.3 minutes apart show the same single worker thread inside `ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer`, recursing through `getNameForVarnode` / `getAddressFromVarnode`: - That thread had used 1,985 s of CPU at 2,226 s elapsed, and 2,116 s at 2,365 s elapsed. - The 11 native `decompile` processes had each used between 0.06 s and 11.4 s of CPU in total and were idle. - `ghidra.log` had no new lines after the first 35 seconds of analysis when checked about 35 minutes in. Two controls with plain `analyzeHeadless`, outside REA, on the same file: - Default analyzers, `-analysisTimeoutPerFile 300`: `Analysis timed out at 300 seconds`. Ghidra's own timing table attributes 259.5 s of the 299 s to `Objective-C Message Analyzer`. - Same command plus one pre-script that sets `Objective-C Message Analyzer` to `false`: `Analysis succeeded`, `Total Time 76 secs`. So the stall reproduces in Ghidra 12.1.4 without REA, and REA's part is that it gives a caller no way around it and no indication of what stalled. None of REA 6.4.0's Ghidra settings (install directory, startup deadline, import language and compiler spec, seed file, NativeAOT jar) changes analyzer options, and the analysis profile records `analyzer_preset: "ghidra-default"`, so a caller cannot select that outcome through REA. ### Reproduction 1. Install Ghidra 12.1.4 and JDK 21, and set `GHIDRA_INSTALL_DIR` and `JAVA_HOME`. `rea doctor --provider ghidra --json` reports healthy. 2. Take the main executable of coconutBattery 4.4.0 for macOS (`com.coconut-flavour.coconutBattery`, universal x86_64 + arm64) and thin it, since Ghidra v1 rejects universal Mach-O: ```bash lipo coconutBattery.app/Contents/MacOS/coconutBattery -thin arm64 -output coconutBattery-arm64 ``` Resulting slice: 1,854,496 bytes, SHA-256 `a20f773dbb13d23e782d6771906f8fa83abe5c52b3145c4e77ddb0d44cf120a9`. 3. Run any Ghidra-backed query: ```bash rea search /abs/path/coconutBattery-arm64 "AppleSmartBattery" --provider ghidra --json ``` Result after about 5.5 minutes: `provider_timeout`, `timeout_ms: 330000`. 4. Repeat with a longer deadline: ```bash REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000 rea search /abs/path/coconutBattery-arm64 "AppleSmartBattery" --provider ghidra --json ``` Result after 2,402 s: `provider_timeout`, `timeout_ms: 2400000`. 5. Control, outside REA, with default analyzers: ```bash analyzeHeadless /abs/tmp-project ctl -import /abs/path/coconutBattery-arm64 \ -readOnly -deleteProject -analysisTimeoutPerFile 300 ``` Result: `Analysis timed out at 300 seconds`; `Objective-C Message Analyzer 259.543 secs` in the timing table. 6. Control, outside REA, with only the one analyzer disabled: ```bash analyzeHeadless /abs/tmp-project ctl -import /abs/path/coconutBattery-arm64 \ -readOnly -deleteProject -scriptPath /abs/scripts \ -preScript DisableObjcMessageAnalyzer.java ``` where the pre-script body is `setAnalysisOption(currentProgram, "Objective-C Message Analyzer", "false");`. Result: `Analysis succeeded`, `Total Time 76 secs`. For comparison, a thin arm64e copy of `/bin/ls` through the same REA + Ghidra installation returns a `search` result in 11 seconds. ### Expected behavior A caller can obtain Ghidra-backed results for this target, or at least learn why not. Either of these would do it: - A supported way to choose a non-default analyzer preset (or skip a named analyzer) for a session, recorded in the analysis profile so snapshots and Evidence stay bound to the analysis that actually ran. - When the startup deadline expires during auto-analysis, an error that reports the stage and what Ghidra was doing, rather than only `provider_timeout`. ### Impact and scope - Affected: Ghidra-backed `search` on this target. I expect every Ghidra-backed operation, through CLI and MCP, to behave the same, since the documentation says operations begin only after default auto-analysis completes, but `search` is the only one I ran. Raising the deadline does not help within 40 minutes. I have not tested longer. - Likely affected: other Mach-O targets that trigger the same analyzer path. I have only observed this one binary. - Not affected: provider admission and doctor (both healthy), small targets (`/bin/ls` slice works), and cleanup. After the 40-minute timeout no Ghidra or `decompile` processes remained and the session's private temp directory was removed; after the 330 s timeout no Ghidra processes remained (I did not check the temp directory that time). - Evidence integrity is not affected; no partial result is returned. - Hopper analyzes the arm64 slice of the universal original through REA without this problem. ### REA version 6.4.0 (npm `rea-agents@6.4.0`). The source lines cited below are the same at the 6.4.0 release commit `a56f7bb6` and on `main` at `713db4dc`. ### Runtime and platform Node 22.22.0; macOS 27.0 (26A428) arm64, Apple M4 Pro (12 cores); Ghidra 12.1.4 (Homebrew formula); OpenJDK 21.0.12.1 (Homebrew `openjdk@21`) ### Target and artifact context Thin Mach-O 64-bit arm64 executable, 1.85 MB, Swift + Objective-C macOS app (SwiftUI/AppKit), lipo-thinned from a universal binary ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence ```text # REA result, default deadline {"error":"Analysis failed","code":"provider_timeout","category":"timeout","message":"Analysis took too long. Try a smaller request, then run `rea doctor` if it continues.","retryable":true,"details":{"operation":"search_strings","timeout_ms":330000}} # REA result, REA_GHIDRA_STARTUP_TIMEOUT_MS=2400000 {"code":"provider_timeout","message":"Analysis took too long. Try a smaller request, then run `rea doctor` if it continues.","details":{"operation":"search_strings","timeout_ms":2400000}} # Tail of the session's ghidra.log (still the last lines when checked ~35 minutes in) INFO (HeadlessAnalyzer) ANALYZING all memory and code: file:///.../target-a20f773dbb13.bin INFO (DecompilerSwitchAnalyzer) hit non-returning function, restarting decompiler switch analyzer later ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0e3c for: x16-1000a0e3c # jstack of the Ghidra JVM at ~2226 s elapsed (frames repeated in the dump are collapsed here) "main" waiting on condition at ghidra.app.util.DecompilerConcurrentQ.waitForResults(DecompilerConcurrentQ.java:105) at ghidra.app.decompiler.parallel.ParallelDecompiler.doDecompileFunctions(ParallelDecompiler.java:116) at ghidra.app.decompiler.parallel.ParallelDecompiler.decompileFunctions(ParallelDecompiler.java:68) at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.added(ObjcMessageAnalyzer.java:153) at ghidra.app.plugin.core.analysis.AnalysisScheduler.runAnalyzer(AnalysisScheduler.java:186) ... at ghidra.app.util.headless.HeadlessAnalyzer.analyzeProgram(HeadlessAnalyzer.java:1052) "Parallel Decompiler-pool-4-thread-10" cpu=1984988.14ms elapsed=2226.33s RUNNABLE at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getAddressFromVarnode(ObjcMessageAnalyzer.java:561) [x10] at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getNameForVarnode(ObjcMessageAnalyzer.java:610) at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getNameForVarnode(ObjcMessageAnalyzer.java:646) [x9] at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.findMessages(ObjcMessageAnalyzer.java:327) at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.fixMsgSendCalls(ObjcMessageAnalyzer.java:370) at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer$1.process(ObjcMessageAnalyzer.java:148) at ghidra.app.decompiler.parallel.DecompilerCallback.process(DecompilerCallback.java:80) # Same thread at ~2365 s elapsed "Parallel Decompiler-pool-4-thread-10" cpu=2116348.63ms elapsed=2364.89s RUNNABLE at ghidra.app.plugin.core.analysis.ObjcMessageAnalyzer.getAddressFromVarnode(ObjcMessageAnalyzer.java:565) ... # Control: analyzeHeadless, default analyzers, -analysisTimeoutPerFile 300 ERROR (InternalResultListener) Unexpected exception getting Decompiler result java.util.concurrent.ExecutionException: ghidra.util.exception.CancelledException: Operation cancelled Decompiler Switch Analysis 14.862 secs Decompiler Switch Analysis - One Time 15.693 secs Objective-C Message Analyzer 259.543 secs Objective-C Type Metadata Analyzer 3.111 secs Swift Type Metadata Analyzer 0.207 secs Total Time 299 secs ERROR (HeadlessAnalyzer) REPORT: Analysis timed out at 300 seconds. Processing not completed for file: file:///.../coconutBattery-arm64 # Control: analyzeHeadless with "Objective-C Message Analyzer" = false INFO (HeadlessAnalyzer) ANALYZING all memory and code: file:///.../coconutBattery-arm64 ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0e3c for: x16-1000a0e3c ERROR (VarnodeContext) VarnodeContext: out of address spaces at @1000a0d34 for: x10-1000a0d34 Total Time 76 secs INFO (HeadlessAnalyzer) REPORT: Analysis succeeded for file: file:///.../coconutBattery-arm64 ``` ### Typed outcome or recovery expected On a startup deadline during auto-analysis, a timeout error whose details identify the stage (import, auto-analysis, bridge readiness) and, where Ghidra exposes it, the active analyzer or the last log line. The current remediation text ("Try a smaller request, then run `rea doctor`") does not apply: the request is already minimal and doctor is healthy. ### Analysis or suspected cause Observed: one `ObjcMessageAnalyzer` worker consumes essentially all CPU for the whole run while every other worker is idle; plain `analyzeHeadless` with default analyzers stalls in the same analyzer; and disabling that analyzer lets analysis finish in 76 s. The stall itself is therefore Ghidra 12.1.4 behavior, not something REA's launch environment introduces. Also observed: Ghidra's own `-analysisTimeoutPerFile` cancelled the stuck analyzer at 300 s and printed per-analyzer timings, which is the diagnostic REA's `provider_timeout` currently lacks. Hypothesis, not verified: the recursive varnode walk in `ObjcMessageAnalyzer.getNameForVarnode` / `getAddressFromVarnode` revisits the same definitions without memoization on some function in this binary, so its cost grows exponentially. I have not identified the specific function, tested other Ghidra versions, or searched the Ghidra tracker. The `VarnodeContext: out of address spaces` error appears in both the failing run and the successful control, so it is probably unrelated. Source-derived: `src/ghidra/GhidraAnalysisProfile.ts` sets `analyzer_preset: "ghidra-default"`, and `src/ghidra/GhidraLauncher.ts` passes `-preScript` only for DOS COM preparation and seed files, and `bridge/ghidra/ReaGhidraPrepareCom.java` is the only packaged script that touches analysis options (DOS COM only). I found no caller path to change analyzer options for a Mach-O target. ### Additional context The full thread dumps and both Ghidra logs are available if useful. A possible regression fixture would need a redistributable binary that triggers the same analyzer path; I do not have a reduced one.
bsakaguchi 2026-10-15 18:26:32 +00:00
Author
Owner

@akushonkamen commented on GitHub (Oct 11, 2026):

Confirmed on main @ ce845ba4: src/ghidra/GhidraLauncher.ts (ghidraHeadlessArguments, interface at lines 371-386, argv builder at 388-468) only injects -preScript for the DOS COM loader branch (lines 446-449, ReaGhidraPrepareCom.java) and seed files, so there is no channel to pass analyzer options; src/ghidra/GhidraAnalysisProfile.ts:152 hardcodes analyzer_preset: "ghidra-default" with no configurable analyzer field anywhere in resolveGhidraAnalysisProfile. This matches the report exactly.

I'm working on a fix: an analysis-phase preScript that runs setAnalysisOption(currentProgram, "<Analyzer>", "false") for analyzers named through a new REA_GHIDRA_DISABLED_ANALYZERS setting (comma-separated), threaded through the session config into the launcher, with the analysis profile's analyzer_preset reflecting the override so snapshots stay bound to the analysis that actually ran. Offline unit tests will cover the argv construction (preScript ordering before the bridge postScript, byte-identical argv when unset).

Disclosure: this contribution is prepared with AI assistance (Claude), reviewed and verified by me.

<!-- gh-comment-id:6108147623 --> @akushonkamen commented on GitHub (Oct 11, 2026): Confirmed on main @ ce845ba4: `src/ghidra/GhidraLauncher.ts` (`ghidraHeadlessArguments`, interface at lines 371-386, argv builder at 388-468) only injects `-preScript` for the DOS COM loader branch (lines 446-449, `ReaGhidraPrepareCom.java`) and seed files, so there is no channel to pass analyzer options; `src/ghidra/GhidraAnalysisProfile.ts:152` hardcodes `analyzer_preset: "ghidra-default"` with no configurable analyzer field anywhere in `resolveGhidraAnalysisProfile`. This matches the report exactly. I'm working on a fix: an analysis-phase preScript that runs `setAnalysisOption(currentProgram, "<Analyzer>", "false")` for analyzers named through a new `REA_GHIDRA_DISABLED_ANALYZERS` setting (comma-separated), threaded through the session config into the launcher, with the analysis profile's `analyzer_preset` reflecting the override so snapshots stay bound to the analysis that actually ran. Offline unit tests will cover the argv construction (preScript ordering before the bridge postScript, byte-identical argv when unset). Disclosure: this contribution is prepared with AI assistance (Claude), reviewed and verified by me.
Author
Owner

@akushonkamen commented on GitHub (Oct 11, 2026):

Opened https://github.com/morluto/rea/pull/1800 implementing this: REA_GHIDRA_DISABLED_ANALYZERS (comma-separated, whitelist-validated) drives a packaged analysis-phase preScript (bridge/ghidra/ReaGhidraAnalysisOptions.java) that disables each named analyzer before default auto-analysis; the profile records ghidra-default+disabled:<names> plus analysis_options.disabled_analyzers and sessions fail closed on profile/setting mismatch. Details, red→green reproduction, and the no-local-Ghidra proof gap are in the PR description.

<!-- gh-comment-id:6108474406 --> @akushonkamen commented on GitHub (Oct 11, 2026): Opened https://github.com/morluto/rea/pull/1800 implementing this: `REA_GHIDRA_DISABLED_ANALYZERS` (comma-separated, whitelist-validated) drives a packaged analysis-phase preScript (`bridge/ghidra/ReaGhidraAnalysisOptions.java`) that disables each named analyzer before default auto-analysis; the profile records `ghidra-default+disabled:<names>` plus `analysis_options.disabled_analyzers` and sessions fail closed on profile/setting mismatch. Details, red→green reproduction, and the no-local-Ghidra proof gap are in the PR description.
Author
Owner

@ramchander7834-cloud commented on GitHub (Oct 11, 2026):

Cham

<!-- gh-comment-id:6108989380 --> @ramchander7834-cloud commented on GitHub (Oct 11, 2026): Cham
Author
Owner

@CassieFox23 commented on GitHub (Oct 14, 2026):

Heads up: this looks fixed on main in 9878bb729. The change is in src/config/ghidraDisabledAnalyzers.ts, and admits the documented Objective-C analyzer name covers it. This skip is opt-in, through REA_GHIDRA_DISABLED_ANALYZERS. It is listed on tracker #3582. If it still happens on main, please say so here and I'll take it off the list.

🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊

<!-- gh-comment-id:6174745058 --> @CassieFox23 commented on GitHub (Oct 14, 2026): Heads up: this looks fixed on main in 9878bb729. The change is in `src/config/ghidraDisabledAnalyzers.ts`, and `admits the documented Objective-C analyzer name` covers it. This skip is opt-in, through `REA_GHIDRA_DISABLED_ANALYZERS`. It is listed on tracker #3582. If it still happens on main, please say so here and I'll take it off the list. 🤖 Generated with Claude Code (Sonnet 5.5, verified by Opus 5.5) 🦊
Author
Owner

@morluto commented on GitHub (Oct 14, 2026):

Closing the REA-side analyzer opt-out gap as addressed by merged #1800 (9878bb729), present in qualified main fffb07419.

REA_GHIDRA_DISABLED_ANALYZERS="Objective-C Message Analyzer" now selects the requested opt-out. The packaged analysis pre-script disables and reads back the named option before default auto-analysis; the selected options participate in the analysis profile and mismatches fail closed. The named analyzer admission has a regression, and current main passed full qualification 38629313022.

This closes the missing caller control, the report's proposed recovery. It does not claim the upstream Ghidra analyzer was fixed or that this audit reran the reported coconutBattery Mach-O; that real-target verification remains unavailable here.

<!-- gh-comment-id:6178772966 --> @morluto commented on GitHub (Oct 14, 2026): Closing the REA-side analyzer opt-out gap as addressed by merged #1800 (`9878bb729`), present in qualified main [`fffb07419`](https://github.com/morluto/rea/commit/fffb0741936067530d1ce9777461cd53e87398c2). `REA_GHIDRA_DISABLED_ANALYZERS="Objective-C Message Analyzer"` now selects the requested opt-out. The packaged analysis pre-script disables and reads back the named option before default auto-analysis; the selected options participate in the analysis profile and mismatches fail closed. The named analyzer admission has a regression, and current main passed full qualification [38629313022](https://github.com/morluto/rea/actions/runs/38629313022). This closes the missing caller control, the report's proposed recovery. It does not claim the upstream Ghidra analyzer was fixed or that this audit reran the reported coconutBattery Mach-O; that real-target verification remains unavailable here.
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#603
No description provided.