Refine for virtual method check in mangling script

We used the flimsy heuristic of a reference from non-executable memory
to try to guess at whether a reference was a vtable, but now we just
check whether it's been named as a vtable.
This commit is contained in:
KeybadeBlox 2026-02-11 21:14:46 -05:00
parent 53b0e82417
commit 0e84f9ab1f

View file

@ -264,24 +264,29 @@ public class MSVC7Mangle extends GhidraScript{
} }
private boolean isVirtual(final Function f) { private boolean isVirtual(final Function f) {
/* Attempt to determine whether a method is virtual /* Determine whether a method is virtual
We essentially try to figure out if any references are from a vtable We essentially check whether any references are from a vtable or a
by checking if they lie in non-executable memory, or from a scalar scalar deleting destructor.
deleting destructor.
*/ */
final Reference[] refs = getReferencesTo(f.getEntryPoint()); final Reference[] refs = getReferencesTo(f.getEntryPoint());
for (int i = 0; i < refs.length; i++) { for (int i = 0; i < refs.length; i++) {
final Address addr = refs[i].getFromAddress(); final Data data = getDataContaining (refs[i].getFromAddress());
final Optional<String> caller = Optional.ofNullable(getFunctionContaining(addr)) final Function func = getFunctionContaining(refs[i].getFromAddress());
.map(x -> x.getName(false));
if ( if (data != null) {
!getMemoryBlock(addr).isExecute() || final String name = getSymbolAt(data.getRoot()
caller.map(x -> x.equals("`scalar_deleting_destructor'")) .getAddress()).getName(false);
.orElse(false) || if (
caller.map(x -> x.startsWith("??_G")) // From mangled name name.equals("`vftable'") ||
.orElse(false) name.startsWith("??_7")
) return true; ) return true;
} else if (func != null) {
final String name = func.getName(false);
if (
name.equals("`scalar_deleting_destructor'") ||
name.startsWith("??_G")
) return true;
}
} }
return false; return false;