From 836c856258c318d135bc02fd1f177d598f881d0f Mon Sep 17 00:00:00 2001 From: Guus Waals <_@guusw.nl> Date: Mon, 2 Jun 2025 12:12:39 +0800 Subject: [PATCH] Remove global load/save functions --- GhidraScripts/DumpCurrentFunction.java | 2 - GhidraScripts/DumpCurrentFunctionFix.java | 2 - .../DumpCurrentFunctionRecursive.java | 2 - GhidraScripts/DumpGlobals.java | 2 - GhidraScripts/SanitizeGlobalSymbols.java | 11 +- GhidraScripts/re3lib/FunctionDatabase.java | 1 - GhidraScripts/re3lib/GlobalDumper.java | 118 ++++++++---------- 7 files changed, 56 insertions(+), 82 deletions(-) diff --git a/GhidraScripts/DumpCurrentFunction.java b/GhidraScripts/DumpCurrentFunction.java index 5cc5691a..b03010db 100644 --- a/GhidraScripts/DumpCurrentFunction.java +++ b/GhidraScripts/DumpCurrentFunction.java @@ -17,7 +17,6 @@ public class DumpCurrentFunction extends GhidraScript { try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) { GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase); - globalDumper.loadGlobalManifest(); FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper); Function currentFunction = getFunctionContaining(currentAddress); @@ -31,7 +30,6 @@ public class DumpCurrentFunction extends GhidraScript { RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); } } } diff --git a/GhidraScripts/DumpCurrentFunctionFix.java b/GhidraScripts/DumpCurrentFunctionFix.java index 868d1a4a..d1e46939 100644 --- a/GhidraScripts/DumpCurrentFunctionFix.java +++ b/GhidraScripts/DumpCurrentFunctionFix.java @@ -17,7 +17,6 @@ public class DumpCurrentFunctionFix extends GhidraScript { 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 @@ -34,7 +33,6 @@ public class DumpCurrentFunctionFix extends GhidraScript { RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); } } } \ No newline at end of file diff --git a/GhidraScripts/DumpCurrentFunctionRecursive.java b/GhidraScripts/DumpCurrentFunctionRecursive.java index 6800a5d5..960701b9 100644 --- a/GhidraScripts/DumpCurrentFunctionRecursive.java +++ b/GhidraScripts/DumpCurrentFunctionRecursive.java @@ -22,7 +22,6 @@ public class DumpCurrentFunctionRecursive extends GhidraScript { try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) { GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase); - globalDumper.loadGlobalManifest(); FunctionDumper functionDumper = new FunctionDumper(this, functionDatabase, globalDumper); @@ -70,7 +69,6 @@ public class DumpCurrentFunctionRecursive extends GhidraScript { RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); } // Dump types diff --git a/GhidraScripts/DumpGlobals.java b/GhidraScripts/DumpGlobals.java index 7e3c8c87..d769ded1 100644 --- a/GhidraScripts/DumpGlobals.java +++ b/GhidraScripts/DumpGlobals.java @@ -16,10 +16,8 @@ public class DumpGlobals extends GhidraScript { try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) { GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase); - globalDumper.loadGlobalManifest(); globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); TypeDumper dumper = new TypeDumper(this); dumper.run(); diff --git a/GhidraScripts/SanitizeGlobalSymbols.java b/GhidraScripts/SanitizeGlobalSymbols.java index 5576d44b..5a7238b7 100644 --- a/GhidraScripts/SanitizeGlobalSymbols.java +++ b/GhidraScripts/SanitizeGlobalSymbols.java @@ -5,6 +5,7 @@ import ghidra.app.script.GhidraScript; import re3lib.GlobalDumper; import re3lib.RemanConfig; +import re3lib.FunctionDatabase; public class SanitizeGlobalSymbols extends GhidraScript { @Override @@ -12,12 +13,12 @@ public class SanitizeGlobalSymbols extends GhidraScript { RemanConfig.INSTANCE = new RemanConfig(this); RemanConfig.INSTANCE.createDirectories(); - GlobalDumper globalDumper = new GlobalDumper(this); - globalDumper.loadGlobalManifest(); + try (FunctionDatabase functionDatabase = new FunctionDatabase(this)) { + GlobalDumper globalDumper = new GlobalDumper(this, functionDatabase); - globalDumper.sanitizeGlobalSymbols(); + globalDumper.sanitizeGlobalSymbols(); - globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); + globalDumper.dumpGlobals(); + } } } diff --git a/GhidraScripts/re3lib/FunctionDatabase.java b/GhidraScripts/re3lib/FunctionDatabase.java index 74abfe75..a1fc49b4 100644 --- a/GhidraScripts/re3lib/FunctionDatabase.java +++ b/GhidraScripts/re3lib/FunctionDatabase.java @@ -673,7 +673,6 @@ public class FunctionDatabase implements AutoCloseable { // Update CMake timestamp RemanConfig.INSTANCE.touchCMakeTimestamp(); globalDumper.dumpGlobals(); - globalDumper.saveGlobalManifest(); TypeDumper typeDumper = new TypeDumper(script); typeDumper.run(); diff --git a/GhidraScripts/re3lib/GlobalDumper.java b/GhidraScripts/re3lib/GlobalDumper.java index 4d95d146..bc46174e 100644 --- a/GhidraScripts/re3lib/GlobalDumper.java +++ b/GhidraScripts/re3lib/GlobalDumper.java @@ -48,7 +48,6 @@ public class GlobalDumper { GhidraScript script; FunctionDatabase functionDatabase; - HashMap globalAddrs = new HashMap<>(); public GlobalDumper(GhidraScript script, FunctionDatabase functionDatabase) { this.script = script; @@ -56,57 +55,14 @@ public class GlobalDumper { } public void removeGlobalManifest() { - // Remove globals from database instead of file + // Remove globals from database try { functionDatabase.removeGlobalsByFilepath(RemanConfig.INSTANCE.GLOBAL_H_FILE); - globalAddrs.clear(); } catch (Exception e) { script.println("Error removing global manifest: " + e.getMessage()); } } - public boolean loadGlobalManifest() throws Exception { - globalAddrs.clear(); - - // Load globals from database - List dbGlobals = functionDatabase.loadAllGlobals(); - - // Get the dataTypeManagerService for parsing types - DataTypeManagerService dataTypeManagerService = (DataTypeManagerService) script.getState().getTool() - .getService(DataTypeManagerService.class); - DataTypeManager dtm = script.getCurrentProgram().getDataTypeManager(); - DataTypeParser dtp = new DataTypeParser(dataTypeManagerService, AllowedDataTypes.ALL); - - for (FunctionDatabase.GlobalEntry entry : dbGlobals) { - // Note: The database stores type as string, need to reconstruct DataType - // For now, we'll parse it back from the type string stored in database - // This is a limitation of moving from the manifest format - DataType type = null; - - // Try to get from existing data at address - Data data = script.getDataAt(entry.address); - if (data != null) { - type = data.getDataType(); - } - - if (type == null) { - script.println("WARNING: Could not reconstruct type for global: " + entry.name + " at " + entry.address); - type = dtp.parse("undefined4"); - } - - // Retrieve the name again - Symbol sym = script.getSymbolAt(entry.address); - if (sym != null) { - entry.name = sym.getName(); - } - - globalAddrs.put(entry.address, new GlobalRec(entry.address, entry.name, type)); - } - - script.println("Loaded " + globalAddrs.size() + " globals from database"); - return !globalAddrs.isEmpty(); - } - String escapeCString(String str) { str = str.replace("\\", "\\\\"); str = str.replace("\"", "\\\""); @@ -149,7 +105,39 @@ public class GlobalDumper { cwriter.println("#include "); hwriter.println(); - List globals = new ArrayList<>(globalAddrs.values()); + // Load globals directly from database + List dbGlobals = functionDatabase.loadAllGlobals(); + List globals = new ArrayList<>(); + + // Convert database entries to GlobalRec objects + for (FunctionDatabase.GlobalEntry entry : dbGlobals) { + DataType type = null; + + // Try to get from existing data at address + Data data = script.getDataAt(entry.address); + if (data != null) { + type = data.getDataType(); + } + + if (type == null) { + script.println("WARNING: Could not determine type for global: " + entry.name + " at " + entry.address); + // Get the dataTypeManagerService for parsing types + DataTypeManagerService dataTypeManagerService = (DataTypeManagerService) script.getState().getTool() + .getService(DataTypeManagerService.class); + DataTypeParser dtp = new DataTypeParser(dataTypeManagerService, AllowedDataTypes.ALL); + type = dtp.parse("undefined4"); + } + + // Retrieve the current symbol name (may have changed since stored) + Symbol sym = script.getSymbolAt(entry.address); + String currentName = entry.name; + if (sym != null) { + currentName = sym.getName(); + } + + globals.add(new GlobalRec(entry.address, currentName, type)); + } + globals.sort((o1, o2) -> o1.address.compareTo(o2.address)); for (GlobalRec global : globals) { @@ -217,19 +205,6 @@ public class GlobalDumper { cwriter.close(); } - public void saveGlobalManifest() throws Exception { - // Save globals to database instead of file - script.println("Saving globals to database"); - - // Clear existing globals for the default filepath - functionDatabase.removeGlobalsByFilepath(RemanConfig.GLOBAL_H_FILE); - - // Add all current globals to database - for (GlobalRec global : globalAddrs.values()) { - functionDatabase.addGlobal(global.address, global.name); - } - } - public void addGlobal(Address addr, HighSymbol sym) throws Exception { if (sym.getName().equals("ExceptionList")) { return; @@ -257,23 +232,30 @@ public class GlobalDumper { } // script.println("Global: " + addr + " - " + sym.getName() + " - " + // dt.getDisplayName()); - globalAddrs.put(addr, new GlobalRec(addr, sym.getName(), dt)); + + // Add directly to database instead of storing in memory + functionDatabase.addGlobal(addr, sym.getName()); } - public void sanitizeGlobalSymbols() { - for (GlobalRec global : globalAddrs.values()) { - String sanitizedName = Utils.sanitizeIdentifier(global.name); - if (!sanitizedName.equals(global.name)) { - Symbol symbol = script.getSymbolAt(global.address); + public void sanitizeGlobalSymbols() throws Exception { + // Load globals from database, sanitize symbol names, and update both Ghidra symbols and database + List dbGlobals = functionDatabase.loadAllGlobals(); + + for (FunctionDatabase.GlobalEntry entry : dbGlobals) { + String sanitizedName = Utils.sanitizeIdentifier(entry.name); + if (!sanitizedName.equals(entry.name)) { + Symbol symbol = script.getSymbolAt(entry.address); if (symbol != null) { - script.println("Renaming global symbol: " + global.name + " -> " + sanitizedName); - AddLabelCmd cmd = new AddLabelCmd(global.address, sanitizedName, + script.println("Renaming global symbol: " + entry.name + " -> " + sanitizedName); + AddLabelCmd cmd = new AddLabelCmd(entry.address, sanitizedName, symbol.getParentNamespace(), SourceType.USER_DEFINED); if (!cmd.applyTo(script.getCurrentProgram())) { script.println("Error renaming symbol: " + cmd.getStatusMsg()); + } else { + // Update the database with the new name + functionDatabase.addGlobal(entry.address, sanitizedName); } - global.name = sanitizedName; } } }