Steward
分享是一種喜悅、更是一種幸福
逆向工程 - Ghidra - Python - Write Exports/Functions To C
ExportAllToC.java
import java.io.File;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
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;
import ghidra.program.model.listing.FunctionIterator;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.symbol.Symbol;
public class ExportAllToC extends GhidraScript {
private DecompInterface decompiler;
@Override
public void run() throws Exception {
if (currentProgram == null) {
println("No program is open.");
return;
}
String outputDir = askString(
"Output Directory",
"Directory:",
"/tmp/ghidra-decompiled"
);
File root = new File(outputDir);
File exportsDir = new File(root, "exports");
File functionsDir = new File(root, "functions");
exportsDir.mkdirs();
functionsDir.mkdirs();
println("Output directory: " + root.getAbsolutePath());
decompiler = new DecompInterface();
DecompileOptions options = new DecompileOptions();
decompiler.setOptions(options);
decompiler.toggleCCode(true);
decompiler.toggleSyntaxTree(false);
decompiler.setSimplificationStyle("decompile");
if (!decompiler.openProgram(currentProgram)) {
println("Failed to initialize decompiler.");
return;
}
println("");
println("========================================");
println("Exported Functions");
println("========================================");
Set<Address> exportedAddresses = new HashSet<>();
for (Symbol symbol : currentProgram.getSymbolTable().getAllSymbols(true)) {
monitor.checkCanceled();
if (!symbol.isExternalEntryPoint()) {
continue;
}
Address address = symbol.getAddress();
Function function =
currentProgram.getFunctionManager().getFunctionAt(address);
if (function == null) {
println("Export without function: "
+ symbol.getName()
+ " @ "
+ address);
continue;
}
exportedAddresses.add(function.getEntryPoint());
File file = new File(
exportsDir,
makeSafeFilename(symbol.getName()) + ".c"
);
decompileFunction(function, file, symbol.getName());
}
println("");
println("========================================");
println("All Functions");
println("========================================");
FunctionManager fm =
currentProgram.getFunctionManager();
FunctionIterator functions =
fm.getFunctions(true);
int count = 0;
while (functions.hasNext()) {
monitor.checkCanceled();
Function function = functions.next();
count++;
Address entry =
function.getEntryPoint();
String name =
function.getName();
File file = new File(
functionsDir,
makeSafeFilename(name)
+ "_"
+ entry.toString()
+ ".c"
);
println(
"[" + count + "] "
+ name
+ " @ "
+ entry
);
decompileFunction(function, file, name);
}
decompiler.dispose();
println("");
println("========================================");
println("Finished");
println("========================================");
println("Export directory : "
+ exportsDir.getAbsolutePath());
println("Functions directory : "
+ functionsDir.getAbsolutePath());
println("Functions : " + count);
}
private void decompileFunction(
Function function,
File outputFile,
String displayName) throws Exception {
try {
DecompileResults result =
decompiler.decompileFunction(
function,
60,
monitor
);
PrintWriter out =
new PrintWriter(outputFile);
out.println("/*");
out.println(" * Ghidra decompilation");
out.println(" *");
out.println(" * Function : "
+ displayName);
out.println(" * Address : "
+ function.getEntryPoint());
out.println(" * Program : "
+ currentProgram.getName());
out.println(" */");
out.println();
if (result == null) {
out.println(
"/* Decompiler returned NULL */"
);
}
else if (!result.decompileCompleted()) {
out.println(
"/* Decompilation failed */"
);
out.println(
"/* "
+ result.getErrorMessage()
+ " */"
);
}
else {
String c =
result.getDecompiledFunction().getC();
if (c != null && !c.isEmpty()) {
out.println(c);
}
else {
out.println(
"/* Empty decompiler output */"
);
}
}
out.close();
}
catch (Exception e) {
println(
"ERROR: "
+ displayName
+ " @ "
+ function.getEntryPoint()
+ " : "
+ e.getMessage()
);
}
}
private String makeSafeFilename(String name) {
if (name == null || name.isEmpty()) {
return "unknown";
}
return name.replaceAll(
"[^a-zA-Z0-9_.-]",
"_"
);
}
}