[GH-ISSUE #6405] [Feature] Ghidra: export analyst names and comments from a session and re-apply them when the target is reopened #3835

Open
opened 2026-10-31 00:44:30 +00:00 by bsakaguchi · 5 comments
Owner

Originally created by @coygeek on GitHub (Oct 22, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6405

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Native analysis or decompilation

Current limitation

Names and comments an agent applies in a Ghidra session are lost when the session ends, and REA offers no compact way to carry them into the next session. Examined at REA main e83e3ceadd (source reading):

  • Session metadata edits "are discarded on close" (docs/installation.md; docs/ghidra-dos.md). Besides a deliberate close_binary, a server restart or a transport loss (#3509) ends the session and drops every name.
  • The import half already exists: REA_GHIDRA_SEED_FILE accepts address<TAB>kind[<TAB>name] lines and applies them before auto-analysis, with the seed digest bound into the analysis profile (docs/installation.md, seed section).
  • The export half is missing. The only route is to call list_names, which returns the complete symbol inventory in one response with no paging (docs/ghidra-provider.md, "Inventory" row), filter the items whose source is user-defined, and hand-write a seed file. On large targets that inventory is expensive in tokens, and entry comments written by annotate_native_function have no re-import path at all.
  • Opening a pre-analysed project read-only (#1048, #3751, open PR #3817) would save analysis time but would still discard new edits.

Use cases

  • A multi-day investigation of a stripped binary: dozens of helpers and globals renamed in session 1 should still be named in session 2, so pseudocode stays readable.
  • Recovering after a transport loss or server restart without re-deriving every name.
  • Handing a set of names to a teammate or to a later build (together with match_native_functions) as a reviewable text file.

Desired outcome and success criteria

  1. An operation (or a close_binary option) writes the names applied during the session, and entry comments written through annotate_native_function, to a caller-selected file. Only analyst edits from this session are written, not the whole symbol inventory.
  2. The file records the target SHA-256 and the analysis-profile identity of the session before any re-applied names, so it cannot be silently applied to a different binary. Because the seed digest is part of the analysis profile, the reopened session's profile will differ; the result should report both the recorded identity and the new one.
  3. The file can be re-applied when the same target is reopened: names through the existing seed path (or a format the seed path accepts), comments through an equivalent open-time option. REA_GHIDRA_SEED_FILE takes a single path, so the design must say how an exported file combines with an existing seed file (for example IL2CPP seeds).
  4. Re-applied names and comments are reported as caller-supplied assertions, as seeds already are, not as analysis results.
  5. Success check: rename two functions and one data label and add one entry comment; export; close; reopen with the file. address_name returns the names, callers' procedure_pseudo_code shows them, and the comment reads back. A file whose digest does not match the target is refused with a typed error; an existing destination file is never overwritten; executable bytes stay unchanged; Windows P0 behavior stays read-only.

If comments at arbitrary addresses are admitted for Ghidra (#6404), the export should include them.

Expected interaction with targets

  • Read existing files or captured data
  • Write or change files/configuration

Target and scope details (optional)

Reads the session database and writes one caller-selected output file; re-application reads that file. The target binary is never modified and no Ghidra project is saved. Non-goals: saving a Ghidra project, exporting types, prototypes or bookmarks, and general investigation notes (that is #4394, which could share the same storage decision).

Verification available so far

I can suggest a sample or manual check

Verification details (optional)

The success check above can run on the existing Ghidra verification fixture. Not run: no local Ghidra was available for this report.

Real-provider manual reapplication control

On macOS arm64, Node 24.22.1, Ghidra 12.1.4, Kuna 1.988 and REA 7abef04a5 (draft #8567), an owned, unexecuted Mach-O was opened with Ghidra and a data address was named rea_switch_label through set_address_name. The returned Evidence retained the exact address and name in its parameters and true readback. After explicitly switching to Kuna and reopening Ghidra, the name was absent while the original mutation Evidence ID was still discoverable. An explicit new set_address_name call using that record's address and name succeeded, and address_name read the label back. The target digest 87fa65dee009e59a8709a70a2aa731a0dc9cae47cf65d4c69292f7cad4897d93 was unchanged.

This is one manual same-target name control using the already returned Evidence; no automatic replay, independent file import, comment restoration, conflict handling or cross-target safety was tested. Separately, after an edit close_binary with snapshot_path refused with evidence_integrity_mismatch and left the edited session open. This confirms an Evidence record can help a caller explicitly reconstruct one edit, but is not an edited-database checkpoint and does not establish a safe general replay contract.

Function name and comments control

Using the same owned Mach-O and Ghidra/Kuna versions, annotate_native_function set a function name, a regular comment containing café, and an inline comment. The resulting Evidence retained all supplied parameters and exact readback. After switching to Kuna and reopening Ghidra, inspect_address_context showed the original function name; explicit reapplication of the retained parameters returned matching name and both comment readbacks. The prior annotation Evidence ID remained retained and the target hash was unchanged. This is still a manual same-target control, not a portable or automatic replay, conflict, identity-mismatch, or arbitrary-address comment test.

During this control, address context reported both comment facets unavailable even while analyze_function returned both comments in the active Ghidra session. This existing UX gap is tracked in #8363.

Selected historical annotation record

On main 85013da0c after #8528, real Ghidra 12.1.4 on macOS arm64 created function-annotation Evidence with a name, regular comment and inline comment on an owned Mach-O. After exporting the bundle and importing it into a fresh target-free MCP server, get_evidence_bundle with detail: "records" and the exact Evidence ID returned the complete original record unchanged in both compact and full output-schema profiles, including exact annotation readback. The response explicitly labels the selection historical and non-importable; no provider was opened in the importing session. The binary was unchanged and never executed.

This improves individual historical-record retrieval and supersedes the older full-inventory/full-bundle-only alternatives for this use. It does not restore an edited database, offer automatic replay, or settle conflict and identity rules for a portable annotation workflow.

Alternatives considered

  • list_names + filter + hand-written seed file: works but costs the full inventory per export, misses comments, and has no digest binding unless the agent adds one.
  • Saving a Ghidra project: outside REA's ephemeral-database contract.
  • Keeping the MCP session alive indefinitely: does not survive restarts or transport loss.

Possible direction

Reuse the IL2CPP seed-writer contract (atomic exclusive creation, docs/il2cpp-metadata.md) for output, and the existing REA_GHIDRA_SEED_FILE admission for names. The Ghidra bridge marks analyst edits with SourceType.USER_DEFINED, but seed-applied names carry the same source (bridge/ghidra/ReaGhidraApplySeeds.java), so filtering on source would export every seed as well (an IL2CPP seed file can hold up to a million entries). The session needs to track its own edits separately.

References

  • Design cautions: an annotation file needs program identity, not just addresses, and names should be re-applied as symbol edits rather than by rewriting FUN_ text in pseudocode.
  • Related: #1634 (closed; listed persistence as a non-goal), #4394, #5339, #3509, #1048, #3751.
Originally created by @coygeek on GitHub (Oct 22, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6405 ### Before submitting - [X] I searched the open and closed issues and pull requests for a related proposal. - [X] I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here. - [X] This request does not include credentials, private samples, or sensitive target data. ### Area Native analysis or decompilation ### Current limitation Names and comments an agent applies in a Ghidra session are lost when the session ends, and REA offers no compact way to carry them into the next session. Examined at REA `main` e83e3ceadd97770a50b8afa97f4077916e4d2b81 (source reading): - Session metadata edits "are discarded on close" (`docs/installation.md`; `docs/ghidra-dos.md`). Besides a deliberate `close_binary`, a server restart or a transport loss (#3509) ends the session and drops every name. - The import half already exists: `REA_GHIDRA_SEED_FILE` accepts `address<TAB>kind[<TAB>name]` lines and applies them before auto-analysis, with the seed digest bound into the analysis profile (`docs/installation.md`, seed section). - The export half is missing. The only route is to call `list_names`, which returns the complete symbol inventory in one response with no paging (`docs/ghidra-provider.md`, "Inventory" row), filter the items whose source is user-defined, and hand-write a seed file. On large targets that inventory is expensive in tokens, and entry comments written by `annotate_native_function` have no re-import path at all. - Opening a pre-analysed project read-only (#1048, #3751, open PR #3817) would save analysis time but would still discard new edits. ### Use cases - A multi-day investigation of a stripped binary: dozens of helpers and globals renamed in session 1 should still be named in session 2, so pseudocode stays readable. - Recovering after a transport loss or server restart without re-deriving every name. - Handing a set of names to a teammate or to a later build (together with `match_native_functions`) as a reviewable text file. ### Desired outcome and success criteria 1. An operation (or a `close_binary` option) writes the names applied during the session, and entry comments written through `annotate_native_function`, to a caller-selected file. Only analyst edits from this session are written, not the whole symbol inventory. 2. The file records the target SHA-256 and the analysis-profile identity of the session before any re-applied names, so it cannot be silently applied to a different binary. Because the seed digest is part of the analysis profile, the reopened session's profile will differ; the result should report both the recorded identity and the new one. 3. The file can be re-applied when the same target is reopened: names through the existing seed path (or a format the seed path accepts), comments through an equivalent open-time option. `REA_GHIDRA_SEED_FILE` takes a single path, so the design must say how an exported file combines with an existing seed file (for example IL2CPP seeds). 4. Re-applied names and comments are reported as caller-supplied assertions, as seeds already are, not as analysis results. 5. Success check: rename two functions and one data label and add one entry comment; export; close; reopen with the file. `address_name` returns the names, callers' `procedure_pseudo_code` shows them, and the comment reads back. A file whose digest does not match the target is refused with a typed error; an existing destination file is never overwritten; executable bytes stay unchanged; Windows P0 behavior stays read-only. If comments at arbitrary addresses are admitted for Ghidra (#6404), the export should include them. ### Expected interaction with targets - Read existing files or captured data - Write or change files/configuration ### Target and scope details (optional) Reads the session database and writes one caller-selected output file; re-application reads that file. The target binary is never modified and no Ghidra project is saved. Non-goals: saving a Ghidra project, exporting types, prototypes or bookmarks, and general investigation notes (that is #4394, which could share the same storage decision). ### Verification available so far I can suggest a sample or manual check ### Verification details (optional) The success check above can run on the existing Ghidra verification fixture. Not run: no local Ghidra was available for this report. ### Real-provider manual reapplication control On macOS arm64, Node 24.22.1, Ghidra 12.1.4, Kuna 1.988 and REA `7abef04a5` (draft #8567), an owned, unexecuted Mach-O was opened with Ghidra and a data address was named `rea_switch_label` through `set_address_name`. The returned Evidence retained the exact address and name in its parameters and `true` readback. After explicitly switching to Kuna and reopening Ghidra, the name was absent while the original mutation Evidence ID was still discoverable. An explicit new `set_address_name` call using that record's address and name succeeded, and `address_name` read the label back. The target digest `87fa65dee009e59a8709a70a2aa731a0dc9cae47cf65d4c69292f7cad4897d93` was unchanged. This is one manual same-target name control using the already returned Evidence; no automatic replay, independent file import, comment restoration, conflict handling or cross-target safety was tested. Separately, after an edit `close_binary` with `snapshot_path` refused with `evidence_integrity_mismatch` and left the edited session open. This confirms an Evidence record can help a caller explicitly reconstruct one edit, but is not an edited-database checkpoint and does not establish a safe general replay contract. ### Function name and comments control Using the same owned Mach-O and Ghidra/Kuna versions, `annotate_native_function` set a function name, a regular comment containing `café`, and an inline comment. The resulting Evidence retained all supplied parameters and exact readback. After switching to Kuna and reopening Ghidra, `inspect_address_context` showed the original function name; explicit reapplication of the retained parameters returned matching name and both comment readbacks. The prior annotation Evidence ID remained retained and the target hash was unchanged. This is still a manual same-target control, not a portable or automatic replay, conflict, identity-mismatch, or arbitrary-address comment test. During this control, address context reported both comment facets unavailable even while `analyze_function` returned both comments in the active Ghidra session. This existing UX gap is tracked in #8363. ### Selected historical annotation record On main `85013da0c` after #8528, real Ghidra 12.1.4 on macOS arm64 created function-annotation Evidence with a name, regular comment and inline comment on an owned Mach-O. After exporting the bundle and importing it into a fresh target-free MCP server, `get_evidence_bundle` with `detail: "records"` and the exact Evidence ID returned the complete original record unchanged in both compact and full output-schema profiles, including exact annotation readback. The response explicitly labels the selection historical and non-importable; no provider was opened in the importing session. The binary was unchanged and never executed. This improves individual historical-record retrieval and supersedes the older full-inventory/full-bundle-only alternatives for this use. It does not restore an edited database, offer automatic replay, or settle conflict and identity rules for a portable annotation workflow. ### Alternatives considered - `list_names` + filter + hand-written seed file: works but costs the full inventory per export, misses comments, and has no digest binding unless the agent adds one. - Saving a Ghidra project: outside REA's ephemeral-database contract. - Keeping the MCP session alive indefinitely: does not survive restarts or transport loss. ### Possible direction Reuse the IL2CPP seed-writer contract (atomic exclusive creation, `docs/il2cpp-metadata.md`) for output, and the existing `REA_GHIDRA_SEED_FILE` admission for names. The Ghidra bridge marks analyst edits with `SourceType.USER_DEFINED`, but seed-applied names carry the same source (`bridge/ghidra/ReaGhidraApplySeeds.java`), so filtering on source would export every seed as well (an IL2CPP seed file can hold up to a million entries). The session needs to track its own edits separately. ### References - Design cautions: an annotation file needs program identity, not just addresses, and names should be re-applied as symbol edits rather than by rewriting `FUN_` text in pseudocode. - Related: #1634 (closed; listed persistence as a non-goal), #4394, #5339, #3509, #1048, #3751.
Author
Owner

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

Real REA/Ghidra 12.1.4 MCP follow-up on one self-built Mach-O clarifies an existing, limited recovery option and why an Evidence bundle is not an edit journal.

In two fresh sessions I applied the same two explicit name/comment changes to the same function in opposite orders (alpha then beta, and beta then alpha). The live final pseudocode respectively showed beta/note_beta and alpha/note_alpha. Both sessions produced the same two annotation Evidence IDs, and both exported bundles ordered those records the same way. Other Evidence in the bundles differed because I also captured each final pseudocode. Thus the annotation records alone cannot establish which of those changes was last; bundle order is canonical by Evidence ID, not chronological. This is expected for historical Evidence and is not a bug in the bundle contract.

In a third fresh session I imported the first bundle: the live pseudocode remained unedited. get_evidence_bundle with an operation-filtered summary discovered both annotation records and their target/profile metadata. I retrieved the complete bundle, explicitly selected the known beta record from my recorded sequence, checked its target SHA-256 and analysis-profile digest against the current session, and invoked annotate_native_function on its recorded address with the selected name and comment. Live pseudocode then reflected that edit. The binary hash was unchanged. This was a manually selected replay of one function's name and regular entry comment, not automatic restoration, conflict resolution, data-label or inline-comment coverage, or a guarantee for a changed profile.

For bounded access, inspect_analysis_view rejected both summary and native procedure views of the annotation Evidence as an unsupported parent operation. Its filtered discovery summary exposes the record identity and provenance but not the annotation payload; my script used get_evidence_bundle complete for this small bundle. That does not establish a measured large-bundle failure. A prospective export/replay design should retain the current final state or explicit ordering and handle conflicts/clears; it must not infer edit order from Evidence IDs or silently apply stale observations.

<!-- gh-comment-id:6534371751 --> @morluto commented on GitHub (Oct 30, 2026): Real REA/Ghidra 12.1.4 MCP follow-up on one self-built Mach-O clarifies an existing, limited recovery option and why an Evidence bundle is not an edit journal. In two fresh sessions I applied the same two explicit name/comment changes to the same function in opposite orders (`alpha` then `beta`, and `beta` then `alpha`). The live final pseudocode respectively showed `beta`/`note_beta` and `alpha`/`note_alpha`. Both sessions produced the *same two annotation Evidence IDs*, and both exported bundles ordered those records the same way. Other Evidence in the bundles differed because I also captured each final pseudocode. Thus the annotation records alone cannot establish which of those changes was last; bundle order is canonical by Evidence ID, not chronological. This is expected for historical Evidence and is not a bug in the bundle contract. In a third fresh session I imported the first bundle: the live pseudocode remained unedited. `get_evidence_bundle` with an operation-filtered summary discovered both annotation records and their target/profile metadata. I retrieved the complete bundle, explicitly selected the known `beta` record from my recorded sequence, checked its target SHA-256 and analysis-profile digest against the current session, and invoked `annotate_native_function` on its recorded address with the selected name and comment. Live pseudocode then reflected that edit. The binary hash was unchanged. This was a manually selected replay of one function's name and regular entry comment, not automatic restoration, conflict resolution, data-label or inline-comment coverage, or a guarantee for a changed profile. For bounded access, `inspect_analysis_view` rejected both summary and native procedure views of the annotation Evidence as an unsupported parent operation. Its filtered discovery summary exposes the record identity and provenance but not the annotation payload; my script used `get_evidence_bundle` complete for this small bundle. That does not establish a measured large-bundle failure. A prospective export/replay design should retain the current final state or explicit ordering and handle conflicts/clears; it must not infer edit order from Evidence IDs or silently apply stale observations.
Author
Owner

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

The inventory alternative in the original report needs an update for current REA: list_names({detail:"summary"}) retains the complete observed inventory and returns counts plus a parent Evidence ID; inspect_analysis_view with kind:"native-inventory" pages the rows and can select fields. It is no longer necessary to transfer the whole inventory in one response. The view reports discovery coverage as unknown and its current request offers offset/limit and fields, not a source-type filter, so identifying all user-defined rows still requires examining the relevant pages. This small fixture is not a large-target token or latency measurement.

I exercised a real Ghidra 12.1.4 MCP session on an owned Mach-O with one pre-analysis label seed, one session data-label edit and one session function rename/comment. The seeded label, edited data label and edited function all appeared as symbol.source: user_defined in paged list_names results. The seed path/digest and caller-assertion limitation were separately retained in the analysis profile; the row's source classification alone did not distinguish a seed from a session edit. Paging all 24 observed rows in pages of four found the three names, while the function's comment remained in the annotation Evidence rather than this names inventory. The target SHA-256 was unchanged and the target was not executed.

This supports retaining current session edit identity and comment state separately from the full symbol inventory, while recognizing that bounded inventory delivery already exists. It does not prove general edit-export or replay behavior, and does not claim that all user-defined names are session edits.

<!-- gh-comment-id:6534574967 --> @morluto commented on GitHub (Oct 30, 2026): The inventory alternative in the original report needs an update for current REA: `list_names({detail:"summary"})` retains the complete observed inventory and returns counts plus a parent Evidence ID; `inspect_analysis_view` with `kind:"native-inventory"` pages the rows and can select fields. It is no longer necessary to transfer the whole inventory in one response. The view reports discovery coverage as unknown and its current request offers offset/limit and fields, not a source-type filter, so identifying all user-defined rows still requires examining the relevant pages. This small fixture is not a large-target token or latency measurement. I exercised a real Ghidra 12.1.4 MCP session on an owned Mach-O with one pre-analysis label seed, one session data-label edit and one session function rename/comment. The seeded label, edited data label and edited function all appeared as `symbol.source: user_defined` in paged `list_names` results. The seed path/digest and caller-assertion limitation were separately retained in the analysis profile; the row's source classification alone did not distinguish a seed from a session edit. Paging all 24 observed rows in pages of four found the three names, while the function's comment remained in the annotation Evidence rather than this names inventory. The target SHA-256 was unchanged and the target was not executed. This supports retaining current session edit identity and comment state separately from the full symbol inventory, while recognizing that bounded inventory delivery already exists. It does not prove general edit-export or replay behavior, and does not claim that all user-defined names are session edits.
Author
Owner

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

A real Ghidra batch-naming control adds an ordering case for any future export/replay design. Two independent sessions submitted the same mapping of two mapped addresses to one name, with opposite JSON object key order. Each session applied the first address and returned false for the second; the winning address differed. Both exported Evidence records correctly retained their opposite per-address Boolean results, but their canonical parameters.names mappings were identical and did not record input member order. #8238 tracks the existing mutation-order question; #8239 discusses per-item failure explanations.

This does not make the Evidence bundle an edit journal or establish that automatic replay exists. A future replay should not infer the original order from the canonical object, blindly retry failed mutations, or treat failed entries as applied. Both target digests stayed unchanged and the binary was not executed.

<!-- gh-comment-id:6535110438 --> @morluto commented on GitHub (Oct 30, 2026): A real Ghidra batch-naming control adds an ordering case for any future export/replay design. Two independent sessions submitted the same mapping of two mapped addresses to one name, with opposite JSON object key order. Each session applied the first address and returned `false` for the second; the winning address differed. Both exported Evidence records correctly retained their opposite per-address Boolean results, but their canonical `parameters.names` mappings were identical and did not record input member order. #8238 tracks the existing mutation-order question; #8239 discusses per-item failure explanations. This does not make the Evidence bundle an edit journal or establish that automatic replay exists. A future replay should not infer the original order from the canonical object, blindly retry failed mutations, or treat failed entries as applied. Both target digests stayed unchanged and the binary was not executed.
Author
Owner

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

Real MCP follow-up on the same self-owned, unexecuted Mach-O, Ghidra 12.1.4 / Kuna 1.986 / REA b43c329:

  1. Set a function name, regular comment, and inline comment. A second edit omitted the name, explicitly cleared the regular comment with "", and changed the inline comment. Its complete annotation readback retained the name, represented the cleared comment as null, and returned the new inline comment.
  2. Switch to Kuna and back to Ghidra. A fresh function dossier showed the original name. Retrieve the complete retained Evidence bundle, explicitly select the second edit by the ID recorded at the time, and compare the record's target SHA-256 and analysis-profile digest with the current target/dossier.
  3. For a meaningful clear control, deliberately set a different name and both comments in the new Ghidra session. Explicitly reapply the selected readback, mapping its null regular comment to "". The returned readback matched the selected name, absent regular comment, and inline comment. Close succeeded; target hash stayed unchanged.

This is a manual, caller-directed recovery of one selected complete readback, not automatic replay or a conflict-safe general checkpoint. The second input omitted the name, so replaying just its original parameters would not restore the full selected readback after a fresh import. null is not a valid comment input and mapping it to "" intentionally clears existing comments; that choice needs to be explicit. Selection used a separately retained Evidence ID, not bundle sort order. Other addresses, conflicts, selected projects, incompatible profiles, bulk labels, and automatic sequencing remain untested. Related provider-switch UX: #8289.

For maintainer visibility: @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

<!-- gh-comment-id:6541990498 --> @morluto commented on GitHub (Oct 31, 2026): Real MCP follow-up on the same self-owned, unexecuted Mach-O, Ghidra 12.1.4 / Kuna 1.986 / REA `b43c329`: 1. Set a function name, regular comment, and inline comment. A second edit omitted the name, explicitly cleared the regular comment with `""`, and changed the inline comment. Its complete annotation readback retained the name, represented the cleared comment as `null`, and returned the new inline comment. 2. Switch to Kuna and back to Ghidra. A fresh function dossier showed the original name. Retrieve the complete retained Evidence bundle, explicitly select the second edit by the ID recorded at the time, and compare the record's target SHA-256 and analysis-profile digest with the current target/dossier. 3. For a meaningful clear control, deliberately set a different name and both comments in the new Ghidra session. Explicitly reapply the selected readback, mapping its `null` regular comment to `""`. The returned readback matched the selected name, absent regular comment, and inline comment. Close succeeded; target hash stayed unchanged. This is a manual, caller-directed recovery of one selected complete readback, not automatic replay or a conflict-safe general checkpoint. The second input omitted the name, so replaying just its original parameters would not restore the full selected readback after a fresh import. `null` is not a valid comment input and mapping it to `""` intentionally clears existing comments; that choice needs to be explicit. Selection used a separately retained Evidence ID, not bundle sort order. Other addresses, conflicts, selected projects, incompatible profiles, bulk labels, and automatic sequencing remain untested. Related provider-switch UX: #8289. For maintainer visibility: @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0
Author
Owner

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

Data-label recovery control on the same unexecuted Mach-O, real REA MCP b43c329, Ghidra 12.1.4 and Kuna 1.986: set_address_name assigned audit_count_label to global address 0x100004000 and returned true. Attempting the same name on the separate 0x100004008 global returned false; address_name confirmed the second address retained _message. Both successful and unsuccessful edit observations appeared as separate complete retained Evidence records.

After Ghidra → Kuna → Ghidra switching, address_name reported the original _global_count and _message. A caller explicitly selected the successful record by its captured ID, verified target SHA-256 and profile digest, reapplied its recorded address/name, and checked both names. The intended label returned; the failed conflicting request was not replayed and the other global remained unchanged. The repeated successful edit produced the same Evidence ID as the first. Close succeeded and the target hash was unchanged.

This is one caller-directed reapplication with an explicit readback, not an automatic bulk restore, conflict-resolution policy, or chronology inferred from Evidence IDs. It demonstrates that a successful boolean and a failed boolean can both be retained; a future replay workflow must distinguish outcomes and coordinate/target identity rather than treating every recorded edit request as applied. The existing #8239 tracks the separate lack of per-item failure reasons. Related switch behavior: #8289.

For maintainer visibility: @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

<!-- gh-comment-id:6542002802 --> @morluto commented on GitHub (Oct 31, 2026): Data-label recovery control on the same unexecuted Mach-O, real REA MCP `b43c329`, Ghidra 12.1.4 and Kuna 1.986: `set_address_name` assigned `audit_count_label` to global address `0x100004000` and returned `true`. Attempting the same name on the separate `0x100004008` global returned `false`; `address_name` confirmed the second address retained `_message`. Both successful and unsuccessful edit observations appeared as separate complete retained Evidence records. After Ghidra → Kuna → Ghidra switching, `address_name` reported the original `_global_count` and `_message`. A caller explicitly selected the successful record by its captured ID, verified target SHA-256 and profile digest, reapplied its recorded address/name, and checked both names. The intended label returned; the failed conflicting request was not replayed and the other global remained unchanged. The repeated successful edit produced the same Evidence ID as the first. Close succeeded and the target hash was unchanged. This is one caller-directed reapplication with an explicit readback, not an automatic bulk restore, conflict-resolution policy, or chronology inferred from Evidence IDs. It demonstrates that a successful boolean and a failed boolean can both be retained; a future replay workflow must distinguish outcomes and coordinate/target identity rather than treating every recorded edit request as applied. The existing #8239 tracks the separate lack of per-item failure reasons. Related switch behavior: #8289. For maintainer visibility: @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0
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#3835
No description provided.