Files
SalastilandClaude Opus 5.5 9f4e6666b3 Annotation-driven symbols, EH-aware matching, hash-checked link; spell-point TU matched
- // FUNCTION: / GLOBAL: / LIBRARY: annotations in source name symbols, so
  decompiling never needs edits to the shared symbols.txt
- check follows compiler-generated EH handlers into .text$x and verifies
  string literals / float constants by content
- link rebuilds eqgame.exe from compiled objects with relocations resolved
  through the map and checks the SHA1 (currently identical)
- Ghidra pseudo-C export script; docs/ROADMAP.md for the full-relink plan
- /GS confirmed; 0x401022-0x4013e1 (13 functions, spell casting particle
  points) match byte-for-byte

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 22:46:21 -04:00

29 lines
1.3 KiB
Java

// Writes Ghidra's pseudo-C for every function to <outdir>/<addr>.c (a starting point for decompiling).
// Usage: analyzeHeadless <proj> <name> -import eqgame.exe -postScript ExportDecomp.java <outdir>
import ghidra.app.decompiler.*;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.*;
import java.io.*;
public class ExportDecomp extends GhidraScript {
@Override
public void run() throws Exception {
File dir = new File(getScriptArgs()[0]);
dir.mkdirs();
DecompInterface di = new DecompInterface();
di.openProgram(currentProgram);
int n = 0;
for (Function f : currentProgram.getFunctionManager().getFunctions(true)) {
if (monitor.isCancelled()) break;
if (f.isExternal() || f.isThunk()) continue;
File out = new File(dir, String.format("%08x.c", f.getEntryPoint().getOffset()));
if (out.exists()) continue;
DecompileResults r = di.decompileFunction(f, 60, monitor);
String c = r.decompileCompleted() ? r.getDecompiledFunction().getC() : "// decompile failed: " + r.getErrorMessage() + "\n";
try (PrintWriter w = new PrintWriter(new FileWriter(out))) { w.print(c); }
if (++n % 500 == 0) println("decompiled " + n);
}
di.dispose();
}
}