[GH-ISSUE #8583] fix(ghidra): clarify interior selectors before function annotation #6658

Open
opened 2026-11-01 21:13:00 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @morluto on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8583

Before submitting

  • I searched open and closed issues for related reports.
  • This report contains no private target data or credentials.

Area

Native analysis or decompilation / MCP and CLI.

Observed behavior

annotate_native_function accepts a Ghidra address inside a function and writes its comment at the containing function's entry. The successful result reports the actual entry address, and Evidence retains the requested address, but the MCP input schema does not explain this resolution before the edit. The CLI describes its procedure argument as an exact function entry address or unique name.

Reproduction

On REA 85013da0c, macOS arm64, Node 24.22.1, Ghidra 12.1.4 and JDK 21, open an owned source-built Mach-O in a fresh Ghidra MCP session. Its _evaluate function starts at 0x100000430; 0x100000434 is an interior instruction. Call annotate_native_function({procedure:"0x100000434",comment:"interior-note"}). In both compact and full schema profiles the call succeeds and returns annotations.address: "0x100000430" with the requested comment. Evidence parameters retain procedure: "0x100000434". The reported limitation says regular comments map to PRE at the exact function entry. set_comment at the interior address is unavailable for Ghidra.

A real CLI control on #8567 head 757f2646 with rea annotate-native-function <target> 0x100000434 --comment interior-note --provider ghidra --format json also succeeds and reports the entry address. The target SHA-256 ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d was unchanged; edits were confined to ephemeral Ghidra session databases and the target was not executed. REA 85013da0c differs from current main ce9095d72 by unrelated changes; this behavior was not separately exercised at ce9095d72.

Expected behavior

Make the pre-mutation contract unambiguous and preserve caller intent. Consider requiring an exact entry for address-based edits, or explicitly requiring/recording a containing-function selection before mutation; account for names and any documented selector conventions. Do not silently treat an interior-instruction comment request as an arbitrary-address edit. Preserve requested and actual addresses, transactional readback, and rollback semantics.

Impact and scope

One owned arm64 Mach-O and Ghidra 12.1.4 on macOS arm64. The action is limited to REA's ephemeral database; the successful result identifies the entry and does not claim to edit the requested instruction. This is a selector-contract and agent-UX concern, not a claim of target-byte mutation, runtime behavior, or a measured agent error rate.

REA version

MCP: 85013da0c; CLI: #8567 757f2646.

Runtime and platform

macOS arm64, Node 24.22.1, Ghidra 12.1.4, JDK 21.

Target and artifact context

Self-built, unexecuted Mach-O; digest above.

Interface

MCP compact and full output profiles; CLI JSON.

Earliest failure stage

Function selector resolution before mutation.

Relevant output or evidence

Requested 0x100000434; returned annotations.address 0x100000430, regular comment interior-note. MCP Evidence includes the requested selector and entry-comment limitations. CLI exits zero and reports the same addresses.

Typed outcome or recovery expected

Make the effective mutation address explicit before any write when the selector can resolve to another address, or reject the non-entry selector with actionable guidance. Verify exact entry, interior, name, alias, external, ambiguous and unmapped selectors; ensure invalid edits leave session metadata unchanged.

Analysis or suspected cause

Source inspection: annotateNativeFunction calls the shared resolveProcedure; its functionAtOrContaining fallback accepts an interior memory address, then the annotation writes function.getEntryPoint(). This shared read-resolution rule is also used by non-mutating operations, so changes should target mutation ownership rather than inadvertently changing read semantics.

Additional context

Related #6404 covers the separate arbitrary-address comment question. #8567 proposes a conditional function-entry handoff for unavailable direct comments; this control supports keeping that condition explicit.

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8583 ### Before submitting - [x] I searched open and closed issues for related reports. - [x] This report contains no private target data or credentials. ### Area Native analysis or decompilation / MCP and CLI. ### Observed behavior `annotate_native_function` accepts a Ghidra address inside a function and writes its comment at the containing function's entry. The successful result reports the actual entry address, and Evidence retains the requested address, but the MCP input schema does not explain this resolution before the edit. The CLI describes its `procedure` argument as an exact function entry address or unique name. ### Reproduction On REA `85013da0c`, macOS arm64, Node 24.22.1, Ghidra 12.1.4 and JDK 21, open an owned source-built Mach-O in a fresh Ghidra MCP session. Its `_evaluate` function starts at `0x100000430`; `0x100000434` is an interior instruction. Call `annotate_native_function({procedure:"0x100000434",comment:"interior-note"})`. In both compact and full schema profiles the call succeeds and returns `annotations.address: "0x100000430"` with the requested comment. Evidence parameters retain `procedure: "0x100000434"`. The reported limitation says regular comments map to PRE at the exact function entry. `set_comment` at the interior address is unavailable for Ghidra. A real CLI control on #8567 head `757f2646` with `rea annotate-native-function <target> 0x100000434 --comment interior-note --provider ghidra --format json` also succeeds and reports the entry address. The target SHA-256 `ffad1b70c6a5a7ef3f7c3f59126be516520210777d949b35e97c9067f272aa2d` was unchanged; edits were confined to ephemeral Ghidra session databases and the target was not executed. REA `85013da0c` differs from current main `ce9095d72` by unrelated changes; this behavior was not separately exercised at `ce9095d72`. ### Expected behavior Make the pre-mutation contract unambiguous and preserve caller intent. Consider requiring an exact entry for address-based edits, or explicitly requiring/recording a containing-function selection before mutation; account for names and any documented selector conventions. Do not silently treat an interior-instruction comment request as an arbitrary-address edit. Preserve requested and actual addresses, transactional readback, and rollback semantics. ### Impact and scope One owned arm64 Mach-O and Ghidra 12.1.4 on macOS arm64. The action is limited to REA's ephemeral database; the successful result identifies the entry and does not claim to edit the requested instruction. This is a selector-contract and agent-UX concern, not a claim of target-byte mutation, runtime behavior, or a measured agent error rate. ### REA version MCP: `85013da0c`; CLI: #8567 `757f2646`. ### Runtime and platform macOS arm64, Node 24.22.1, Ghidra 12.1.4, JDK 21. ### Target and artifact context Self-built, unexecuted Mach-O; digest above. ### Interface MCP compact and full output profiles; CLI JSON. ### Earliest failure stage Function selector resolution before mutation. ### Relevant output or evidence Requested `0x100000434`; returned `annotations.address` `0x100000430`, regular comment `interior-note`. MCP Evidence includes the requested selector and entry-comment limitations. CLI exits zero and reports the same addresses. ### Typed outcome or recovery expected Make the effective mutation address explicit before any write when the selector can resolve to another address, or reject the non-entry selector with actionable guidance. Verify exact entry, interior, name, alias, external, ambiguous and unmapped selectors; ensure invalid edits leave session metadata unchanged. ### Analysis or suspected cause Source inspection: `annotateNativeFunction` calls the shared `resolveProcedure`; its `functionAtOrContaining` fallback accepts an interior memory address, then the annotation writes `function.getEntryPoint()`. This shared read-resolution rule is also used by non-mutating operations, so changes should target mutation ownership rather than inadvertently changing read semantics. ### Additional context Related #6404 covers the separate arbitrary-address comment question. #8567 proposes a conditional function-entry handoff for unavailable direct comments; this control supports keeping that condition explicit. cc @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#6658
No description provided.