import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompileResults; import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Instruction; import ghidra.program.model.listing.InstructionIterator; import ghidra.program.model.listing.Listing; import java.io.FileWriter; import java.io.PrintWriter; /** * DumpAIS.java — Ghidra headless postScript. Decompiles + disassembles * checksum-hunt targets into /tmp/opencode/ghidra-lab/out/. */ public class DumpAIS extends GhidraScript { static final String OUT = "/tmp/opencode/ghidra-lab/out"; static final String[] TARGETS = { "C70A0A60", "C708E4E4", "C7086400", "C70A28A0", "C707841C" }; @Override public void run() throws Exception { new java.io.File(OUT).mkdirs(); AddressSpace space = currentProgram.getAddressFactory() .getDefaultAddressSpace(); Listing listing = currentProgram.getListing(); DecompInterface iface = new DecompInterface(); iface.openProgram(currentProgram); for (String t : TARGETS) { Address addr = space.getAddress(t); Function fn = getFunctionAt(addr); if (fn == null) { try { disassemble(addr); } catch (Exception e) { println("[DumpAIS] " + t + " disassemble: " + e); } try { fn = createFunction(addr, "sub_" + t); } catch (Exception e) { println("[DumpAIS] " + t + " createFunction: " + e); } } else { println("[DumpAIS] " + t + " fn=" + fn.getName()); } // disassembly window: 64B back, ~120 insns forward try { Address start = addr.addNoWrap(-64); InstructionIterator it = listing.getInstructions(start, true); PrintWriter pw = new PrintWriter(new FileWriter( OUT + "/dis_" + t + ".txt")); int n = 0; while (it.hasNext() && n < 150) { Instruction ins = it.next(); pw.println(String.format("%08X %s %s", ins.getAddress().getOffset(), ins.getMnemonicString(), ins.toString())); n++; if (ins.getAddress().compareTo(addr) > 0 && n > 100) { break; } } pw.close(); } catch (Exception e) { println("[DumpAIS] " + t + " disasm dump: " + e); } if (fn != null) { try { DecompileResults res = iface.decompileFunction( fn, 120, getMonitor()); String c = (res != null && res.getDecompiledFunction() != null) ? res.getDecompiledFunction().getC() : "DECOMPILE_NULL"; PrintWriter pw = new PrintWriter(new FileWriter( OUT + "/dec_" + t + ".txt")); pw.print(c); pw.close(); println("[DumpAIS] " + t + " decompiled " + (c == null ? 0 : c.length()) + " chars"); } catch (Exception e) { println("[DumpAIS] " + t + " decompile: " + e); PrintWriter pw = new PrintWriter(new FileWriter( OUT + "/dec_" + t + ".txt")); pw.print("DECOMPILE_ERROR: " + e); pw.close(); } } } iface.dispose(); println("[DumpAIS] done -> " + OUT); } }