//TODO write a description for this script //@author //@category Export //@keybinding //@menupath //@toolbar bomb import java.io.File; import java.io.PrintWriter; import java.util.List; import java.util.regex.Pattern; import ghidra.app.decompiler.DecompInterface; import ghidra.app.decompiler.DecompileOptions; import ghidra.app.decompiler.DecompileResults; import ghidra.app.script.GhidraScript; import ghidra.program.model.listing.Function; public class ExportFunctionsBulk extends GhidraScript { @Override public void run() throws Exception { Pattern pattern = BulkUtils.askForRegex(this, "entire function name"); List functions = BulkUtils.getFunctionsByRegex(this, pattern); if(functions.size() == 0) { println("Abort: no functions match the provided regex"); return; } String programName = currentProgram.getName(); DecompInterface decompiler = new DecompInterface(); DecompileOptions options = new DecompileOptions(); options.setMaxWidth(1024); // easier parsing if everything is in one line decompiler.setOptions(options); decompiler.openProgram(currentProgram); String fileName = programName + ".c"; File outputFile = BulkUtils.askForOutputFile(fileName); if(outputFile == null){ println("Abort: export dialog has been cancelled"); return; } PrintWriter decompWriter = new PrintWriter(outputFile); int decompileTimeout = 10; // seconds functions.forEach(function -> { decompWriter.write("// ADDRESS - 0x" + function.getEntryPoint().toString().toUpperCase() + "\n"); DecompileResults decompileResults = decompiler.decompileFunction(function, decompileTimeout, null); String decompiledCode = decompileResults.getDecompiledFunction().getC(); decompWriter.println(decompiledCode.trim() + "\n\n"); }); decompWriter.close(); println(functions.size() + " matching function(s) exported to " + outputFile.getAbsolutePath()); } }