package re3lib; import java.io.File; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; import ghidra.program.model.data.CategoryPath; import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; import ghidra.program.model.data.Enum; import ghidra.program.model.data.EnumDataType; import ghidra.program.model.data.FunctionDefinition; import ghidra.program.model.data.ProgramBasedDataTypeManager; import ghidra.program.model.data.Structure; import ghidra.program.model.data.TypeDef; import ghidra.program.model.data.TypedefDataType; import ghidra.program.model.data.Union; import ghidra.program.model.data.UnionDataType; import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Program; import re3lib.FunctionDatabase.GlobalEntry; public class TypeDumper { Program currentProgram; GhidraScript script; public TypeDumper(GhidraScript script) { this.script = script; currentProgram = script.getCurrentProgram(); RemanConfig.INSTANCE = new RemanConfig(script); } public void run() throws Exception { ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager(); HashSet requiredFunctionTypes = new HashSet<>(); FunctionDatabase fd = new FunctionDatabase(script); List globals = fd.loadAllGlobals(); for (GlobalEntry globalEntry : globals) { // Fetch type of global from ghidra Address addr = globalEntry.address; if (globalEntry.name == "p_fn_vDisplayAll") script.println("EEEEE"); Data data = script.getDataAt(addr); if (data != null) { DataType type = data.getDataType(); if (type instanceof FunctionDefinition) { requiredFunctionTypes.add(type.getDisplayName()); script.println("Adding required global function type: " + type.getDisplayName()); } } } HashSet typeBlacklist = Utils.loadSimpleBlacklist(RemanConfig.INSTANCE.typeBlacklistPath); HashSet categoryPathBlacklist = Utils .loadSimpleBlacklist(RemanConfig.INSTANCE.categoryPathBlacklistPath); if (typeBlacklist == null) { script.println("Building struct blacklist from existing data types"); typeBlacklist = new HashSet<>(); Iterator it = dtm.getAllDataTypes(); while (it.hasNext()) { DataType dt = it.next(); if (dt instanceof Structure || dt instanceof TypedefDataType) { typeBlacklist.add(dt.getDisplayName()); } } Utils.saveStructBlacklist(typeBlacklist, RemanConfig.INSTANCE.typeBlacklistPath); } List filteredTypes = new ArrayList<>(); // Iterator compIt = dtm.getAllDataTypes(); // while (compIt.hasNext()) { // DataType comp = compIt.next(); // // script.println("Found: " + comp.getDisplayName() + " - " + // // comp.getClass().getSimpleName()); // if (comp instanceof TypeDef) { // if (comp.getDisplayName().startsWith("FIL_")) { // script.println("Found: " + comp.getDisplayName() + " - " + comp.getName() + " // - " + comp.getClass().getSimpleName()); // } // } // // if (comp.getName() == "FIL_tdstConcatFile") { // // // script.println("Found: " + dt.getDisplayName() + " - " + // // // dt.getClass().getSimpleName()); // // throw new Exception("Found: " + comp.getDisplayName() + " - " + // comp.getClass().getSimpleName()); // // } // } Iterator it = dtm.getAllDataTypes(); while (it.hasNext()) { DataType dt = it.next(); if (typeBlacklist.contains(dt.getDisplayName())) continue; CategoryPath catPath = dt.getCategoryPath(); if (catPath.getPathElements().length > 0 && categoryPathBlacklist.contains(catPath.getPathElements()[0])) continue; if (dt instanceof Structure || dt instanceof TypeDef || dt instanceof EnumDataType || dt instanceof Union || dt instanceof Enum || dt instanceof FunctionDefinition) { if (dt.getDisplayName().contains("level_displayFn") || dt.getDisplayName().contains("_M_IX86")) script.println("DEBUG " + dt.getDisplayName() + " - " + dt.getClass().getSimpleName()); // if (dt.getDisplayName().contains("tdstObjectTypeElement_") || // dt.getDisplayName().contains("ObjectTypeElementHandle")) filteredTypes.add(dt); } // } } // String s = ""; // for (DataType dataType : filteredTypes) { // s += dataType.getDisplayName() + ", "; // } // script.println(s); try (PrintWriter writer = new PrintWriter(new File(RemanConfig.INSTANCE.outputDir, "gh_types.h"), "UTF-8")) { Utils.headerGuardPre(writer, "STRUCTS"); writer.println("// AUTO-GENERATED FILE "); writer.println("#include "); DataTypeWriter dtw = new DataTypeWriter(dtm, writer); dtw.requiredFunctionTypes = requiredFunctionTypes; dtw.write(filteredTypes, script.getMonitor()); Utils.headerGuardPost(writer, "STRUCTS"); } } }