[GH-ISSUE #4487] [Feature] Ghidra RISC-V lane: admit position-independent executables (ET_DYN); distro riscv64 binaries are almost all PIE #1776

Open
opened 2026-10-16 21:10:08 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

  • I searched the open and closed issues for a related report (riscv ET_DYN, riscv PIE, RISC-V shared, riscv dynamic). #2063 and #2151 added the lane and are closed; I found no follow-up for PIE.
  • I understand the contribution scope.
  • This report contains no credentials or private target samples.

Area

Native analysis or decompilation

Current limitation

The RISC-V Ghidra lane admits only ET_EXEC (docs/ghidra-riscv.md, src/ghidra/GhidraRiscvProfile.ts:61), and the refusal is clear:

{"provider_id":"ghidra","code":"architecture_unsupported",
 "reason":"This Ghidra RISC-V lane supports fixed-address ET_EXEC only; shared and position-independent images need separate load verification. ET_EXEC alone does not establish static linkage, which this lane does not inspect."}

But distributions build riscv64 userland as PIE. In Debian trixie riscv64, coreutils 9.7-3 has 106 ET_DYN ELF files and 0 ET_EXEC (for example /usr/bin/ls: "pie executable … dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1", e_flags 0x5). The only ET_EXEC I found was a static build, busybox-static. So on real Linux riscv64 targets the lane refuses nearly every binary. The e_flags profile (RVC + double-float ABI) would otherwise be admitted.

For the case it does admit, the lane is accurate. Debian busybox-static 1:1.37.0-6+b9 riscv64 (ET_EXEC, e_flags 0x5), rea-agents@6.5.0, Ghidra 12.1.4:

  • 104 s import.
  • Allocated section addresses and sizes match readelf -S.
  • All 13 entry instructions (0x103a0, a 38-byte body) match riscv64-linux-gnu-objdump -d -M no-aliases (j versus jal zero is only an alias).
  • The __libc_start_main callee decompiles readably, including the R_RISCV_IRELATIVE (58) loop over .rela.plt.

So the decoding side is ready for PIE images too.

Desired outcome and success criteria

  • Admit little-endian ET_DYN images that are executables. That means PT_INTERP present, or the existing ELF executable-versus-library classification, with the same e_flags profile, pinned language and compiler specification. Record the load base Ghidra applied and the load model in the lane identity and analysis profile, as the other ELF lanes do for PIE.
  • Shared libraries (ET_DYN without PT_INTERP) could follow in the same increment or stay refused with their own reason.
  • Verification: the existing verifier compiles with Clang/LLD, so a -fPIE -pie fixture, checked against llvm-readelf and the bytes at the relocated entry, would cover it.

Expected interaction with targets

Read files only. No execution.

Verification available so far

  • Packages from apt-get download in debian:trixie with dpkg --add-architecture riscv64 (apt verifies the signed InRelease):
    • busybox-static_1%3a1.37.0-6+b9_riscv64.deb, sha256 4add476d…8633; usr/bin/busybox sha256 659d3048…d3ed8d309b;
    • coreutils_9.7-3_riscv64.deb, sha256 47b00d78…86d7.
  • Reference tools: binutils-riscv64-linux-gnu from trixie.

Minor, while here: in the same refusal, the IDA rejection says "Select a supported Ghidra profile instead", although the Ghidra rejection in the same list says no profile admits this target.

Originally created by @Rinkia on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4487 ### Before submitting - [x] I searched the open and closed issues for a related report (riscv ET_DYN, riscv PIE, RISC-V shared, riscv dynamic). #2063 and #2151 added the lane and are closed; I found no follow-up for PIE. - [x] I understand the contribution scope. - [x] This report contains no credentials or private target samples. ### Area Native analysis or decompilation ### Current limitation The RISC-V Ghidra lane admits only `ET_EXEC` (`docs/ghidra-riscv.md`, `src/ghidra/GhidraRiscvProfile.ts:61`), and the refusal is clear: ```json {"provider_id":"ghidra","code":"architecture_unsupported", "reason":"This Ghidra RISC-V lane supports fixed-address ET_EXEC only; shared and position-independent images need separate load verification. ET_EXEC alone does not establish static linkage, which this lane does not inspect."} ``` But distributions build riscv64 userland as PIE. In Debian trixie riscv64, `coreutils 9.7-3` has **106 `ET_DYN` ELF files and 0 `ET_EXEC`** (for example `/usr/bin/ls`: "pie executable … dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1", `e_flags` `0x5`). The only `ET_EXEC` I found was a static build, `busybox-static`. So on real Linux riscv64 targets the lane refuses nearly every binary. The `e_flags` profile (RVC + double-float ABI) would otherwise be admitted. For the case it does admit, the lane is accurate. Debian `busybox-static 1:1.37.0-6+b9` riscv64 (`ET_EXEC`, `e_flags` `0x5`), `rea-agents@6.5.0`, Ghidra 12.1.4: - 104 s import. - Allocated section addresses and sizes match `readelf -S`. - All 13 entry instructions (`0x103a0`, a 38-byte body) match `riscv64-linux-gnu-objdump -d -M no-aliases` (`j` versus `jal zero` is only an alias). - The `__libc_start_main` callee decompiles readably, including the `R_RISCV_IRELATIVE` (58) loop over `.rela.plt`. So the decoding side is ready for PIE images too. ### Desired outcome and success criteria - Admit little-endian `ET_DYN` images that are executables. That means `PT_INTERP` present, or the existing ELF executable-versus-library classification, with the same `e_flags` profile, pinned language and compiler specification. Record the load base Ghidra applied and the load model in the lane identity and analysis profile, as the other ELF lanes do for PIE. - Shared libraries (`ET_DYN` without `PT_INTERP`) could follow in the same increment or stay refused with their own reason. - Verification: the existing verifier compiles with Clang/LLD, so a `-fPIE -pie` fixture, checked against `llvm-readelf` and the bytes at the relocated entry, would cover it. ### Expected interaction with targets Read files only. No execution. ### Verification available so far - Packages from `apt-get download` in `debian:trixie` with `dpkg --add-architecture riscv64` (apt verifies the signed InRelease): - `busybox-static_1%3a1.37.0-6+b9_riscv64.deb`, sha256 `4add476d…8633`; `usr/bin/busybox` sha256 `659d3048…d3ed8d309b`; - `coreutils_9.7-3_riscv64.deb`, sha256 `47b00d78…86d7`. - Reference tools: `binutils-riscv64-linux-gnu` from trixie. Minor, while here: in the same refusal, the IDA rejection says "Select a supported Ghidra profile instead", although the Ghidra rejection in the same list says no profile admits this target.
Author
Owner

@abhay-2108 commented on GitHub (Oct 17, 2026):

Hey! I'd love to work on this. Please assign it to me, and I'll have a PR ready soon.

<!-- gh-comment-id:6234645161 --> @abhay-2108 commented on GitHub (Oct 17, 2026): Hey! I'd love to work on this. Please assign it to me, and I'll have a PR ready soon.
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#1776
No description provided.