Files
reverse-engineering-anything/docs/ghidra-psp.md
T
Entrpi 091892dfed test(ghidra): expect carved MIPS copies to be refused at target opening (#8227)
Since 651afa445 target opening refuses every ELF declaration beyond EOF,
including carved copies, and ac6e0e258 moved the carved MIPS boundary tests
to that contract. The real-Ghidra MIPS lane still expected a carved image to
resolve with section-table limitations and be refused later by Ghidra
admission, so verify:ghidra:mips failed at its first carved fixture.

The lane now requires open_binary and the CLI to refuse the carved copy as
target_unavailable (file_format_rejected) with the exact declared
section-table range and captured size. The carve and that expectation live in
the shared MIPS checks, and a boundary regression applies them to the
production resolver and error projection, so a later contract change fails
without real Ghidra. The MIPS and PSP guides describe the current contract.
2026-10-31 15:24:17 +08:00

5.7 KiB

PSP static ELF analysis through Ghidra

This specialization builds on generic MIPS support for #1330. It reuses REA's existing CLI/MCP, Ghidra bridge, Evidence and snapshot workflows. Allegrex instructions, PSP loading and calling conventions remain owned by ghidra-allegrex.

Initial boundary

The initial profile is limited to Linux x64, little-endian ELF32 ET_EXEC, EM_MIPS and the PSPSDK declaration e_flags=0x10a23001. Those bits declare MIPS II, Allegrex, EABI32 and NOREORDER; they are not proof of every instruction's semantics. The profile also requires an inspected version-0 MIPS ABI flags record declaring ISA level 2/revision 0, 32-bit GPR and CPR1, no CPR2, single-precision hard float (fpAbi=2), no ISA extension or ASEs, flags1=1 and flags2=0. These are the declarations independently reported by PSPDEV v20261001's GNU readelf 2.44 and its 24-byte section dump. Missing, uninspected, contradictory and other producer declarations are refused. The PSP profile is not an exception to the generic MIPS32r2/o32 policy; that separate gate is unchanged. Profile revision v2 records this corrected boundary.

PRX, relocatable/shared images, PBP/ISO/CSO containers, runtime emulation and live code overlays are outside this first profile. Other hosts and flag combinations are not silently admitted. File names do not identify a PSP target.

Bring your own compatible extension

Install the extension in the selected Ghidra distribution at $GHIDRA_INSTALL_DIR/Ghidra/Extensions/ghidra-allegrex, with its Module.manifest, extension.properties, language files and loader JARs. User-home installations are not searched because REA uses an isolated analysis home. REA never downloads, installs, rebuilds or vendors the extension.

The published compatibility experiment used Ghidra 12.1.3, extension v21.4, PSPDEV v20261001 and JDK 21. New public-provider results must be reported separately from that historical bridge experiment. The extension's version property declares its compatible Ghidra version, not its release tag; the property must match the selected installation. Other same-version builds are not described as independently verified merely because they pass this metadata check. A malformed or unloadable extension still fails real import.

REA fingerprints installed extension files before resolving the analysis profile and checks that identity again immediately before launch. Symlinks, nonregular files, missing components and incompatible metadata are refused. Inspection is bounded to 1,024 entries, 16 directory levels and 64 MiB, with streamed file hashing and 64 KiB properties. Rebuilds or content changes yield a different profile; an old snapshot is not silently reused with the new profile. This is content identity, not a signature or a sandbox for installed code. Do not modify the Ghidra installation while a session is running.

Ordinary public interfaces

rea analyze /absolute/path/to/psp.elf --provider ghidra --json
rea function /absolute/path/to/psp.elf function_name --provider ghidra --json

MCP uses open_binary with an absolute path and provider_id: "ghidra", then ordinary inventory and function operations. The loader is explicitly PspElfLoader, language Allegrex:LE:32:default, compiler default. The handshake must confirm the language and compiler before serving observations. Missing prerequisites return PSP_EXTENSION_UNAVAILABLE with an installation remedy; no provider fallback or automatic installation occurs.

Evidence retains the mips architecture family and its PSP-specific profile, including extension content identity. It also carries the VFPU and static-only limitations. The extension does not model VFPU prefix effects completely; nonempty decompiled code is not proof of correct vector behavior. Existing session-local metadata editing does not change executable bytes or turn a snapshot into a persistent Ghidra project.

Verification

Use the existing real MIPS verifier with its PSP option. Required tools are caller-supplied make, psp-config, psp-gcc, psp-readelf, psp-objdump, PSPDEV, GHIDRA_INSTALL_DIR and a compatible JAVA_HOME.

npm run build:cached
node scripts/verify-real-ghidra-mips.mjs --psp
# In a disposable installation without Allegrex, test actual public refusals:
node scripts/verify-real-ghidra-mips.mjs --psp-missing-extension
# Generic MIPS must remain generic with Allegrex installed:
npm run verify:ghidra:mips

The generic verifier also checks that a section-truncated firmware copy is refused when the target is opened. That check runs only in generic mode; the PSP report explicitly records carved-PSP coverage as not run.

The maintained PSP fixture builds from tests/conformance/psp/, never executes, and is independent of commercial game data. PSP GNU tools supply ELF/ABI, raw ABI-record, symbol and encoding observations; REA's parsed target and saved snapshot must agree with the independent ABI declaration. Public CLI/MCP must recover known functions, a direct call, the immediate 0x1234, BITREV, a global word and a marker. The verifier checks observed loader/language, original bytes, Evidence, snapshot reopening, and an A-B-A target switch with different global contents at the same address. A snapshot for A must not open B. Cleanup must finish before success is reported.

These checks are selected static facts, not full behavioral equivalence, VFPU semantics or arbitrary PSP compatibility. Independently published PSP binaries are supplemental calibration targets after payload classification and license review; unsupported PRX/PBP must not count as a successful static-ELF case.