mirror of https://github.com/zeldaret/botw.git
119 lines
4.1 KiB
Java
119 lines
4.1 KiB
Java
// Script to load BotW CSV data into Ghidra
|
|
//@author AlexApps99
|
|
//@category BotW
|
|
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.symbol.SourceType;
|
|
import java.io.BufferedReader;
|
|
import java.io.FileReader;
|
|
import java.io.File;
|
|
import ghidra.program.model.address.Address;
|
|
import ghidra.program.model.listing.Function;
|
|
import ghidra.program.model.listing.FunctionManager;
|
|
import ghidra.app.cmd.label.DemanglerCmd;
|
|
import ghidra.program.model.address.AddressSet;
|
|
import ghidra.util.NumericUtilities;
|
|
import ghidra.app.cmd.label.DemanglerCmd;
|
|
import ghidra.program.model.listing.FunctionTag;
|
|
import ghidra.util.exception.DuplicateNameException;
|
|
import ghidra.program.model.listing.FunctionTagManager;
|
|
|
|
public class RenameFunctionsInGhidra extends GhidraScript {
|
|
private FunctionManager func_mgr;
|
|
private FunctionTagManager func_tag_mgr;
|
|
private String ok;
|
|
private String minor;
|
|
private String major;
|
|
private String wip;
|
|
private String undecompiled;
|
|
private String lib;
|
|
|
|
private FunctionTag getOrMake(String name) {
|
|
FunctionTag f = func_tag_mgr.getFunctionTag(name);
|
|
if (f == null) f = func_tag_mgr.createFunctionTag(name, null);
|
|
return f;
|
|
}
|
|
|
|
@Override
|
|
public void run() throws Exception {
|
|
func_mgr = currentProgram.getFunctionManager();
|
|
func_tag_mgr = func_mgr.getFunctionTagManager();
|
|
ok = getOrMake("OK").getName();
|
|
minor = getOrMake("MINOR").getName();
|
|
major = getOrMake("MAJOR").getName();
|
|
wip = getOrMake("WIP").getName();
|
|
undecompiled = getOrMake("UNDECOMPILED").getName();
|
|
lib = getOrMake("LIBRARY").getName();
|
|
|
|
|
|
File input_csv = askFile("uking_functions.csv", "Go");
|
|
try (BufferedReader br = new BufferedReader(new FileReader(input_csv))) {
|
|
// Skip header
|
|
String line = br.readLine();
|
|
while ((line = br.readLine()) != null) {
|
|
String[] pieces = line.split(",", -4); // Don't skip empty last column
|
|
if (pieces.length != 4) throw new Exception("Invalid CSV row: " + line);
|
|
|
|
Address addr = toAddr(pieces[0]);
|
|
String status = pieces[1];
|
|
long func_size = func_size = NumericUtilities.parseLong(pieces[2].strip());
|
|
|
|
String name = pieces[3].strip();
|
|
|
|
Function func = applyFunction(addr, status, name, func_size);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// TODO the j_ prefix probably breaks demangling
|
|
private Function applyFunction(Address addr, String status, String name, long func_size) throws Exception {
|
|
if (name.isEmpty()) name = null;
|
|
|
|
Function func = func_mgr.getFunctionAt(addr);
|
|
AddressSet body = new AddressSet(addr, addr.addNoWrap(func_size - 1));
|
|
|
|
|
|
if (func != null) {
|
|
// Demangling can break this, hence the try-catch
|
|
try {
|
|
if (func.getName() != name) func.setName(name, SourceType.IMPORTED);
|
|
} catch (DuplicateNameException e) {}
|
|
if (!func.getBody().hasSameAddresses(body)) {
|
|
func.setBody(body);
|
|
}
|
|
} else {
|
|
func = func_mgr.createFunction(name, addr, body, SourceType.IMPORTED);
|
|
}
|
|
|
|
if (name != null) {
|
|
DemanglerCmd cmd = new DemanglerCmd(addr, name);
|
|
if (!cmd.applyTo(currentProgram, monitor)) {
|
|
// Something that isn't mangled
|
|
}
|
|
}
|
|
|
|
func.removeTag(ok);
|
|
func.removeTag(minor);
|
|
func.removeTag(major);
|
|
func.removeTag(wip);
|
|
func.removeTag(undecompiled);
|
|
func.removeTag(lib);
|
|
if (status.equals("O")) {
|
|
func.addTag(ok);
|
|
} else if (status.equals("m")) {
|
|
func.addTag(minor);
|
|
} else if (status.equals("M")) {
|
|
func.addTag(major);
|
|
} else if (status.equals("W")) {
|
|
func.addTag(wip);
|
|
} else if (status.equals("L")) {
|
|
func.addTag(lib);
|
|
func.addTag(undecompiled);
|
|
} else {
|
|
func.addTag(undecompiled);
|
|
}
|
|
|
|
return func;
|
|
}
|
|
} |