[GH-ISSUE #8244] [Bug] File-offset lookup advises schema repair for a valid unbacked address #6511

Closed
opened 2026-11-01 21:11:48 +00:00 by bsakaguchi · 3 comments
Owner

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

Originally assigned to: @kaoru0822-kitauji on GitHub.

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

address_to_file_offset accepts a syntactically valid address in a loaded Ghidra .bss block, but the error headline says the input is invalid and recovery directs the caller to fix the schema. The actual reason, Address has no initialized file-backed memory: 0x403010, survives in the nested issue and diagnostics. Correctly refusing to invent a file offset is not the bug; the misleading headline and recovery are.

Reproduction

On REA 53a4ab78451a0654e9c3beb3d43a5e371a288fcc, Ghidra 12.1.4 and a self-built x86-64 ELF, llvm-readelf reported .data at 0x403000..0x40300f and NOBITS .bss at 0x403010..0x40302f. The data load segment has file size 0x10 and memory size 0x30. Open it with REA/Ghidra and call MCP address_to_file_offset for 0x403010; the operation returns an error with the output below. The same address through rea address-to-file-offset <fixture> 0x403010 --provider ghidra --format json exited 1 with the same headline, recovery and nested reason. The last data address 0x40300f returned offset 8207. Ghidra's load-image observation separately identified .bss as loaded, uninitialized and without a file offset. Each adapter was exercised once; frequency beyond that is unknown. The target was not executed or modified.

Expected behavior

Expose the non-file-backed outcome prominently and give context-appropriate recovery, such as inspecting load-image mappings or choosing an address known to have a source mapping. Preserve the exact caller address and distinguish absent, ambiguous and otherwise unavailable mappings. Do not invent an offset or imply a syntactically malformed request. The expected UX follows the documented operation's purpose of mapping an analysis address to original file bytes; the exact error type is a design question.

Impact and scope

An agent following the displayed recovery may edit a valid request or inspect the schema instead of understanding that this address has no source bytes. The nested issue preserves the reason, so this is not total evidence loss. Only the Ghidra ELF example and the two adapter calls above were tested; other causes and providers remain unverified.

REA version

53a4ab78451a0654e9c3beb3d43a5e371a288fcc

Runtime and platform

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

Target and artifact context

Self-built x86-64 ELF executable; no target execution; SHA-256 0da0aaf5e5397516db7d6f8f51afd7305bd6fa8cea2259aa93d953ca5cc0b0e6 unchanged.

Interface

MCP and CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

MCP: code: invalid_request, message Analysis input is invalid. Check the arguments and try again., remediation Read the declared input schema or CLI usage ... Correct the listed fields, then retry. The nested details.issues[0].message is Address has no initialized file-backed memory: 0x403010.

Typed outcome or recovery expected

Preserve a meaningful non-file-backed reason and applicable recovery at the top level, with equivalent CLI/MCP semantics. Avoid classifying unrelated failures solely by parsing arbitrary message text.

Analysis or suspected cause

Source-derived: addressToFileOffset reports this condition as invalid_request; GhidraProviderClient maps remote input failures into an AnalysisInputError with the provider message as a nested issue. These explain the observed projection; a precise replacement contract and its compatibility need investigation.

Additional context

Related #8170 concerns byte-view and mapping semantics; #8208 covers missing-function recovery for selected projects. Neither proposes inventing mappings.

Originally created by @morluto on GitHub (Oct 30, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8244 Originally assigned to: @kaoru0822-kitauji on GitHub. ### 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 `address_to_file_offset` accepts a syntactically valid address in a loaded Ghidra `.bss` block, but the error headline says the input is invalid and recovery directs the caller to fix the schema. The actual reason, `Address has no initialized file-backed memory: 0x403010`, survives in the nested issue and diagnostics. Correctly refusing to invent a file offset is not the bug; the misleading headline and recovery are. ### Reproduction On REA `53a4ab78451a0654e9c3beb3d43a5e371a288fcc`, Ghidra 12.1.4 and a self-built x86-64 ELF, `llvm-readelf` reported `.data` at `0x403000..0x40300f` and NOBITS `.bss` at `0x403010..0x40302f`. The data load segment has file size `0x10` and memory size `0x30`. Open it with REA/Ghidra and call MCP `address_to_file_offset` for `0x403010`; the operation returns an error with the output below. The same address through `rea address-to-file-offset <fixture> 0x403010 --provider ghidra --format json` exited 1 with the same headline, recovery and nested reason. The last data address `0x40300f` returned offset `8207`. Ghidra's load-image observation separately identified `.bss` as loaded, uninitialized and without a file offset. Each adapter was exercised once; frequency beyond that is unknown. The target was not executed or modified. ### Expected behavior Expose the non-file-backed outcome prominently and give context-appropriate recovery, such as inspecting load-image mappings or choosing an address known to have a source mapping. Preserve the exact caller address and distinguish absent, ambiguous and otherwise unavailable mappings. Do not invent an offset or imply a syntactically malformed request. The expected UX follows the documented operation's purpose of mapping an analysis address to original file bytes; the exact error type is a design question. ### Impact and scope An agent following the displayed recovery may edit a valid request or inspect the schema instead of understanding that this address has no source bytes. The nested issue preserves the reason, so this is not total evidence loss. Only the Ghidra ELF example and the two adapter calls above were tested; other causes and providers remain unverified. ### REA version `53a4ab78451a0654e9c3beb3d43a5e371a288fcc` ### Runtime and platform Node 24.22.1; macOS arm64; Ghidra 12.1.4; JDK 21. ### Target and artifact context Self-built x86-64 ELF executable; no target execution; SHA-256 `0da0aaf5e5397516db7d6f8f51afd7305bd6fa8cea2259aa93d953ca5cc0b0e6` unchanged. ### Interface MCP and CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence MCP: `code: invalid_request`, message `Analysis input is invalid. Check the arguments and try again.`, remediation `Read the declared input schema or CLI usage ... Correct the listed fields, then retry.` The nested `details.issues[0].message` is `Address has no initialized file-backed memory: 0x403010`. ### Typed outcome or recovery expected Preserve a meaningful non-file-backed reason and applicable recovery at the top level, with equivalent CLI/MCP semantics. Avoid classifying unrelated failures solely by parsing arbitrary message text. ### Analysis or suspected cause Source-derived: [`addressToFileOffset`](https://github.com/morluto/rea/blob/53a4ab78451a0654e9c3beb3d43a5e371a288fcc/bridge/ghidra/ReaGhidraBridge.java#L921-L935) reports this condition as `invalid_request`; [`GhidraProviderClient`](https://github.com/morluto/rea/blob/53a4ab78451a0654e9c3beb3d43a5e371a288fcc/src/ghidra/GhidraProviderClient.ts#L1127-L1132) maps remote input failures into an `AnalysisInputError` with the provider message as a nested issue. These explain the observed projection; a precise replacement contract and its compatibility need investigation. ### Additional context Related [#8170](https://github.com/morluto/rea/issues/8170#issuecomment-6535266695) concerns byte-view and mapping semantics; [#8208](https://github.com/morluto/rea/issues/8208) covers missing-function recovery for selected projects. Neither proposes inventing mappings.
bsakaguchi 2026-11-01 21:11:48 +00:00
  • closed this issue
  • added the
    bug
    triage
    labels
Author
Owner

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

Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.

<!-- gh-comment-id:6538809075 --> @morluto commented on GitHub (Oct 31, 2026): Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.
Author
Owner

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

Additional controls on current main 245a5818, using the same unexecuted ELF with real Ghidra 12.1.4 and stdio MCP:

Input Independent/current observation address_to_file_offset
0x40300f Last byte of file-backed .data Success, offset 8207
0x403010 First byte of loaded, uninitialized .bss invalid_request; nested reason says no initialized file-backed memory
0x403030 Just beyond .bss, outside the reported blocks Same headline, recovery and nested reason as BSS, except for address
.shstrtab:0x0 Initialized, file-backed overlay marked loaded:false Success, offset 8304
not-an-address Malformed address syntax Same headline and schema-repair recovery; nested validation issue identifies address and invalid_format

inspect_native_load_image reports the BSS block and file-backed overlay, though independent load-image verification remains unsupported for ELF. The distinction between BSS and unmapped is also lost at the provider boundary: the bridge checks both cases together, before REA's generic input-error projection. A fix confined to changing the top-level message cannot by itself distinguish those cases, and a loaded check alone would incorrectly reject the file-backed overlay. This is not a request to invent a mapping for BSS or to infer mapping solely from a block name. The fixture hash was unchanged; these are single-provider, single-fixture controls.

<!-- gh-comment-id:6540509668 --> @morluto commented on GitHub (Oct 31, 2026): Additional controls on current main `245a5818`, using the same unexecuted ELF with real Ghidra 12.1.4 and stdio MCP: | Input | Independent/current observation | `address_to_file_offset` | | --- | --- | --- | | `0x40300f` | Last byte of file-backed `.data` | Success, offset 8207 | | `0x403010` | First byte of loaded, uninitialized `.bss` | `invalid_request`; nested reason says no initialized file-backed memory | | `0x403030` | Just beyond `.bss`, outside the reported blocks | Same headline, recovery and nested reason as BSS, except for address | | `.shstrtab:0x0` | Initialized, file-backed overlay marked `loaded:false` | Success, offset 8304 | | `not-an-address` | Malformed address syntax | Same headline and schema-repair recovery; nested validation issue identifies `address` and `invalid_format` | `inspect_native_load_image` reports the BSS block and file-backed overlay, though independent load-image verification remains unsupported for ELF. The distinction between BSS and unmapped is also lost at the provider boundary: [the bridge checks both cases together](https://github.com/morluto/rea/blob/245a581818ab13694fa438a06e39898ce03ab206/bridge/ghidra/ReaGhidraBridge.java#L925-L930), before REA's generic input-error projection. A fix confined to changing the top-level message cannot by itself distinguish those cases, and a `loaded` check alone would incorrectly reject the file-backed overlay. This is not a request to invent a mapping for BSS or to infer mapping solely from a block name. The fixture hash was unchanged; these are single-provider, single-fixture controls.
Author
Owner

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

Real-provider follow-up for merged #8308 on REA c287a73276a7f751ca65a8cc2219a29d5914bc2c, macOS arm64, Node 24.22.1 and Ghidra 12.1.4:

  • On the original unexecuted x86-64 ELF fixture, real MCP mapped the last file-backed data byte to offset 8207 and a file-backed, non-loaded .shstrtab overlay to 8304. .bss returned file_mapping: uninitialized, the adjacent unmapped address returned file_mapping: unmapped; each headline stated the reason, recommended inspecting load-image mappings and omitted schema-repair recovery. Malformed address syntax still returned invalid_format and inspect_input_contract. The same live session continued through all calls and closed. The fixture SHA-256 was unchanged.
  • Real CLI address-to-file-offset on the .bss address exited 1 with the same specific uninitialized outcome and no schema-repair recovery. This is one CLI error control, not full CLI parity for all outcomes.
  • Separately, the repository's ReaFileOffsetSourceProbe.java ran successfully via Ghidra headless on the repository-generated source-owned x86-64 PE fixture, with the REA_FILE_OFFSET_SOURCE_OK marker and no logged script errors. It exercised foreign/partial source rejection, uninitialized/unmapped distinctions, original target round trip, and duplicate loaded-mapping ambiguity. Its decompiler failure/cancellation cases are explicitly injected and do not prove natural engine failure. The probe edits only its temporary Ghidra program; neither fixture was executed.

This establishes these cases on a macOS host, not Windows-host behavior, Hopper, real unrepresentable offsets, or naturally ambiguous reverse mappings.

<!-- gh-comment-id:6545771177 --> @morluto commented on GitHub (Oct 31, 2026): Real-provider follow-up for merged #8308 on REA `c287a73276a7f751ca65a8cc2219a29d5914bc2c`, macOS arm64, Node 24.22.1 and Ghidra 12.1.4: - On the original unexecuted x86-64 ELF fixture, real MCP mapped the last file-backed data byte to offset 8207 and a file-backed, non-loaded `.shstrtab` overlay to 8304. `.bss` returned `file_mapping: uninitialized`, the adjacent unmapped address returned `file_mapping: unmapped`; each headline stated the reason, recommended inspecting load-image mappings and omitted schema-repair recovery. Malformed address syntax still returned `invalid_format` and `inspect_input_contract`. The same live session continued through all calls and closed. The fixture SHA-256 was unchanged. - Real CLI `address-to-file-offset` on the `.bss` address exited 1 with the same specific uninitialized outcome and no schema-repair recovery. This is one CLI error control, not full CLI parity for all outcomes. - Separately, the repository's `ReaFileOffsetSourceProbe.java` ran successfully via Ghidra headless on the repository-generated source-owned x86-64 PE fixture, with the `REA_FILE_OFFSET_SOURCE_OK` marker and no logged script errors. It exercised foreign/partial source rejection, uninitialized/unmapped distinctions, original target round trip, and duplicate loaded-mapping ambiguity. Its decompiler failure/cancellation cases are explicitly injected and do not prove natural engine failure. The probe edits only its temporary Ghidra program; neither fixture was executed. This establishes these cases on a macOS host, not Windows-host behavior, Hopper, real unrepresentable offsets, or naturally ambiguous reverse mappings.
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#6511
No description provided.