Prevent repeated name mangling

A symbol could be encountered more than once in headless mode if it
appeared in the body of a function.  The mangler script now tracks which
symbols have been seen to avoid this.
This commit is contained in:
KeybadeBlox 2026-02-20 21:44:43 -05:00
parent bbe9d63294
commit 9b6c91a12e

View file

@ -66,8 +66,10 @@ import ghidra.program.model.symbol.Symbol;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.zip.CRC32; import java.util.zip.CRC32;
@ -88,28 +90,35 @@ public class MSVC7Mangle extends GhidraScript {
setCurrentSelection(addr); setCurrentSelection(addr);
} }
final HashSet<Symbol> seenSymbols = new HashSet<>(1024);
for (final Symbol s : currentProgram.getSymbolTable() for (final Symbol s : currentProgram.getSymbolTable()
.getPrimarySymbolIterator(currentSelection, true)) { .getPrimarySymbolIterator(currentSelection, true)) {
mangle(s); mangle(s, seenSymbols);
// Also mangle everything referenced inside functions // Also mangle everything referenced inside functions
// if headless // if headless
if ( if (
isRunningHeadless() && isRunningHeadless() &&
s.getObject() instanceof Function f s.getObject() instanceof Function f
) mangleRefs(f); ) mangleRefs(f, seenSymbols);
} }
} }
private void mangle(final Symbol s) throws Exception { private void mangle(
final Symbol s,
final Set seenSymbols
) throws Exception {
/* Set the given symbol's name to its mangled version */ /* Set the given symbol's name to its mangled version */
// Skip if already mangled; skip jump tables // Skip if already mangled; skip jump tables
final String name = s.getName(true); final String name = s.getName(true);
if ( if (
seenSymbols.contains(s) ||
name.charAt(0) == '?' || name.charAt(0) == '?' ||
name.startsWith("switchD_") name.startsWith("switchD_")
) return; ) return;
seenSymbols.add(s);
// Get mangled name // Get mangled name
final String mangled = switch (s.getObject()) { final String mangled = switch (s.getObject()) {
case Function f -> mangleFn (f); case Function f -> mangleFn (f);
@ -622,7 +631,10 @@ public class MSVC7Mangle extends GhidraScript {
return (int)crc.getValue() ^ 0xFFFFFFFF; return (int)crc.getValue() ^ 0xFFFFFFFF;
} }
private void mangleRefs(final Function f) throws Exception { private void mangleRefs(
final Function f,
final Set seenSymbols
) throws Exception {
/* Mangle all symbols referenced in the body of a function */ /* Mangle all symbols referenced in the body of a function */
for ( for (
Instruction ins = getFirstInstruction(f); Instruction ins = getFirstInstruction(f);
@ -650,7 +662,7 @@ public class MSVC7Mangle extends GhidraScript {
continue; continue;
} }
mangle(symbol); mangle(symbol, seenSymbols);
} }
} }
} }