reman3/scripts/Decompile.java

185 lines
7.0 KiB
Java

// Script to export decompiled C code from Ghidra
// @category _Reman3
// @menupath Reman3.Decompile All
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Arrays;
import java.util.Dictionary;
import ghidra.app.decompiler.ClangFieldToken;
import ghidra.app.decompiler.ClangLine;
import ghidra.app.decompiler.ClangSyntaxToken;
import ghidra.app.decompiler.ClangToken;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.decompiler.PrettyPrinter;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.AbstractStringDataType;
import ghidra.program.model.data.Array;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.BitFieldDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.EnumDataType;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.ProgramBasedDataTypeManager;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.TypedefDataType;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.VariableStorage;
import ghidra.program.model.pcode.HighFunction;
import ghidra.program.model.pcode.HighSymbol;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.Symbol;
import ghidra.util.task.TaskMonitor;
import re3lib.*;
public class Decompile extends GhidraScript {
// void headerGuardPre(PrintWriter writer, String tag) {
// writer.println("#ifndef GH_GENERATED_" + tag + "_H");
// writer.println("#define GH_GENERATED_" + tag + "_H");
// writer.println();
// }
// void headerGuardPost(PrintWriter writer, String tag) {
// writer.println("#endif // GH_GENERATED_" + tag + "_H");
// }
// void dumpGlobals(Hashtable<String, GlobalRec> globalSymbols) throws Exception {
// File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h");
// PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8");
// hwriter.println("// AUTO-GENERATED FILE ");
// headerGuardPre(hwriter, "GLOBALS");
// hwriter.println("#include <r3/binder/global.h>");
// hwriter.println();
// File globalSymbolsListC = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.cxx");
// PrintWriter cwriter = new PrintWriter(globalSymbolsListC, "UTF-8");
// cwriter.println("// AUTO-GENERATED FILE ");
// cwriter.println("#include <r3/binder/global.h>");
// hwriter.println();
// for (GlobalRec sym : globalSymbols.values()) {
// HighSymbol highSym = sym.highSymbol;
// DataType dt = highSym.getDataType();
// String dataType = dt.getDisplayName();
// String sanitizedName = sanitizeFunctionName(highSym.getName());
// String name = highSym.getName();
// if (!sanitizedName.equals(name)) {
// println("Invalid global symbol name: " + name);
// name = sanitizedName;
// }
// Address addr = sym.address;
// // println("Symbol: " + symbol + " Addr: " + addr + " Size:" + symSize + " " +
// // storage.getSerializationString());
// try {
// String initBlk = " = ";
// boolean fullyDefinedType = false;
// if (dt instanceof AbstractStringDataType) {
// AbstractStringDataType sdt = (AbstractStringDataType) dt;
// dataType = "const char*";
// // String type
// initBlk += "\"" + escapeCString(readCString(addr, 2048)) + "\"";
// fullyDefinedType = true;
// } else if (dt instanceof PointerDataType) {
// PointerDataType pdt = (PointerDataType) dt;
// DataType baseType = pdt.getDataType();
// dataType = baseType.getDisplayName() + "*";
// initBlk += "(" + dataType + ")&GH_MEM(0x" + addr + ")";
// fullyDefinedType = true;
// }
// if (fullyDefinedType) {
// hwriter.println("extern " + dataType + " " + name + "; // " + addr);
// cwriter.println(dataType + " " + name + initBlk + "; // " + addr);
// } else {
// if (dt instanceof Array) {
// // println("Array: " + dt.getDisplayName() + " - " + addr + " - " +
// // dt.getClass().getSimpleName());
// Array adt = (Array) dt;
// DataType baseType = adt.getDataType();
// hwriter.println(
// "extern " + baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "]; // " + addr);
// cwriter.println(
// baseType.getDisplayName() + "(&" + name + ")[" + adt.getNumElements() + "] = *reinterpret_cast<"
// + baseType.getDisplayName() + "(*)[" + adt.getNumElements() + "]>(GH_MEM(0x" + addr + "));");
// } else {
// String refTypeStr = dt.getDisplayName() + "&";
// hwriter.println("extern " + refTypeStr + " " + name + "; // " + addr);
// cwriter.println(dataType + " " + name + "= (" + refTypeStr + ") GH_MEM(0x" + addr + ");");
// }
// }
// } catch (Exception e) {
// println("Error processing global symbol: " + e);
// println("Symbol: " + highSym.getName() + " - " + addr + " - "
// + highSym.getHighFunction().getFunction().getName());
// }
// }
// headerGuardPost(hwriter, "GLOBALS");
// hwriter.close();
// cwriter.close();
// }
void decompileAll(List<Function> functions) throws Exception {
// Hashtable<String, GlobalRec> globalSymbols = new Hashtable<>();
// for (Function function : functions) {
// decompileFunction(globalSymbols, function);
// }
// dumpStructureTypes();
// dumpGlobals(globalSymbols);
}
@Override
public void run() throws Exception {
if (currentProgram == null) {
return;
}
RecompileConfig.INSTANCE = new RecompileConfig(this);
if (!new File(RecompileConfig.INSTANCE.outputDir).exists()) {
throw new Exception("Output directory does not exist: " + RecompileConfig.INSTANCE.outputDir);
}
// Make sure to create output folders
RecompileConfig.INSTANCE.dirDecompFix.mkdirs();
RecompileConfig.INSTANCE.dirDecompAuto.mkdirs();
RecompileConfig.INSTANCE.dirDecompRef.mkdirs();
// buildFunctionBlacklist();
List<Function> functions = new ArrayList<>();
Iterator<Function> functionsIt = currentProgram.getFunctionManager().getFunctions(true).iterator();
while (functionsIt.hasNext()) {
Function function = functionsIt.next();
// if (!shouldDecompileFunction(function)) {
// continue;
// }
functions.add(function);
}
decompileAll(functions);
}
String sanitizeFunctionName(String name) {
return name.replaceAll("[^a-zA-Z0-9_]", "_");
}
}