Defend against spurious references during mangling

Ghidra sometimes identifies random numbers as pointers, which trips up
our mangler script when it encounters them as they generally have no
type information.  We now use heuristics to ignore such references.
This commit is contained in:
KeybadeBlox 2026-02-13 23:37:22 -05:00
parent 022582003d
commit ccd2cd37a5
2 changed files with 37 additions and 26 deletions

View file

@ -44,4 +44,4 @@
} }
} }
] ]
} }

View file

@ -94,26 +94,12 @@ public class MSVC7Mangle extends GhidraScript{
mangle(s); mangle(s);
// Also mangle everything referenced inside functions
// if headless
if ( if (
isRunningHeadless() && isRunningHeadless() &&
s.getObject() instanceof Function f s.getObject() instanceof Function f
) { ) mangleRefs(f);
// Also mangle everything referenced inside f
for (
Instruction ins = getFirstInstruction(f);
ins != null && f.getBody().contains(ins.getAddress());
ins = ins.getNext()
) {
final Reference[] refs = ins.getReferencesFrom();
for (int i = 0; i < refs.length; i++) {
final Symbol symbol = getSymbolAt(refs[i].getToAddress());
if ( // Guard against spurious references to nonexisting things
symbol != null &&
symbol.getObject() != null
) mangle(symbol);
}
}
}
} }
} }
@ -136,7 +122,7 @@ public class MSVC7Mangle extends GhidraScript{
// Apply new name // Apply new name
if (mangled != null) { if (mangled != null) {
s.setName(mangled, SourceType.USER_DEFINED); s.setName(mangled, SourceType.USER_DEFINED);
makeGlobal(s); s.setNamespace(currentProgram.getGlobalNamespace());
if (s.getObject() instanceof Function f) { if (s.getObject() instanceof Function f) {
// Also apply to target function if f is thunk // Also apply to target function if f is thunk
@ -144,7 +130,7 @@ public class MSVC7Mangle extends GhidraScript{
if (thunked != null) { if (thunked != null) {
final Symbol ts = thunked.getSymbol(); final Symbol ts = thunked.getSymbol();
ts.setName(mangled, SourceType.USER_DEFINED); ts.setName(mangled, SourceType.USER_DEFINED);
makeGlobal(ts); ts.setNamespace(currentProgram.getGlobalNamespace());
} }
} }
} }
@ -594,11 +580,36 @@ public class MSVC7Mangle extends GhidraScript{
return (int)crc.getValue() ^ 0xFFFFFFFF; return (int)crc.getValue() ^ 0xFFFFFFFF;
} }
private static void makeGlobal(final Symbol s) throws Exception { private void mangleRefs(final Function f) throws Exception {
/* Move into the global namespace */ /* Mangle all symbols referenced in the body of a function */
// I cannot for the life of me find a more convenient way of for (
// doing this Instruction ins = getFirstInstruction(f);
while (!s.isGlobal()) s.setNamespace(s.getParentNamespace() ins != null && f.getBody().contains(ins.getAddress());
.getParentNamespace()); ins = ins.getNext()
) {
final Reference[] refs = ins.getReferencesFrom();
for (int i = 0; i < refs.length; i++) {
final Symbol symbol = getSymbolAt(refs[i].getToAddress());
// Guard against spurious references to nonexisting things
if (
symbol == null ||
symbol.getObject() == null ||
(
symbol.getObject() instanceof Data d &&
(
d.getBaseDataType() instanceof Undefined ||
d.getBaseDataType() instanceof DefaultDataType
) &&
refs[i].getSource() != SourceType.USER_DEFINED
)
) {
removeReference(refs[i]);
continue;
}
mangle(symbol);
}
}
} }
} }