mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 10:43:30 +00:00
fix(ghidra): prevent loader relocations from constant folding (#10483)
* fix(ghidra): prevent loader relocations from constant folding Ghidra imports loader relocation destinations with their file bytes. A destination in a non-writable loaded block can be populated by the runtime loader instead, for example a copy-relocated musl `stderr` in RELRO, so the decompiler folded the on-disk zero and showed `fprintf(NULL, ...)`. Before initializing the decompiler, mark each loaded, initialized, non-writable block containing a relocation destination volatile in the ephemeral database, and add a limitation to procedures that read such a destination. ELF shared objects and PIEs are included; relocatable objects and core files are not. Permissions and source FileBytes are unchanged. Sessions without database-mutation authority (Windows P0 and existing caller projects) record the limitation but do not mark blocks volatile, and the analysis profile versions the two behaviors separately. A real Linux Ghidra ELF probe runs in the Ghidra bridge CI lane. Fixes #4177 Squashed from #4198 and rebased onto main. Rebase adaptations: the read-only gate, the verifier renamed to verify-ghidra-loader-relocation so it stays out of the manual-verifier glob, docs moved to docs/testing-lanes.md and docs/providers/ghidra-provider.md. Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ghidra): await installation inspection in the relocation verifier inspectGhidraInstallation became async on main after #4198's base, so the verifier asserted on a pending Promise. Also wait for provider output to close before reading it, like the sibling Ghidra verifiers, and keep the workflow reference inside the docs site. Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ghidra): address relocation review findings - Version the existing-project analysis profile with the read-only relocation semantics, since those sessions now add the limitation. - Inspect the installation through the verifier helper that owns the file-reader resources. - Build the fixture with -fPIC: with -fPIE, GCC 12 emits a copy relocation of rea_external_value into writable .bss, so the probe's GOT check could not hold. - Run probe cleanup through withVerifierCleanup so a cleanup failure does not hide the probe failure, and keep the workspace when owned Ghidra cleanup is incomplete. - Link the workflow with a full GitHub URL, per the docs guide. Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ghidra): reach the external data through the GOT with a weak extern Building the whole fixture with -fPIC also turned the reader's direct load of rea_loader_pointer into a GOT-relaxed lea plus two loads, and the real-Ghidra lane then reported that the baseline no longer folds the file constant. Keep -fPIE and declare only rea_external_value weak: GCC and clang must reach a possibly absent symbol through a GOT entry, which lands as R_X86_64_GLOB_DAT inside GNU_RELRO (checked with readelf for GCC 12.2 and clang/lld). Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ghidra): protect only relocations Ghidra could not apply Running the real-Ghidra lane locally (Ghidra 12.1.4, JDK 21, GCC 12) showed that marking every non-writable block that holds a relocation volatile also marks full-RELRO .got. External calls then decompile as opaque pointer calls (`(*pcVar2)(param_1)` through `PTR_rea_external_...` instead of `rea_external(param_1)`), which the probe's GOT-stability check caught. Ghidra applies GLOB_DAT and RELATIVE relocations, so those bytes already hold the loader's value and folding them is correct. The #4177 case is a copy relocation, which Ghidra imports as UNSUPPORTED with the file's zero in place. Protect only destinations whose relocation status is not APPLIED or APPLIED_OTHER. The fixture now reads a provider `const` object that the linker copies into .data.rel.ro, the #4177 shape. The probe requires that relocation to be unapplied and requires applied GOT relocations to stay non-volatile. Ghidra 12.1.4 already shows this x86-64 read by name without protection, so the probe records whether the baseline folds and compares before and after only when it does. The profile value becomes volatile-unapplied-relocation-blocks-v1. Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Arslan Basharat <arslanbasharat414@gmail.com> Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
14 files changed
+998
-1
No files matched your search
@@ -14,7 +14,7 @@ jobs:
|
||||
ghidra-bridge-sources:
|
||||
name: Compile packaged Ghidra bridge sources
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
GHIDRA_RELEASE_URL: https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_12.1.4_build/ghidra_12.1.4_PUBLIC_20260921.zip
|
||||
GHIDRA_RELEASE_SHA256: ddac49f903da9d5bac833e5cc79395098b9c33cfd3279be5f31bd00387d2d4db
|
||||
@@ -46,6 +46,14 @@ jobs:
|
||||
java_home_variable="JAVA_HOME_${GHIDRA_JAVA_MAJOR}_X64"
|
||||
test -n "${!java_home_variable}"
|
||||
JAVA_HOME="${!java_home_variable}" npm run verify:ghidra:bridge-sources -- --verified-sdk
|
||||
- name: Install locked dependencies for loader relocation regression
|
||||
run: npm ci
|
||||
- name: Verify loader relocation handling with the native decompiler
|
||||
shell: bash
|
||||
run: |
|
||||
java_home_variable="JAVA_HOME_${GHIDRA_JAVA_MAJOR}_X64"
|
||||
export JAVA_HOME="${!java_home_variable}"
|
||||
npm run verify:ghidra:loader-relocation
|
||||
- name: Inspect real ARM, Thumb and MIPS instruction context through the bridge
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
Reference in new issue
Block a user