Files
BFM-decomp/tools/ghidra_scripts/DecompileFunctions.java
T
Drew T 0dd9bf6bac feat(phase-17): calibration harvest wave — fleet 55.04%->55.51% (+0.47%)
- Ultracode wave: 30 high-reach tractable residuals, parallel guided-hand-matching
  agents (m2c + Ghidra-C cache + asm + actor-struct + S1/S2/S3a playbook), self-
  validate match_one. 18/30 match_one MATCH (60%); 10/30 whole-binary verified (33%)
  after sig_unify recovered 2 -> all 10 propagated x134; 2 demo fns caught up
- 136/136 byte-identical (R22 clean check-all); REAL +1,610; 1421 dedup groups
- KEY FINDING: the match_one->whole-binary gap (60%->33%) is 100% SIG CONFLICTS
  (shared callees like func_80131CA8 declared inconsistently across parallel agents),
  NOT codegen. The canonical-sig layer (deferred as low-value) is the ESSENTIAL
  enabler -> would lift 33% toward 60%. 12/30 are the genuine gcc-quirk tail (DIFF).
- Ghidra pre-pass: tools/ghidra_scripts/DecompileFunctions.java (headless batch
  decompile -> .run/ghidra_c cache; no /mcp needed); 300 tractable targets sized
- harness: .run/harvest_wave_s3.js (embedded-targets Workflow; args channel doesn't
  transit arrays). cost ~1.89M tokens / 30 fns
2026-06-19 20:54:45 -06:00

55 lines
2.3 KiB
Java

// DecompileFunctions.java — headless postScript: batch-decompile a list of functions
// (one hex address per line in arg[0]) and write each function's C to arg[1]/<name>.c.
// Built for the Phase-17 harvest Ghidra pre-pass: dump whole-program Ghidra-C for the
// tractable residuals so harvest agents get local/global/callee disambiguation m2c lacks,
// WITHOUT live-MCP contention (agents read the cached files).
// Usage: -postScript DecompileFunctions.java <addr-list-file> <out-dir>
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 java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class DecompileFunctions extends GhidraScript {
@Override
public void run() throws Exception {
String[] a = getScriptArgs();
if (a.length < 2) {
println("USAGE: DecompileFunctions.java <addr-list-file> <out-dir>");
return;
}
String addrFile = a[0];
String outDir = a[1];
new File(outDir).mkdirs();
DecompInterface di = new DecompInterface();
di.openProgram(currentProgram);
List<String> lines = Files.readAllLines(Paths.get(addrFile));
int ok = 0, fail = 0, nofunc = 0;
for (String raw : lines) {
String line = raw.trim();
if (line.isEmpty()) continue;
Address addr = toAddr(line);
Function f = getFunctionAt(addr);
if (f == null) f = getFunctionContaining(addr);
if (f == null) { nofunc++; println("NOFUNC " + line); continue; }
DecompileResults res = di.decompileFunction(f, 60, monitor);
String out;
if (res != null && res.decompileCompleted()) {
out = res.getDecompiledFunction().getC();
ok++;
} else {
out = "// DECOMPILE FAILED: " + (res != null ? res.getErrorMessage() : "null result");
fail++;
}
Files.write(Paths.get(outDir, f.getName() + ".c"), out.getBytes());
}
di.dispose();
println("DecompileFunctions: " + ok + " ok, " + fail + " decompile-fail, " + nofunc
+ " no-func -> " + outDir);
}
}