mirror of
https://github.com/morluto/rea.git
synced 2026-11-05 06:45:22 +00:00
[GH-ISSUE #3751] Ghidra provider: open an existing analysed project instead of re-importing every session (large native binaries) #1456
Open
opened 2026-10-16 21:05:36 +00:00 by bsakaguchi
·
20 comments
No Branch/Tag specified
main
codex/procedure-reference-stacked
release-please--branches--main--components--rea-agents
release-please--branches--main--components--rea-agents--release-notes
codex/kuna-independent-retry
codex/byte-search-overlay-coverage
codex/open-failure-target-receipt
codex/kuna-xref-evidence
codex/ghidra-ambiguous-procedure-recovery
codex/function-source-bundle
codex/trace-function-integration-prototype
codex/snapshot-source-closure
codex/recorded-evidence-array-pages
codex/evidence-recovery-redesign
codex/trace-feature-address-scope
codex/call-discovery-scope
codex/ghidra-literal-candidate-evidence
codex/decompile-directory-independent-retry
codex/retry-provenance-base
codex/value-flow-capability-experiment
codex/ghidra-containing-instruction
cursor/readme-discord-button-ef9f
dependabot/github_actions/actions/setup-node-7.1.0
dependabot/github_actions/actions/upload-artifact-7.0.2
dependabot/npm_and_yarn/npm-minor-and-patch-d8d97ce6df
codex/kuna-1989
fix/8559-native-ui-fixture-ownership
fix/8555-go-verifier-mcp-ownership
codex/provider-capability-recovery
fix/8642-rizin-target-stdin
codex/ghidra-memory-effect-scope
codex/ghidra-annotation-entry-selector
codex/ghidra-readonly-recovery
codex/ghidra-regex-verifier-recovery
codex/evidence-discovery-view-guidance
fix/8545-bulk-append-overflow
fix/8428-navigation-refusal-alternatives
codex/address-context-recovery
codex/matching-member-limitations
codex/unknown-scope-contract
codex/evidence-view-guidance
feat/8373-native-trace-views
codex/ghidra-snapshot-verifier-binding
codex/elf-export-visibility
codex/evidence-view-recovery
codex/native-reference-cli-help
codex/provider-candidate-observation-scope
codex/kuna-session-verification
codex/ghidra-switch-lifetime-guidance
codex/pseudocode-paging-discovery
codex/clarify-evidence-view-support
codex/kuna-xrefs-selector-recovery
codex/context-capacity-recovery
codex/evidence-closure-large-links
codex/same-function-evidence-identity
codex/ghidra-verifier-inspected-jdk
codex/audit-guided-workflows
codex/crash-prompt-retained-dossiers
codex/analysis-view-error-recovery
codex/kuna-verifier-target-selection
codex/ghidra-selected-project-call-coverage
codex/docs-native-analysis-scope
codex/ghidra-java-socket-boundary
codex/ghidra-retained-snapshot-verifier
codex/ghidra-search-inventory-facts
fix/8284-zero-argument-parameter-bindings
fix/8198-ui-action-handler-offset
fix/8257-elf-entry-label-identity
fix/8304-deferred-output-schema-projection
fix/8277-call-path-computed-target-uncertainty
fix/pr-8089-conflicts
fix/ci-static-duplicate-export
dependabot/npm_and_yarn/lint-staged-17.6.0
dependabot/github_actions/actions/download-artifact-8.0.2
dependabot/npm_and_yarn/write-file-atomic-8.0.0
dependabot/npm_and_yarn/canonicalize-5.1.0
dependabot/github_actions/actions/cache/restore-6.1.0
dependabot/npm_and_yarn/toon-format/toon-4.4.0
dependabot/github_actions/actions/deploy-pages-5.0.1
codex/review-fixes-pr-2403
codex/review-fixes-pr-2400
codex/process-terminal-width
codex/test-brittleness-cleanup
verify/7167-browser-connect-macos
fix/7167-browser-connect
feat/native-matching-allowance-setting
feat/browser-scenario-dry-run
test/managed-caller-parameters-20261024
codex/parser-fortythird-boundaries
fix/6926-pinvoke-platform-decorations-20261023
fix/6889-har-body-encoding-20261023
fix/6888-sqlite-schema-budget-20261023
fix/dependency-security-gates-6708
cursor/evidence-overwrite-rebase-b4ac
feat/4057-verify-native-exports
fix/windows-acl-observer-overhead-20261022
cursor/erlang-beam-restack-4476
cursor/pe-certificate-review-bf32
fix/6116-javascript-application-fs-errors
fix/6061-unmapped-runtime-script-unknown
feat/browser-scenario-summary
fix/pe-certificates
codex/verify-3407
cursor/rebase-5699
cursor/rebase-5352
cursor/rebase-5600
cursor/fix-cli-schema-omission-10a8
codex/audit-hopper-shutdown-reasons-20261021
fix/demangle-swift-omitted-record
fix/nib-boolean-value-types
cursor/cancellation-partial-observation-a5ac
fix/ib-object-limit-reasons
fix/electron-fuse-limit-advice
fix/kuna-doctor-dangling-cache
fix/fixed-budget-refusal-advice
fix/js-ipc-listener-dedup
fix/js-return-member-provenance
fix/dmg-integrity-retry-advice
fix/ida-doctor-readiness
fix/kuna-version-probe-output-drain
fix/legacy-swift-runtime-name-matching
fix/dylib-lazy-load-commands
fix/browser-scenario-startup-cancel
fix/swift-nested-punycode-classification
fix/compare-unselected-scopes
fix/objc-method-budget-coverage
fix/dmg-mounted-root-observations
audit/ci-tests-20261019-round2
release/6.7.0
fix/wabt-cleanup-retry-resolution
fix/electron-fuse-elf-pe-architecture
fix/native-plist-descriptor-ownership
fix/kuna-caller-cleanup-ownership
experiment/atomic-codemode-20261016
review/first-contributor-3776
fix/call-resolution-full-read-cycles
fix/member-mutation-selection-repeat
experiment/atomic-re-tools-20261015
perf/member-mutation-lazy-origins
perf/static-network-mutation-index
fix/hopper-startup-lifecycle
audit/3050-windows-proof-20261015
feat/windows-window-capture-2183
audit/3049-windows-proof-20261015
audit/3735-macos-fixtures-20261015
fix/batch-decompile-null-pseudocode
fix/kuna-inventory-honors-jobs
experiment/browser-codemode-tool-design-20261015
fix/hopper-clean-runtime-argv
codex/review-2049-27f1b367
review-fixes/pr-2787-routing
fix/3360-scoped-this-emitters
fix/3367-replaced-global-effects
fix/3838-compact-any-value-items
test/hopper-download-probe-20261015
codex/windows-runtime-creation-red-green-20261015
codex/windows-readonly-root-red-green-20261015
codex/windows-root-share-red-green-20261015
codex/exp-1685-win-mcp-startup
codex/bug-sweep-20261015
investigate/2190-windows-package-phases
investigate/3543-macos-cli-deadline
perf/3281-reverse-tools-feedback-quality
fix/3406-hopper-doctor-fixture
fix/3341-wrapper-require-test-context
fix/3301-owned-uninstall-fixtures
fix/3164-compiler-input-ownership
fix/pcap-cleanup-stdout-newline-20261014
perf/interface-builder-summary
codex/review-fixes-pr-1977
fix/ghidra-effective-jvm-platform
fix/docs-turkish-rust-link-20261013
fix/main-maintenance-ci-20261010
fix/recover-binary-session-process-effects
codex/review-fixes-pr-2457
codex/ci-required-cancellation-gate
fix/main-format-baseline-20261013
fix/setup-preserve-entry-fields
cursor/restore-main-checks-1ffc
fix/ghidra-bridge-hashmap-import
codex/shared-ci-jadx-json-default-20261013
codex/shared-ci-ghidra-test-groups-20261013
codex/shared-ci-java-fixture-format-20261013
codex/fix-intrinsic-invocation-boundaries
test/release-preflight-reusable-jobs
test/js-parameter-provenance-expectation
fix/linux-hopper-verification-current
test/2419-ghidra-elf-probe-size
followup/pr-1544-native-ida
codex/fold-pr-2230-contribution
docs/readme-responsible-use
fix/issue-2064
fix/issue-2050
fix/issue-2053
fix/issue-1968
fix/issue-1945
experiment/codemode-bridge-20261011
fix/tool-effects-negative-wording-1904-20261012
fix/1842-electron-interop-provenance
feat/recover-javascript-multi-input
refactor/website-i18n-prep
fix/nativeaot-pe-virtual-extent
fix/browser-verifier-ci-hang
fix/pe-resources-input-selection
docs/beginner-friendly-guides
docs/beginner-setup-guide
fix/javascript-analysis-worker-1563
fix/1649-ghidra-duplicate-names
fix/javascript-export-keys-integration-1369
test/maintenance-boundary-contracts-20261011
review/javascript-export-keys-1369
review/process-live-progress-1483
test/javascript-1495-growth-ratio
fix/ci-escape-timing
docs/normalized-terminal-geometry-1450
release/6.3.0
archive/release-6.3.0-pr1381
release/6.2.0
fix/electron-preload-dynamic-override
fix/javascript-self-referential-bundler-edges
release/6.1.0
cursor/grok-client-cherry-pick-0b56
feat/signature-posture
feat/dyld-shared-cache
feat/artifact-integrity-policy
feat/pkg-inventory
release/6.0.0
chore/sync-release-5.0.0
release/5.0.0
cursor/cloud-agent-node-787e
fix/javascript-xhr-open-endpoints
review/pr-711-realpath-fallback-wording
cleanup/replay-confinement
codex/test-suite-performance
codex/issue-foundations
codex/address-open-issues-2026-07-20
agent/javascript-vite-rollup-esbuild-adapters
agent/process-cleanup
agent/triage-integration
agent/unknown-commands-registry
feat/mcp-identity-metadata
morlvps/issue_cleanup
codex/installer-redesign
morl/roadmap-investigation-core
morl/roadmap-investigation-docs
release-please--branches--main--components--rea
rea-agents-6.8.0
rea-agents-6.7.0
rea-agents-6.6.0
experiment/atomic-codemode-wait-runtime-20261016
rea-agents-6.5.0
rea-agents-6.4.0
rea-agents-6.3.0
rea-agents-6.2.0
rea-agents-6.1.0
rea-agents-6.0.0
rea-agents-5.0.0
rea-agents-4.1.0
rea-agents-4.0.1
rea-agents-4.0.0
rea-agents-3.2.1
rea-agents-3.2.0
rea-agents-3.1.0
rea-agents-3.0.0
rea-agents-2.7.0
rea-agents-2.6.0
rea-agents-2.5.1
rea-agents-2.5.0
rea-agents-2.4.0
rea-agents-2.3.0
rea-agents-2.2.0
rea-agents-2.1.0
rea-agents-2.0.0
rea-agents-1.7.0
rea-agents-1.6.0
rea-agents-1.5.0
rea-agents-1.4.0
rea-agents-1.3.0
rea-agents-1.2.0
rea-agents-1.1.0
rea-agents-1.0.0
rea-agents-0.5.0
rea-agents-0.4.0
rea-agents-0.3.0
rea-0.2.1
rea-0.2.0
Labels
Clear labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
Mirrored from GitHub Pull Request
question
roadmap
triage
No labels
area: bridge
area: bridge
area: build
area: build
area: build
area: cli
area: domain
area: evidence
area: mcp
area: native
area: providers
area: runtime
area: server
area: setup
area: tests
bug
design
documentation
enhancement
enhancement
enhancement
experiment
help wanted
i18n
invalid
P0: critical
P1: high
P2: medium
P2: medium
P2: medium
P3: low
performance
provider-request
pull-request
question
roadmap
triage
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
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#1456
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @whalemenace on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3751
Summary
Allow the Ghidra provider to open an existing, already-analysed Ghidra program (a project + program name, or a
.gzf) instead of always importing the raw binary into an ephemeral project. Today every session pays the full auto-analysis again, which on large native binaries is the whole cost.Measurements (rea-agents 6.5.0, Ghidra 12.1.4, JDK 21, Windows 11 x64, 63 GB RAM)
Target: a shipped Unreal Engine 5.8 game executable, x86-64 PE, 191 MiB, ~379k functions.
rea analyzewith the default ephemeral import (GHIDRA_HEADLESS_MAXMEM=12G)REA_GHIDRA_STARTUP_TIMEOUT_MS, analysis unfinishedanalyzeHeadless -importdirectly into a persistent project (32G heap)-process -noanalysisand running 3 post-scripts incl. 5 decompilesrea functionwithREA_GHIDRA_SEED_FILE(all 377,642 functions exported from the project) and 9 heavy analyzers inREA_GHIDRA_DISABLED_ANALYZERS--snapshot: 15 min 08 s againWhere the 74 minutes go (Ghidra's own table): Create Address Tables 21 min, Stack 14 min, x86 Constant Reference 12 min, Disassemble Entry Points 7 min, Decompiler Switch 7 min. Seeds plus disabled analyzers remove about 60 of the 74 minutes, but the remaining ~15 minutes are paid on every CLI invocation and on every MCP session start, because
import_modeisephemeral-source-immutable.Proposal
open_binaryparameter) that points at an existing Ghidra project directory + program name, opened read-only with-process <program> -noanalysis(or an imported.gzf), with the same binary-identity check REA already does (sha256 of the program's original executable vs the selected target).import_mode: persistent-project-read-onlyand mark the program's existing names as caller assertions, exactly as the seed outcome text already does..hop).This would make the Ghidra provider usable for daily work on large game binaries (names applied once via PDB, BinDiff or scripts, then queried for seconds) without an IDA licence, and it keeps the evidence ledger intact for the whole investigation.
Happy to draft the bridge change if the direction is acceptable.
@XinwangTao commented on GitHub (Oct 15, 2026):
The numbers make the case convincingly: 74 min for one-time analysis vs 15 s to reopen with -noanalysis, and the remaining ~15 min per invocation is pure re-import overhead with ephemeral mode. Opening a caller-selected persistent project read-only, with the existing sha256 identity check carried over, is the right design — it keeps evidence semantics intact (import_mode recorded as persistent-project-read-only) while making daily work on large binaries feasible. Also good that the Hopper provider already sets precedent with .hop analysis paths, so this slots into an existing pattern rather than inventing a new one.
@RoKenobi commented on GitHub (Oct 18, 2026):
A data point for this issue, from REA 6.5.0 on Linux x64 (20 cores, 31 GB RAM) with Ghidra 12.1.4:
iTunes.exe12.10.11.2, a 38 MB x64 PE.rea doctor". The fix was raisingREA_GHIDRA_STARTUP_TIMEOUT_MS, which the README mentions, but the error message, the doctor output and the skill don't. Naming the setting in the error would help. This is the same in 6.7.0. PR #4864 documents the same startup-budget case.Reusing a finished analysis across server restarts (as this issue asks) would have saved most of that time.
@morluto commented on GitHub (Oct 26, 2026):
Thanks for documenting the large-project workflow and its target identity needs. #7236 landed reuse of a selected
.gprproject through a verified private copy, with read-only Ghidra processing and binary identity checks. I am leaving this report open because your reproduced host was Windows, which that implementation explicitly does not support, and.gzfimport is also outside its described scope. The merged PR reports real Linux verification; this triage did not rerun the large target.@XinwangTao commented on GitHub (Oct 27, 2026):
#7236 落地后把 Windows 缺口补上是有明确收益的:RoKenobi 的数据点说明默认 330s 启动预算对大二进制根本不够,而错误消息引导用户去跑 rea doctor 是误导。如果 persistent-project 复用能覆盖 Windows(.gpr 只读打开 + 身份校验),这类用例会直接从"调大 timeout 反复等待重导入"变成"秒级重开",超时错误也就自然消失。建议 Windows 实现时留意三点:Ghidra 项目目录在 Windows 上的文件锁语义(并发打开同一 .gpr 时的 .lock 行为)、路径长度上限(UE 大项目树很容易超 MAX_PATH)、以及把超时错误消息改成同时提示 REA_GHIDRA_STARTUP_TIMEOUT_MS 与 persistent-project 复用两个选项。
@macjayz commented on GitHub (Oct 27, 2026):
I would like to contribute the remaining Windows support for persistent Ghidra-project reuse, building on #7236. Before I start, can a maintainer confirm that this follow-up is available and indicate whether Windows
.gprreuse alone is the preferred first scope, with.gzfleft separate? I can keep the change focused on the current verified-copy and identity-check design, and add Windows-specific regression coverage where the repository can support it.@XinwangTao commented on GitHub (Oct 28, 2026):
+1 for the Windows follow-up scoped as .gpr reuse first, .gzf left separate — that matches how #7236 landed and keeps the diff reviewable. Echoing my earlier notes as acceptance criteria for the Windows port: (1) verify the verified-copy step works under Windows file-lock semantics (concurrent open of the same .gpr, .lock behavior), and (2) watch MAX_PATH in the Ghidra project tree copy — deep UE trees can trip the 260-char limit before any Ghidra code runs. Also worth a tiny independent change: make the startup-timeout error name REA_GHIDRA_STARTUP_TIMEOUT_MS and mention persistent-project reuse as the alternative, since RoKenobi showed the current "run rea doctor" hint misleads.
@macjayz commented on GitHub (Oct 28, 2026):
Thanks @XinwangTao, I'll treat those as acceptance criteria for the Windows
.gprreuse:.gprthat is already open elsewhere and a leftover.lockfileOn the startup-timeout message: I agree it's a separate change, and it's useful on every platform, not just Windows. I can open it as its own small PR. It would name
REA_GHIDRA_STARTUP_TIMEOUT_MSand mention persistent-project reuse instead of pointing torea doctor.@morluto, could you confirm whether (a) the Windows
.gprfollow-up is open for me to take, and (b) you'd accept the timeout-message fix as a separate PR?@morluto commented on GitHub (Oct 30, 2026):
Current-state note from a real macOS arm64 / Ghidra 12.1.4 check: REA now supports the expanded-project portion of this request on POSIX via
REA_GHIDRA_PROJECT_PATHand optionalREA_GHIDRA_PROGRAM_NAME. It copies the caller's project into an owned runtime, checks the selected program's recorded executable SHA-256 against the chosen binary, opens the copy read-only with-noanalysis, and reports that prior completeness/settings are unknown. These settings are server-start environment configuration, not a per-open_binaryproject selector.In a new owned test project I used direct headless Ghidra to export and reimport a
.gzfcontaining a renamed function, comment, structure and typed signature. Selecting the restored expanded project in REA returned the refined pseudocode and type; REA refused further annotation, and all 10 original project regular-file content digests remained unchanged. The packed export/import were done outside REA; this does not demonstrate direct.gzfselection, editable project continuation, Windows support, or large-binary speed. The full observation and open design questions are in #8165. A deliberately unanalysed selected project also motivated the recovery question in #8208.@morluto commented on GitHub (Oct 30, 2026):
Additional real macOS/Ghidra 12.1.4 control for existing-project selection: a single self-owned project contained two root programs imported from byte-identical Mach-O files, but each had a different user-defined function name and comment. Separate REA servers explicitly selecting
program_alphaandprogram_betareturned the corresponding distinct pseudocode. Their profiles retained the same project content digest but different exact program names and profile digests. A snapshot created while selecting alpha was refused withprofile_mismatchwhen beta was selected; opening beta without that snapshot then worked. All 12 source-project regular-file digests and the original target digest remained unchanged.This supports preserving exact program choice in future per-open selection designs: a matching binary hash alone cannot choose between separately annotated programs. It is one POSIX/headless fixture, not Windows, nested-folder or
.gzfsupport. Omitting the program name when the target basename was not a project program produced the separate recovery issue #8216.@morluto commented on GitHub (Oct 30, 2026):
Another macOS 12.1.4 headless control exercised source-project freshness. REA committed a selected project/profile at
open_binary. A separate Ghidra headless script then intentionally renamed a function in that disposable source project before the first query; REA refused the stale copy. Reopening the same selected target committed a new project fingerprint and returned the updated annotation. A further source-project edit while REA's private Ghidra copy was already running did not change the active query result; explicitly reopening loaded the newer project state. The executable digest was unchanged and close succeeded.The safety boundary worked in this fixture, but the stale-project refusal reached the agent as generic provider startup failure and doctor advice; the typed project-change cause survived only inside diagnostics. #8217 records that separate recovery issue. This is not evidence about concurrent writes during the copy, GUI use, or Windows.
@morluto commented on GitHub (Oct 30, 2026):
A project-identity control: I intentionally changed an instruction in a disposable Ghidra project, leaving its imported Mach-O unchanged. REA selected the project read-only and returned the saved changed bytes/pseudocode; a fresh-import session on the same original returned the original bytes/pseudocode. Both mapped the same address to the same original file offset. The selected-project profile and limitations disclosed its identity and possible earlier edits, consistent with the installation guide's warning that matching the recorded import SHA-256 does not establish an unedited program. REA did not write the project or target.
The existing load-image source-files view showed different original/modified digests for this edited project, but an independent fresh-import fixture with an applied relocation also showed different digests. #8232 discusses whether a bounded source-versus-image comparison would help agents without classifying every difference as a patch. This is one controlled project on macOS, not a broad analysis of project contents or Windows.
@XinwangTao commented on GitHub (Oct 31, 2026):
Thanks for the detailed POSIX verification — reopening the persistent project read-only with the sha256 identity check and refusing further annotation keeps the evidence ledger intact, which is exactly what this request needed. Echoing macjayz: scoping the Windows port to .gpr reuse first (with the file-lock and MAX_PATH checks discussed above) and leaving .gzf separate keeps the follow-up diff reviewable. Glad the startup-timeout message fix landed as its own PR (#8114) since it benefits every platform.
@morluto commented on GitHub (Oct 31, 2026):
Snapshot control after changing the same selected project
On REA
b43c329df779708e43ae297f498a844e45d9c923and Ghidra 12.1.4, I copied a source-owned project into a disposable directory, opened its selected program through real stdio MCP, analyzed one function, and closed withsnapshot_path. The resulting snapshot reported one primitive entry and one Evidence record. Reopening the unchanged project with that snapshot and querying the function succeeded and explicitly reported snapshot replay.After those sessions closed, a separate headless Ghidra script deliberately renamed the function in the disposable source project at the same project path and program name. Opening with the old snapshot then returned
evidence_integrity_mismatch/profile_mismatchand advised analyzing without the snapshot and saving a fresh one. Opening without it succeeded and returned the newly named function. Thus the observed refusal is not just a different selected program or project pathname.REA did not alter the target, selected project, or saved snapshot during the replay/refusal/recovery calls; their before/after content hashes matched within each phase. The intentional project edit was outside REA. The target was not executed. The error names target, provider or profile as possible causes rather than identifying the changed project field; this control establishes safe refusal and usable recovery, not a field-level diagnostic or broad race coverage.
@morluto commented on GitHub (Oct 31, 2026):
Real CLI refusal and recovery control
Using the same changed disposable project,
rea function <target> 0x1000002d8 --provider ghidra --snapshot <old-snapshot> --format json --full-outputexited 1 withevidence_integrity_mismatch/profile_mismatchand the same analyze-without-this-snapshot recovery as MCP. The old snapshot's SHA-256 remained unchanged.A subsequent
rea functioncall with a new snapshot path succeeded and returnedaudit_project_changed; repeating with that new path returned identical Evidence. In a separate process-tree sampling control at roughly 100 ms intervals, the uncached CLI call showed Ghidra Java/decompiler descendants, while the saved-snapshot call showed none. The two results and Evidence IDs matched. Sampling cannot rule out a very short-lived process; sourcesnapshotEvidenceForQueryand its CLI fast path explain how a matching record can be returned without starting the provider. The CLI returned the original Evidence without the explicit snapshot-replay limitation observed in the earlier MCP control, so the captured output alone does not establish which path was used.Target, selected-project file hashes, and the old snapshot hash remained unchanged through the CLI checks; the new snapshot was caller-selected test output. The target was not executed. This is one macOS/Ghidra selected-project case, not a cross-platform or performance measurement.
@morluto commented on GitHub (Oct 31, 2026):
Real MCP snapshot-destination conflict and recovery control on the same source-owned, unexecuted Mach-O with REA
b43c329, Ghidra 12.1.4 and Kuna 1.986:close_binary({snapshot_path:<existing owned file>})returnedinvalid_requestwith reasonexistsand advice to choose another path or allow overwrite. The existing file's hash was unchanged.binary_sessionstill reported the selected provider open with no cleanup pending, and a subsequentprocedure_addressquery succeeded.Both sessions closed successfully and the target hash remained unchanged. This checks one existing-file conflict and explicit fresh-path recovery per provider; it does not test overwrite, permissions, interrupted writes, edited Ghidra sessions, or provider-independent snapshot replay.
@morluto commented on GitHub (Oct 31, 2026):
Real cross-provider snapshot controls on the same unexecuted Mach-O, REA
b43c329, Ghidra 12.1.4 and Kuna 1.986:evidence_integrity_mismatch/profile_mismatch. The Ghidra binding stayed open, cleanup was not pending, and a Ghidra session rename remained resolvable.These verify early refusal and active-session preservation for the tested mismatch and dirty-session cases. The profile-mismatch message intentionally lists target/provider/profile possibilities, so this is not a claim that it identifies the exact differing field. No cross-provider cache reuse or broader compatibility is established. Related switch-retirement discussion: #8289.
@morluto commented on GitHub (Oct 31, 2026):
Packed-program admission and explicit recovery
I tested the existing
.gzf-to-expanded-project workflow on REAb43c329df779708e43ae297f498a844e45d9c923, Ghidra 12.1.4, and the owned packed program described in #8165.Setting
REA_GHIDRA_PROJECT_PATHto that.gzfmade scopedrea doctor --provider ghidra --target <target> --format jsonreportconfig_drift, andrea decompilereturnconfiguration_invalid. The guidance requested an expanded.gprmarker and said to restore.grezarchives first; it did not describe importing a.gzfpacked program. With the same configuration, the MCP SDK could not initialize because the REA process exited 1; its stderr contained the same configuration error. This is a startup configuration refusal, not a failedopen_binarycall or a claim that direct.gzfis supported.For a concrete manual recovery, I ran Ghidra
analyzeHeadless <owned-dir> restored -import <packed.gzf> -noanalysisinto a newly created disposable project, then configured REA with itsrestored.gprand exact program name. A realrea decompilereturned the earlier caller-authored function name, comment and typed structure accesses. The original executable, packed file and the expanded project's regular-file hashes stayed unchanged during the REA command; neither binary ran. Ghidra's own import created the new project before that check. This is one single-program, same-version control, not a full project archive, Windows, compatibility, concurrent import or performance test.The existing
.gprroute is therefore usable after an explicit external import, but a caller who has only a.gzfmay not discover that from the error. Any future direct support should preserve the distinction between packed programs and.grezproject archives, exact program/target identity, caller-selected storage, and existing read-only/cleanup semantics. No implicit import or project mutation is proposed by this observation.@morluto commented on GitHub (Oct 31, 2026):
Follow-up on the two-program control above: current main
60149282now gives the actionable missing-program error, andlist_documentscorrectly lists only the already selected program. Direct Ghidra wildcard processing of a disposable copy found both root programs with the same imported digest, while each had distinct authored analysis. I opened #8344 to discuss bounded candidate discovery before selection and its copy/cleanup costs; it does not propose auto-selecting by digest or changing the existing read-only authority.@morluto commented on GitHub (Nov 1, 2026):
Same-project program handoff through existing Evidence export
A follow-up on the two-program fixture tests the current recovery path without proposing a silent project switch. With real Ghidra 12.1.4/JDK 21 and REA PR #8437 head
22072c787566e8aa4bbc7eac8659c820a2fc3c08(the PR changes only prompt wording/tests), I used two separate stdio MCP server processes selecting the same owned project withREA_GHIDRA_PROGRAM_NAME=program_alphaand thenprogram_beta:analyze_functionreturned a summary and retained parent. Adding a hypotheticalprogram_name: "program_beta"toopen_binaryreturnedinvalid_request; alpha remained usable. The advertisedopen_binaryinput schema does not contain that field. This is the currently unsupported request, not a promised API regression.selected_beta; its analysis-profile digest differed from alpha's.inspect_analysis_viewresolved alpha's original parent ID, and the imported full parent retained alpha's profile digest. A subsequent beta procedure lookup still succeeded.The target and all regular files of the disposable source project had unchanged content hashes; the target was not executed. This is one project, one macOS host and two explicitly configured server processes. It transfers historical Evidence, not an editable project or live annotations. It supports a possible per-open selector discussion while showing the existing launch-time configuration plus export/import alternative; it does not establish that restarting is always harmless or that cross-profile comparison is semantically equivalent.
@XinwangTao commented on GitHub (Nov 4, 2026):
morluto 的 follow-up 非常有价值。特别是 #8819 这个缺口:caller 手里只有 .gzf 时,从现有错误信息根本发现不了外部导入恢复这条路(只有 stderr 里的配置错误 + 进程退出 1),诊断成本很高。赞同不直接支持隐式导入、保持 packed program 与 .grez 项目归档的区分,但建议至少在错误消息里显式给出恢复路径(如 "import the .gzf with analyzeHeadless into a disposable project, then configure REA_GHIDRA_PROJECT/REA_GHIDRA_PROGRAM_NAME"),而不是让调用者自己去排查。对 #8821 的配置失败隔离也支持——把启动期配置错误变成 open_binary 可读的明确错误,比让 MCP SDK 初始化直接失败更容易让客户端正确降级。希望看到这两个 design issue 落地。