Compare commits

...

2 Commits

Author SHA1 Message Date
Guus Waals 1d305a44c6 Convert to fix dump script 2025-05-31 23:57:56 +08:00
Guus Waals 36b700f66e Cleanup 2025-05-31 23:50:32 +08:00
2 changed files with 79 additions and 17 deletions

View File

@ -0,0 +1,40 @@
// Script to export decompiled C code for selected function from Ghidra as Fix type
// @category _Reman3
// @menupath Reman3.Dump Current Function (Fix)
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.Function;
import re3lib.FunctionDumper;
import re3lib.GlobalDumper;
import re3lib.RemanConfig;
import re3lib.FunctionDatabase;
public class DumpCurrentFunctionFix extends GhidraScript {
@Override
public void run() throws Exception {
RemanConfig.INSTANCE = new RemanConfig(this);
RemanConfig.INSTANCE.createDirectories();
try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) {
GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase);
globalDumper.loadGlobalManifest();
FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper);
// Force Fix type instead of Auto
functionDumper.forceFixType = true;
Function currentFunction = getFunctionContaining(currentAddress);
if (currentFunction != null) {
functionDumper.dump(currentFunction);
} else {
println("No function found at the current address.");
}
if (functionDumper.createdFile)
RemanConfig.INSTANCE.touchCMakeTimestamp();
globalDumper.dumpGlobals();
globalDumper.saveGlobalManifest();
}
}
}

View File

@ -34,6 +34,9 @@ public class FunctionDumper {
// Collects functions called by the current function
public HashSet<Function> functionReferences = new HashSet<>();
// Add flag to force Fix type
public boolean forceFixType = false;
static final Pattern fieldAccessRegex = Pattern.compile("^_([0-9]+)_([0-9]+)_$");
public FunctionDumper(GhidraScript script, FunctionDatabase functionDatabase, GlobalDumper globalDumper) {
@ -104,20 +107,6 @@ public class FunctionDumper {
}
}
public static boolean isDumpedFix(Function function) {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
String fileName = sanitizedFunctionName + ".cxx";
File f0 = new File(RemanConfig.INSTANCE.dirDecompFix, fileName);
return f0.exists();
}
public static boolean isDumpedAuto(Function function) {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
String fileName = sanitizedFunctionName + ".cxx";
File f0 = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName);
return f0.exists();
}
public void dump(Function function)
throws Exception {
String sanitizedFunctionName = Utils.sanitizeIdentifier(function.getName());
@ -126,13 +115,33 @@ public class FunctionDumper {
Address entrypoint = function.getEntryPoint();
List<FunctionDatabase.FunctionEntry> entries = functionDatabase.findEntriesByAddress(entrypoint);
FunctionDatabase.Type targetType = FunctionDatabase.Type.Auto;
// Handle forceFixType flag
if (forceFixType) {
targetType = FunctionDatabase.Type.Fix;
// Remove any existing Auto entries for this function
for (FunctionDatabase.FunctionEntry entry : entries) {
if (entry.type == FunctionDatabase.Type.Auto) {
script.println("Removing existing Auto entry: " + entry.file);
if (entry.file.exists()) {
entry.file.delete();
}
functionDatabase.removeEntryAt(entry.file.toString());
}
}
} else {
// Original logic for determining target type
for (FunctionDatabase.FunctionEntry entry : entries) {
script.println("Found existing decompiled entry at " + entry.file + " - " + entry.name);
if (targetType != FunctionDatabase.Type.Ref) {
if (entry.type == FunctionDatabase.Type.Fix) {
targetType = FunctionDatabase.Type.Ref;
}
}
}
// Always remove stub entries regardless of mode
for (FunctionDatabase.FunctionEntry entry : entries) {
if (entry.type == FunctionDatabase.Type.Stub) {
// Remove the stub file, since we now use the decompiled file
File stubFile = entry.file;
@ -148,10 +157,23 @@ public class FunctionDumper {
File targetFilename = null;
if (targetType == FunctionDatabase.Type.Ref) {
targetFilename = new File(RemanConfig.INSTANCE.dirDecompRef, fileName);
} else if (targetType == FunctionDatabase.Type.Fix) {
targetFilename = new File(RemanConfig.INSTANCE.dirDecompFix, fileName);
} else {
targetFilename = new File(RemanConfig.INSTANCE.dirDecompAuto, fileName);
}
// Handle overwrite prompting for Fix type
if (targetFilename.exists()) {
if (targetType == FunctionDatabase.Type.Fix) {
script.println("Fix file already exists: " + targetFilename);
boolean overwrite = script.askYesNo("Overwrite existing Fix file?",
"The Fix file " + targetFilename.getName() + " already exists. Do you want to overwrite it?");
if (!overwrite) {
script.println("Aborted: User chose not to overwrite existing Fix file.");
return;
}
}
targetFilename.delete();
script.println("Overwriting existing file " + targetFilename);
} else {