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);
// Also mangle everything referenced inside functions
// if headless
if (
isRunningHeadless() &&
s.getObject() instanceof Function 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);
}
}
}
) mangleRefs(f);
}
}
@ -136,7 +122,7 @@ public class MSVC7Mangle extends GhidraScript{
// Apply new name
if (mangled != null) {
s.setName(mangled, SourceType.USER_DEFINED);
makeGlobal(s);
s.setNamespace(currentProgram.getGlobalNamespace());
if (s.getObject() instanceof Function f) {
// Also apply to target function if f is thunk
@ -144,7 +130,7 @@ public class MSVC7Mangle extends GhidraScript{
if (thunked != null) {
final Symbol ts = thunked.getSymbol();
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;
}
private static void makeGlobal(final Symbol s) throws Exception {
/* Move into the global namespace */
// I cannot for the life of me find a more convenient way of
// doing this
while (!s.isGlobal()) s.setNamespace(s.getParentNamespace()
.getParentNamespace());
private void mangleRefs(final Function f) throws Exception {
/* Mangle all symbols referenced in the body of a function */
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());
// 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);
}
}
}
}