From 03dcb159fe078c059a96465980ae19bfc9d45902 Mon Sep 17 00:00:00 2001 From: Guus Waals <_@guusw.nl> Date: Mon, 23 Sep 2024 20:35:35 +0800 Subject: [PATCH] Rename gh_structs.h to gh_types.h, split script --- game_re/{gh_structs.h => gh_types.h} | 0 scripts/Decompile.java | 127 --------------------------- scripts/DecompileFile.java | 25 ++++++ scripts/DumpTypes.java | 18 ++++ scripts/re3lib/RecompileConfig.java | 6 ++ scripts/re3lib/TypeDumper.java | 72 +++++++++++++++ scripts/re3lib/Utils.java | 10 +++ 7 files changed, 131 insertions(+), 127 deletions(-) rename game_re/{gh_structs.h => gh_types.h} (100%) create mode 100644 scripts/DecompileFile.java create mode 100644 scripts/DumpTypes.java create mode 100644 scripts/re3lib/TypeDumper.java diff --git a/game_re/gh_structs.h b/game_re/gh_types.h similarity index 100% rename from game_re/gh_structs.h rename to game_re/gh_types.h diff --git a/scripts/Decompile.java b/scripts/Decompile.java index 8e9c692e..2c953df7 100644 --- a/scripts/Decompile.java +++ b/scripts/Decompile.java @@ -344,133 +344,6 @@ public class Decompile extends GhidraScript { writer.println("#endif // GH_GENERATED_" + tag + "_H"); } - class DependencyTypeDumper { - HashSet types = new HashSet<>(); - DataTypeManager dtm; - TaskMonitor taskMonitor; - - public DependencyTypeDumper(DataTypeManager dtm) { - this.dtm = dtm; - this.taskMonitor = monitor; - } - - void visit(DataType dataType, PrintWriter writer) throws Exception { - // If not already written - if (types.contains(dataType)) { - println("Visiting: " + dataType.getName()); - types.remove(dataType); - - // Write dependencies, and then write self - if (dataType instanceof Structure) { - Structure struct = (Structure) dataType; - for (DataTypeComponent component : struct.getComponents()) { - DataType dt = component.getDataType(); - if (dt instanceof Structure) { - println("Dependency: " + dt.getName()); - visit((Structure) dt, writer); - } - } - } - writeNoDeps(dataType, writer); - } - } - - void writeNoDeps(DataType dt, PrintWriter writer) throws Exception { - // Check - // https://github.com/NationalSecurityAgency/ghidra/blob/17c93909bbf99f7f98dbf5737b38d8dd2c01bef0/Ghidra/Features/Decompiler/src/main/java/ghidra/app/util/exporter/CppExporter.java#L401 - - // DataTypeWriter dtw = new DataTypeWriter(dtm, writer); - // dtw.blacklistedTypes = - // dtw.write(new DataType[] { dt }, taskMonitor); - - // if (dt instanceof Structure) { - // Structure struct = (Structure) dt; - // writer.append("typedef struct " + struct.getName() + " {\n"); - // for (DataTypeComponent component : struct.getComponents()) { - // if (component.isBitFieldComponent()) { - // BitFieldDataType bfdt = (BitFieldDataType) component.getDataType(); - // writer.append( - // " " + bfdt.getDisplayName() + " " + component.getDefaultFieldName() + " : " + - // bfdt.getBitSize() + ";\n"); - // } else { - // writer.append( - // " " + component.getDataType().getDisplayName() + " " + - // component.getDefaultFieldName() + ";\n"); - // } - // writer.append("} " + struct.getDisplayName() + " ;\n"); - // writer.append("\n"); - // } else if (dt instanceof TypedefDataType) { - // TypedefDataType typedef = (TypedefDataType) dt; - // writer.append("typedef " + typedef.getDataType().getDisplayName() + " " + - // typedef.getName() + ";\n"); - // writer.append("\n"); - // } else { - // throw new Exception("Unsupported type: " + dt.getDisplayName()); - // } - } - - void writeAll(PrintWriter writer) throws Exception { - while (types.size() > 0) { - DataType first = types.iterator().next(); - visit(first, writer); - } - } - }; - - void dumpStructureTypes() throws Exception { - ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager(); - - HashSet typeBlacklist = Utils.loadStructBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath); - - if (typeBlacklist == null) { - 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, RecompileConfig.INSTANCE.typeBlacklistPath); - } - - List filteredTypes = new ArrayList<>(); - Iterator it = dtm.getAllDataTypes(); - // DependencyTypeDumper dumper = new DependencyTypeDumper(dtm); - while (it.hasNext()) { - DataType dt = it.next(); - if (dt instanceof Structure || dt instanceof TypedefDataType || dt instanceof EnumDataType) { - if (typeBlacklist.contains(dt.getDisplayName())) - continue; - // println("Adding: " + dt.getDisplayName() + " - " + - // dt.getClass().getSimpleName()); - filteredTypes.add(dt); - } - - // Structure struct = (Structure) dt; - // dumper.types.add(struct); - // } else if (dt instanceof TypedefDataType) { - // TypedefDataType typedef = (TypedefDataType) dt; - // dumper.types.add(typedef); - // } - } - - try (PrintWriter writer = new PrintWriter(new File(RecompileConfig.INSTANCE.outputDir, "gh_structs.h"), - "UTF-8")) { - headerGuardPre(writer, "STRUCTS"); - writer.println("// AUTO-GENERATED FILE "); - writer.println("#include "); - // dumper.writeAll(writer); - - DataTypeWriter dtw = new DataTypeWriter(dtm, writer); - dtw.blacklistedTypes = typeBlacklist; - dtw.write(filteredTypes, monitor); - - headerGuardPost(writer, "STRUCTS"); - } - } - void dumpGlobals(Hashtable globalSymbols) throws Exception { File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h"); PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8"); diff --git a/scripts/DecompileFile.java b/scripts/DecompileFile.java new file mode 100644 index 00000000..4fdba7d2 --- /dev/null +++ b/scripts/DecompileFile.java @@ -0,0 +1,25 @@ +public class DecompileFile { + + public class MyDecompilerAction extends DecompilerAction { + + public MyDecompilerAction() { + super("My Custom Action"); + setDescription("Description of my custom decompiler action"); + setKeyBindingData(new KeyBindingData(KeyEvent.VK_F5, 0)); + } + + @Override + public void actionPerformed(DecompilerActionContext context) { + // Custom action logic goes here + // You can access decompiler results via: + // DecompileResults results = context.getDecompileResults(); + // HighFunction highFunction = results.getHighFunction(); + + // Implement your custom functionality + } + } + + // Register the action in your plugin's init() method: + // tool.addAction(new MyDecompilerAction()); + +} diff --git a/scripts/DumpTypes.java b/scripts/DumpTypes.java new file mode 100644 index 00000000..079976cd --- /dev/null +++ b/scripts/DumpTypes.java @@ -0,0 +1,18 @@ +// Script to dump all custom types from Ghidra +// @category _Reman3 +// @menupath Reman3.Dump Types + +import ghidra.app.script.GhidraScript; +import ghidra.program.model.data.DataType; +import ghidra.program.model.data.ProgramBasedDataTypeManager; +import ghidra.program.model.data.Structure; +import ghidra.program.model.data.TypedefDataType; +import re3lib.TypeDumper; + +public class DumpTypes extends GhidraScript { + @Override + protected void run() throws Exception { + TypeDumper dumper = new TypeDumper(this); + dumper.run(); + } +} diff --git a/scripts/re3lib/RecompileConfig.java b/scripts/re3lib/RecompileConfig.java index 825c8665..b5ca7725 100644 --- a/scripts/re3lib/RecompileConfig.java +++ b/scripts/re3lib/RecompileConfig.java @@ -61,4 +61,10 @@ public class RecompileConfig { decomp.openProgram(currentProgram); decompCache = new DecompileCache(decomp, script.getMonitor()); } + + public void createDirectories() { + dirDecompAuto.mkdirs(); + dirDecompFix.mkdirs(); + dirDecompRef.mkdirs(); + } } diff --git a/scripts/re3lib/TypeDumper.java b/scripts/re3lib/TypeDumper.java new file mode 100644 index 00000000..35a10c41 --- /dev/null +++ b/scripts/re3lib/TypeDumper.java @@ -0,0 +1,72 @@ +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.data.DataType; +import ghidra.program.model.data.EnumDataType; +import ghidra.program.model.data.ProgramBasedDataTypeManager; +import ghidra.program.model.data.Structure; +import ghidra.program.model.data.TypedefDataType; +import ghidra.program.model.listing.Program; + +public class TypeDumper { + Program currentProgram; + GhidraScript script; + + public TypeDumper(GhidraScript script) { + this.script = script; + currentProgram = script.getCurrentProgram(); + RecompileConfig.INSTANCE = new RecompileConfig(script); + } + + public void run() throws Exception { + ProgramBasedDataTypeManager dtm = currentProgram.getDataTypeManager(); + + HashSet typeBlacklist = Utils.loadStructBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath); + + 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, RecompileConfig.INSTANCE.typeBlacklistPath); + } + + List filteredTypes = new ArrayList<>(); + Iterator it = dtm.getAllDataTypes(); + while (it.hasNext()) { + DataType dt = it.next(); + if (dt instanceof Structure || dt instanceof TypedefDataType || dt instanceof EnumDataType) { + if (typeBlacklist.contains(dt.getDisplayName())) + continue; + // println("Adding: " + dt.getDisplayName() + " - " + + // dt.getClass().getSimpleName()); + filteredTypes.add(dt); + } + } + + try (PrintWriter writer = new PrintWriter(new File(RecompileConfig.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.blacklistedTypes = typeBlacklist; + dtw.write(filteredTypes, script.getMonitor()); + + Utils.headerGuardPost(writer, "STRUCTS"); + } + } +} diff --git a/scripts/re3lib/Utils.java b/scripts/re3lib/Utils.java index 9bf585c4..df6d1b5f 100644 --- a/scripts/re3lib/Utils.java +++ b/scripts/re3lib/Utils.java @@ -11,6 +11,16 @@ import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; public class Utils { + public static void headerGuardPre(PrintWriter writer, String tag) { + writer.println("#ifndef GH_GENERATED_" + tag + "_H"); + writer.println("#define GH_GENERATED_" + tag + "_H"); + writer.println(); + } + + public static void headerGuardPost(PrintWriter writer, String tag) { + writer.println("#endif // GH_GENERATED_" + tag + "_H"); + } + public static HashSet loadStructBlacklist(String path) { File file = new File(path); HashSet structBlacklist = new HashSet<>();