Files
Drew T 36a366ba3f chore(phase-1): install RE stack + headless import (PsyQ 4.0.0, MCP live)
- WSL RE stack installed: JDK 21.0.11, Ghidra 12.1 PUBLIC, GhidrAssistMCP
  v2.8.0, ghidra_psx_ldr 2026.06.04 (extensions extracted into
  Ghidra/Extensions/ at version=12.1; exact-12.1 pin held, no version-lock)
- headless import of extracted/SLUS_007.26: PSX loader auto-selected
  (PSX:LE:32:default), PsyQ Version = 4.0.0 recorded, 1726 functions,
  saved to ghidra/bfm.{gpr,rep} (gitignored)
- GhidrAssistMCP headless server verified on 127.0.0.1:8080 (41 tools);
  get_code(0x80018730) returns the LZSS streaming decompressor
  (milestone substance, also confirmed via headless decompiler)
- tools/ghidra_scripts: DumpProgramInfo.java, DecompileAt.java (helpers)
- docs/SETUP.md: confirm PsyQ 4.0.0; 41 tools + async get_code/SSE notes;
  headless -loader rejected -> use auto-detect; extension-install path;
  ledger #1 moot, #12 resolved
2026-06-13 15:52:37 -06:00

46 lines
2.0 KiB
Java

// DecompileAt.java — headless postScript: decompile the function at a given
// address (default 0x80018730, the LZSS streaming decompressor) and print the C.
// Used to verify Phase 1's milestone substance (recognizable LZSS code) directly
// from Ghidra's decompiler. Usage: -postScript DecompileAt.java [hexaddr]
import ghidra.app.script.GhidraScript;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileResults;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Instruction;
public class DecompileAt extends GhidraScript {
@Override
public void run() throws Exception {
String addrStr = "80018730";
String[] a = getScriptArgs();
if (a.length > 0) addrStr = a[0];
Address addr = toAddr(addrStr);
println("=== DECOMPILE @ 0x" + addrStr + " ===");
Function f = getFunctionContaining(addr);
if (f == null) f = getFunctionAt(addr);
if (f == null) {
println("NO FUNCTION at/containing 0x" + addrStr + ". Raw instructions follow:");
Instruction ins = getInstructionAt(addr);
for (int i = 0; i < 24 && ins != null; i++) {
println(String.format(" %s %s", ins.getAddress(), ins.toString()));
ins = ins.getNext();
}
println("=== END DECOMPILE ===");
return;
}
println("Function: " + f.getName() + " @ " + f.getEntryPoint()
+ " bytes=" + f.getBody().getNumAddresses());
DecompInterface di = new DecompInterface();
di.openProgram(currentProgram);
DecompileResults res = di.decompileFunction(f, 90, monitor);
if (res != null && res.decompileCompleted()) {
println(res.getDecompiledFunction().getC());
} else {
println("DECOMPILE FAILED: " + (res != null ? res.getErrorMessage() : "null result"));
}
di.dispose();
println("=== END DECOMPILE ===");
}
}