// Decompile functions of the persistent sacred.exe Ghidra project. // // Headless usage (see tools/decompile.ps1): // analyzeHeadless sacred -process sacred.exe -noanalysis // -scriptPath tools/ghidra -postScript Decompile.java [addr...] // // Addresses without a function (e.g. methods only reachable via a vtable) get // one created first; run without -readOnly to keep those in the project. // @category sacredK import java.io.File; import java.io.PrintWriter; import ghidra.app.cmd.disassemble.DisassembleCommand; import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompileOptions; import ghidra.app.decompiler.DecompileResults; import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function; public class Decompile extends GhidraScript { @Override protected void run() throws Exception { String[] args = getScriptArgs(); if (args.length < 2) { printerr("usage: Decompile.java
[address...]"); return; } DecompInterface decompiler = new DecompInterface(); decompiler.setOptions(new DecompileOptions()); decompiler.openProgram(currentProgram); try (PrintWriter out = new PrintWriter(new File(args[0]), "UTF-8")) { for (int i = 1; i < args.length; i++) { Address address = toAddr(args[i]); Function function = getFunctionAt(address); if (function == null) { function = getFunctionContaining(address); } if (function == null) { new DisassembleCommand(address, null, true).applyTo(currentProgram, monitor); function = createFunction(address, null); } out.println("// ==== " + args[i] + " ===="); if (function == null) { out.println("// could not create a function here"); continue; } out.println("// " + function.getName(true) + " @ " + function.getEntryPoint() + " (" + function.getCallingConventionName() + ")"); DecompileResults result = decompiler.decompileFunction(function, 120, monitor); if (result.decompileCompleted()) { out.println(result.getDecompiledFunction().getC()); } else { out.println("// decompile failed: " + result.getErrorMessage()); } } } finally { decompiler.dispose(); } } }