Mangle referenced symbols in mangling script

This produces correct symbol names in disassembly in objdiff.
This commit is contained in:
KeybadeBlox 2026-02-12 00:36:40 -05:00
parent 0e84f9ab1f
commit 05b4da2f78

View file

@ -19,6 +19,7 @@
// @category Symbol // @category Symbol
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.Array; import ghidra.program.model.data.Array;
@ -53,6 +54,7 @@ import ghidra.program.model.data.WideCharDataType;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionSignature; import ghidra.program.model.listing.FunctionSignature;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
@ -74,16 +76,12 @@ public class MSVC7Mangle extends GhidraScript{
public void run() throws Exception { public void run() throws Exception {
// Get selected ranges from arguments if invoked headless // Get selected ranges from arguments if invoked headless
if (isRunningHeadless()) { if (isRunningHeadless()) {
final String[] args = getScriptArgs();
final AddressSet addr = new AddressSet(); final AddressSet addr = new AddressSet();
for (int i = 0; i < args.length; i++) { Arrays.stream(getScriptArgs()).forEach(arg -> {
final String[] range = args[i].split("-"); final String[] range = arg.split("-");
addr.add( addr.add(toAddr(range[0]), toAddr(range[1]));
currentAddress.getAddress(range[0]), });
currentAddress.getAddress(range[1])
);
}
setCurrentSelection(addr); setCurrentSelection(addr);
} }
@ -94,31 +92,62 @@ public class MSVC7Mangle extends GhidraScript{
while (iter.hasNext() && !monitor.isCancelled()) { while (iter.hasNext() && !monitor.isCancelled()) {
final Symbol s = iter.next(); final Symbol s = iter.next();
// Skip if already mangled mangle(s);
if (s.getName().charAt(0) == '?') return;
// Get mangled name if (
final String mangled = switch (s.getObject()) { isRunningHeadless() &&
case Function f -> mangleFn (f); s.getObject() instanceof Function f
case Data d -> mangleData(d, s.getName(true)); ) {
default -> null; // Also mangle everything referenced inside f
}; for (
Instruction ins = getFirstInstruction(f);
// Apply new name ins != null && f.getBody().contains(ins.getAddress());
if (mangled != null) { ins = ins.getNext()
s.setName(mangled, SourceType.USER_DEFINED); ) {
makeGlobal(s); final Reference[] refs = ins.getReferencesFrom();
for (int i = 0; i < refs.length; i++) {
final Symbol symbol = getSymbolAt(refs[i].getToAddress());
if (symbol != null) mangle(symbol);
}
}
} }
}
}
// TODO: in headless mode, also mangle everything private void mangle(final Symbol s) throws Exception {
// referenced by functions /* Set the given symbol's name to its mangled version */
// Skip if already mangled
if (s.getName().charAt(0) == '?') return;
// Get mangled name
final String mangled = switch (s.getObject()) {
case Function f -> mangleFn (f);
case Data d -> mangleData(d, s.getName(true));
default -> null;
};
// Apply new name
if (mangled != null) {
s.setName(mangled, SourceType.USER_DEFINED);
makeGlobal(s);
if (s.getObject() instanceof Function f) {
// Also apply to target function if f is thunk
final Function thunked = f.getThunkedFunction(true);
if (thunked != null) {
final Symbol ts = thunked.getSymbol();
ts.setName(mangled, SourceType.USER_DEFINED);
makeGlobal(ts);
}
}
} }
} }
private String mangleFn(final Function f) throws Exception { private String mangleFn(final Function f) throws Exception {
/* Generate a mangled name for a function */ /* Generate a mangled name for a function */
// Special case for main() // Special cases for main()
if (f.getName(true).equals("main")) return "_main"; if (f.getName(true).equals("main" )) return "_main";
if (f.getName(true).equals("___CxxFrameHandler")) return "___CxxFrameHandler";
final ArrayList<String> dict = new ArrayList<>(); final ArrayList<String> dict = new ArrayList<>();