Rename gh_structs.h to gh_types.h, split script
This commit is contained in:
parent
619f3c36dc
commit
03dcb159fe
|
@ -344,133 +344,6 @@ public class Decompile extends GhidraScript {
|
||||||
writer.println("#endif // GH_GENERATED_" + tag + "_H");
|
writer.println("#endif // GH_GENERATED_" + tag + "_H");
|
||||||
}
|
}
|
||||||
|
|
||||||
class DependencyTypeDumper {
|
|
||||||
HashSet<DataType> 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<String> typeBlacklist = Utils.loadStructBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath);
|
|
||||||
|
|
||||||
if (typeBlacklist == null) {
|
|
||||||
println("Building struct blacklist from existing data types");
|
|
||||||
typeBlacklist = new HashSet<>();
|
|
||||||
Iterator<DataType> 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<DataType> filteredTypes = new ArrayList<>();
|
|
||||||
Iterator<DataType> 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 <gh_struct_binder.h>");
|
|
||||||
// dumper.writeAll(writer);
|
|
||||||
|
|
||||||
DataTypeWriter dtw = new DataTypeWriter(dtm, writer);
|
|
||||||
dtw.blacklistedTypes = typeBlacklist;
|
|
||||||
dtw.write(filteredTypes, monitor);
|
|
||||||
|
|
||||||
headerGuardPost(writer, "STRUCTS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpGlobals(Hashtable<String, GlobalRec> globalSymbols) throws Exception {
|
void dumpGlobals(Hashtable<String, GlobalRec> globalSymbols) throws Exception {
|
||||||
File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h");
|
File globalSymbolsListH = new File(RecompileConfig.INSTANCE.outputDir, "gh_global.h");
|
||||||
PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8");
|
PrintWriter hwriter = new PrintWriter(globalSymbolsListH, "UTF-8");
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,4 +61,10 @@ public class RecompileConfig {
|
||||||
decomp.openProgram(currentProgram);
|
decomp.openProgram(currentProgram);
|
||||||
decompCache = new DecompileCache(decomp, script.getMonitor());
|
decompCache = new DecompileCache(decomp, script.getMonitor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createDirectories() {
|
||||||
|
dirDecompAuto.mkdirs();
|
||||||
|
dirDecompFix.mkdirs();
|
||||||
|
dirDecompRef.mkdirs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String> typeBlacklist = Utils.loadStructBlacklist(RecompileConfig.INSTANCE.typeBlacklistPath);
|
||||||
|
|
||||||
|
if (typeBlacklist == null) {
|
||||||
|
script.println("Building struct blacklist from existing data types");
|
||||||
|
typeBlacklist = new HashSet<>();
|
||||||
|
Iterator<DataType> 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<DataType> filteredTypes = new ArrayList<>();
|
||||||
|
Iterator<DataType> 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 <gh_struct_binder.h>");
|
||||||
|
|
||||||
|
DataTypeWriter dtw = new DataTypeWriter(dtm, writer);
|
||||||
|
dtw.blacklistedTypes = typeBlacklist;
|
||||||
|
dtw.write(filteredTypes, script.getMonitor());
|
||||||
|
|
||||||
|
Utils.headerGuardPost(writer, "STRUCTS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,16 @@ import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
|
||||||
public class Utils {
|
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<String> loadStructBlacklist(String path) {
|
public static HashSet<String> loadStructBlacklist(String path) {
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
HashSet<String> structBlacklist = new HashSet<>();
|
HashSet<String> structBlacklist = new HashSet<>();
|
||||||
|
|
Loading…
Reference in New Issue