Fix persistent global mapping
This commit is contained in:
@@ -13,20 +13,16 @@ public class DumpCurrentFunction extends GhidraScript {
|
||||
public void run() throws Exception {
|
||||
RecompileConfig.INSTANCE = new RecompileConfig(this);
|
||||
RecompileConfig.INSTANCE.createDirectories();
|
||||
|
||||
|
||||
GlobalDumper globalDumper = new GlobalDumper(this);
|
||||
try {
|
||||
globalDumper.loadGlobalManifest();
|
||||
} catch (Exception e) {
|
||||
println("No global manifest found");
|
||||
}
|
||||
globalDumper.loadGlobalManifest();
|
||||
FunctionDumper functionDumper = new FunctionDumper(this, globalDumper);
|
||||
|
||||
|
||||
Function currentFunction = getFunctionContaining(currentAddress);
|
||||
if (currentFunction != null) {
|
||||
functionDumper.dump(currentFunction);
|
||||
functionDumper.dump(currentFunction);
|
||||
} else {
|
||||
println("No function found at the current address.");
|
||||
println("No function found at the current address.");
|
||||
}
|
||||
|
||||
globalDumper.dumpGlobals();
|
||||
|
@@ -13,13 +13,22 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.datatype.DatatypeFactory;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.AbstractStringDataType;
|
||||
import ghidra.program.model.data.Array;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.DataTypePath;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.Undefined;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.pcode.HighSymbol;
|
||||
import ghidra.util.data.DataTypeParser;
|
||||
import ghidra.util.data.DataTypeParser.AllowedDataTypes;
|
||||
|
||||
public class GlobalDumper {
|
||||
|
||||
@@ -44,26 +53,58 @@ public class GlobalDumper {
|
||||
manifestFile = new File(RecompileConfig.INSTANCE.outputDir, "globals.txt");
|
||||
}
|
||||
|
||||
public void loadGlobalManifest() throws Exception {
|
||||
public boolean loadGlobalManifest() throws Exception {
|
||||
// Globals are stored in the format of
|
||||
// <address> || <name> || <type>
|
||||
|
||||
if (!manifestFile.exists()) {
|
||||
script.println("Global manifest file not found: " + manifestFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the dataTypeManagerService
|
||||
DataTypeManagerService dataTypeManagerService = (DataTypeManagerService) script.getState().getTool()
|
||||
.getService(DataTypeManagerService.class);
|
||||
DataTypeManager dtm = script.getCurrentProgram().getDataTypeManager();
|
||||
DataTypeParser dtp = new DataTypeParser(dataTypeManagerService, AllowedDataTypes.ALL);
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(manifestFile))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] parts = line.split(" || ");
|
||||
if (parts.length == 3) {
|
||||
String address = parts[0];
|
||||
String name = parts[1];
|
||||
String typeName = parts[2];
|
||||
DataType type = script.getCurrentProgram().getDataTypeManager().getDataType(typeName);
|
||||
globalAddrs.put(script.parseAddress(address), new GlobalRec(script.parseAddress(address), name, type));
|
||||
String[] parts = line.split("\\|\\|");
|
||||
if (parts.length == 4) {
|
||||
Address address = script.parseAddress(parts[0].trim());
|
||||
String name = parts[1].trim();
|
||||
String categoryPath = parts[2].trim();
|
||||
String dataTypePath = parts[3].trim();
|
||||
DataTypePath typePath = new DataTypePath(categoryPath, dataTypePath);
|
||||
DataType type = null;
|
||||
type = dtm.getDataType(typePath);
|
||||
if (type == null) {
|
||||
// script.println("Parsing type: " + dataTypePath);
|
||||
type = dtp.parse(dataTypePath);
|
||||
}
|
||||
if (type == null) {
|
||||
script.println("WARNING: Failed to find type: " + dataTypePath + " for global: " + name + " at " + address);
|
||||
continue;
|
||||
}
|
||||
globalAddrs.put(address, new GlobalRec(address, name, type));
|
||||
} else {
|
||||
script.println("Invalid global manifest line: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script.println("Loaded " + globalAddrs.size() + " globals from " + manifestFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addGlobal(Address addr, HighSymbol sym) {
|
||||
globalAddrs.put(addr, new GlobalRec(addr, sym.getName(), sym.getDataType()));
|
||||
DataType dt = sym.getDataType();
|
||||
if (dt == null) {
|
||||
script.println("WARNING: Missing type for global: " + sym.getName() + " at " + addr);
|
||||
return;
|
||||
}
|
||||
globalAddrs.put(addr, new GlobalRec(addr, sym.getName(), dt));
|
||||
}
|
||||
|
||||
String escapeCString(String str) {
|
||||
@@ -172,12 +213,23 @@ public class GlobalDumper {
|
||||
}
|
||||
|
||||
public void saveGlobalManifest() throws Exception {
|
||||
File backupFile = new File(manifestFile.getParentFile(), manifestFile.getName() + ".bak");
|
||||
if (backupFile.exists()) {
|
||||
if (!backupFile.delete()) {
|
||||
throw new Exception("Failed to delete backup file: " + backupFile + ", globals will not be saved!");
|
||||
}
|
||||
}
|
||||
if (!manifestFile.renameTo(backupFile))
|
||||
throw new Exception("Failed to rename manifest file: " + manifestFile + ", globals will not be saved!");
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(manifestFile)) {
|
||||
script.println("Saving global manifest to " + manifestFile);
|
||||
GlobalRec[] globals = globalAddrs.values().toArray(new GlobalRec[0]);
|
||||
Arrays.sort(globals, (a, b) -> a.address.compareTo(b.address));
|
||||
for (GlobalRec global : globals) {
|
||||
writer.println(global.address.toString() + " || " + global.name + " || " + global.type.getDisplayName());
|
||||
DataTypePath path = global.type.getDataTypePath();
|
||||
writer.println(global.address.toString() + " || " + global.name + " || " + path.getCategoryPath() + " || "
|
||||
+ path.getDataTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user