mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 02:07:02 +03:00
Miscellaneous name mangling improvements
Improved error reporting, skipping undesirable symbols like jump tables, skipping special symbols like intrinsics, etc.
This commit is contained in:
parent
78127e64ef
commit
d372c17094
1 changed files with 66 additions and 39 deletions
|
|
@ -107,7 +107,10 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
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);
|
||||
if ( // Guard against spurious references to nonexisting things
|
||||
symbol != null &&
|
||||
symbol.getObject() != null
|
||||
) mangle(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,13 +119,17 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
|
||||
private void mangle(final Symbol s) throws Exception {
|
||||
/* Set the given symbol's name to its mangled version */
|
||||
// Skip if already mangled
|
||||
if (s.getName().charAt(0) == '?') return;
|
||||
// Skip if already mangled; skip jump tables
|
||||
final String name = s.getName(true);
|
||||
if (
|
||||
name.charAt(0) == '?' ||
|
||||
name.startsWith("switchD_")
|
||||
) return;
|
||||
|
||||
// Get mangled name
|
||||
final String mangled = switch (s.getObject()) {
|
||||
case Function f -> mangleFn (f);
|
||||
case Data d -> mangleData(d, s.getName(true));
|
||||
case Data d -> mangleData(d, name);
|
||||
default -> null;
|
||||
};
|
||||
|
||||
|
|
@ -145,17 +152,21 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
|
||||
private String mangleFn(final Function f) throws Exception {
|
||||
/* Generate a mangled name for a function */
|
||||
// Special cases for main()
|
||||
if (f.getName(true).equals("main" )) return "_main";
|
||||
if (f.getName(true).equals("___CxxFrameHandler")) return "___CxxFrameHandler";
|
||||
final String nameRaw = f.getName(true);
|
||||
|
||||
// Special case for main()
|
||||
if (nameRaw.equals("main")) return "_main";
|
||||
|
||||
// Special symbols like intrinsics aren't mangled
|
||||
if (nameRaw.startsWith("__")) return nameRaw;
|
||||
|
||||
final ArrayList<String> dict = new ArrayList<>();
|
||||
|
||||
final List<String> nameParts = Arrays.asList(f.getName(true).split("::"));
|
||||
final List<String> nameParts = Arrays.asList(nameRaw.split("::"));
|
||||
Collections.reverse(nameParts);
|
||||
final boolean isMethod = f.getCallingConventionName().equals("__thiscall") &&
|
||||
nameParts.size() >= 2;
|
||||
final String name = mangleIdentifier(f.getName(true), isMethod, f.getReturnType(), dict);
|
||||
final String name = mangleIdentifier(nameRaw, isMethod, f.getReturnType(), dict);
|
||||
|
||||
// Special methods with unique formats
|
||||
if (isMethod) {
|
||||
|
|
@ -163,14 +174,16 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
final String clsName = nameParts.get(1);
|
||||
|
||||
if (unqualified.equals( clsName)) { // Constructor
|
||||
return "?" + name + "QAE@" + mangleArgs(f.getSignature(true), dict) + "Z";
|
||||
return "?" + name + "QAE@" +
|
||||
mangleArgs(f.getSignature(true), dict, nameRaw + "()") +
|
||||
"Z";
|
||||
} else if (unqualified.equals("~" + clsName)) { // Destructor
|
||||
return "?" + name + (isVirtual(f) ? "UAE" : "QAE") + "@XZ";
|
||||
}
|
||||
}
|
||||
|
||||
return "?" + name + mangleFnAttrs(f, nameParts) +
|
||||
mangleFnType(f.getSignature(true), dict);
|
||||
mangleFnType(f.getSignature(true), dict, nameRaw + "()");
|
||||
}
|
||||
|
||||
private static String mangleIdentifier(
|
||||
|
|
@ -272,7 +285,9 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
final List<T> dict
|
||||
) {
|
||||
/* Produce a backreference string if x is found in dict */
|
||||
switch (Integer.valueOf(dict.indexOf(x))) {
|
||||
if (x instanceof String s && s.startsWith("?"))
|
||||
return Optional.empty(); // No matching special names
|
||||
else switch (Integer.valueOf(dict.indexOf(x))) {
|
||||
case -1:
|
||||
dict.add(x);
|
||||
return Optional.empty();
|
||||
|
|
@ -303,12 +318,15 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
final Function func = getFunctionContaining(refs[i].getFromAddress());
|
||||
|
||||
if (data != null) {
|
||||
final String name = getSymbolAt(data.getRoot()
|
||||
.getAddress()).getName(false);
|
||||
final Symbol s = getSymbolAt(data.getRoot()
|
||||
.getAddress());
|
||||
if (s != null) {
|
||||
final String name = s.getName(false);
|
||||
if (
|
||||
name.equals("`vftable'") ||
|
||||
name.startsWith("??_7")
|
||||
) return true;
|
||||
}
|
||||
} else if (func != null) {
|
||||
final String name = func.getName(false);
|
||||
if (
|
||||
|
|
@ -334,12 +352,13 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
|
||||
private static String mangleFnType(
|
||||
final FunctionSignature f,
|
||||
final List<String> dict
|
||||
final List<String> dict,
|
||||
final String loc
|
||||
) throws Exception {
|
||||
/* Mangle everything in f but its name and visibility/linkage */
|
||||
|
||||
return mangleCallC(f) + mangleType(f.getReturnType(), dict) +
|
||||
mangleArgs(f, dict) + "Z";
|
||||
return mangleCallC(f) +
|
||||
mangleType(f.getReturnType(), dict, loc) +
|
||||
mangleArgs(f, dict, loc) + "Z";
|
||||
}
|
||||
|
||||
private static String mangleCallC(final FunctionSignature f) throws Exception {
|
||||
|
|
@ -358,15 +377,16 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
|
||||
private static String mangleType(
|
||||
final DataType t,
|
||||
final List<String> dict
|
||||
final List<String> dict,
|
||||
final String loc
|
||||
) throws Exception {
|
||||
/* Mangle a data type in a function name
|
||||
All types are assumed to have no CV qualifiers.
|
||||
*/
|
||||
if (t == null) throw new Exception (
|
||||
"A data type was reported as null. Ensure that all " +
|
||||
"data types in the code/data to mangle have been " +
|
||||
"defined."
|
||||
"A data type at " + loc + " was reported as null. " +
|
||||
"Ensure that all data types in the code/data to " +
|
||||
"mangle have been defined."
|
||||
);
|
||||
|
||||
return switch(t) {
|
||||
|
|
@ -384,7 +404,7 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
case LongDoubleDataType _ -> "O";
|
||||
case Pointer p -> "P" +
|
||||
(p.getDataType() instanceof FunctionSignature ? "6" : "A") +
|
||||
mangleType(p.getDataType(), dict);
|
||||
mangleType(p.getDataType(), dict, loc);
|
||||
case Union u -> "T" + mangleIdentifier(u.getName(), false, null, dict);
|
||||
case Structure s -> "U" + mangleIdentifier(s.getName(), false, null, dict);
|
||||
case Enum e -> "W4" + mangleIdentifier(e.getName(), false, null, dict);
|
||||
|
|
@ -393,12 +413,12 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
case UnsignedLongLongDataType _ -> "_K";
|
||||
case BooleanDataType _ -> "_N";
|
||||
case WideCharDataType _ -> "_W";
|
||||
case Array a -> "PA" + mangleArrDims(a) + mangleType(arrType(a), dict);
|
||||
case FunctionSignature f -> mangleFnType(f, dict);
|
||||
case TypeDef d -> mangleType(d.getBaseDataType(), dict);
|
||||
case DefaultDataType _ -> throw new Exception ("Encountered data marked \"undefined\". Ensure that all data types in the code/data to mangle have been defined.");
|
||||
case Undefined _ -> throw new Exception ("Encountered data marked \"undefined\". Ensure that all data types in the code/data to mangle have been defined.");
|
||||
default -> throw new Exception ("Unknown type \"" + t.getClass().getName() + "\"");
|
||||
case Array a -> "PA" + mangleArrDims(a) + mangleType(arrType(a), dict, loc);
|
||||
case FunctionSignature f -> mangleFnType(f, dict, "function typedef \"" + f.getName() + "\"");
|
||||
case TypeDef d -> mangleType(d.getBaseDataType(), dict, "typedef \"" + d.getName() + "\"");
|
||||
case DefaultDataType _ -> throw new Exception ("Encountered data marked \"undefined\" at " + loc + ". Ensure that all data types in the code/data to mangle have been defined.");
|
||||
case Undefined _ -> throw new Exception ("Encountered data marked \"undefined\" at " + loc + ". Ensure that all data types in the code/data to mangle have been defined.");
|
||||
default -> throw new Exception ("Unknown type \"" + t.getClass().getName() + "\" at " + loc);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +466,8 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
|
||||
private static String mangleArgs(
|
||||
final FunctionSignature f,
|
||||
final List<String> dict
|
||||
final List<String> dict,
|
||||
final String loc
|
||||
) throws Exception {
|
||||
/* Mangle the arguments for a function */
|
||||
final DataType[] args = Arrays.stream(f.getArguments())
|
||||
|
|
@ -469,10 +490,15 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
// It turns out that academic-sounding stuff everyone
|
||||
// freaks out at is actually useful (and Optional still
|
||||
// helped us out here)
|
||||
String mangled = "";
|
||||
for (int i = 0; i < args.length; i++)
|
||||
mangled += backref(args[i], argDict).orElse(mangleType(args[i], dict));
|
||||
return mangled + (f.hasVarArgs() ? "Z" : "@");
|
||||
String mangledArgs = "";
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
final String mangledArg = mangleType(args[i], dict, loc);
|
||||
|
||||
mangledArgs += mangledArg.length() == 1 ?
|
||||
mangledArg :
|
||||
backref(args[i], argDict).orElse(mangledArg);
|
||||
}
|
||||
return mangledArgs + (f.hasVarArgs() ? "Z" : "@");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -495,7 +521,8 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
// vtable
|
||||
if (ident.startsWith("?_7")) return "?" + ident + "6B@";
|
||||
|
||||
return "?" + ident + "3" + mangleType(d.getDataType(), dict) +
|
||||
return "?" + ident + "3" +
|
||||
mangleType(d.getDataType(), dict, "0x" + d.getAddress().toString()) +
|
||||
"A";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue