mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 02:07:02 +03:00
Add C symbol support to name mangling Ghida script
This commit is contained in:
parent
d435282a8b
commit
92179ea9bd
1 changed files with 52 additions and 9 deletions
|
|
@ -11,6 +11,9 @@
|
||||||
// appear in objdiff, replacing spaces with underscores, e.g. "operator_new"
|
// appear in objdiff, replacing spaces with underscores, e.g. "operator_new"
|
||||||
// and "`scalar_deleting_destructor'" (notice the ` and ').
|
// and "`scalar_deleting_destructor'" (notice the ` and ').
|
||||||
//
|
//
|
||||||
|
// MSVC also applies minor name mangling to C symbols. This can be enabled for
|
||||||
|
// a given symbol by placing it in a top-level namespace named extern_"C".
|
||||||
|
//
|
||||||
// This script can be called in headless mode with the address ranges to mangle
|
// This script can be called in headless mode with the address ranges to mangle
|
||||||
// as arguments, e.g. 0x1234-0x5678. Any symbols referenced by functions being
|
// as arguments, e.g. 0x1234-0x5678. Any symbols referenced by functions being
|
||||||
// mangled will also be mangled in this mode (so that the references are
|
// mangled will also be mangled in this mode (so that the references are
|
||||||
|
|
@ -135,21 +138,56 @@ public class MSVC7Mangle extends GhidraScript{
|
||||||
/* Generate a mangled name for a function */
|
/* Generate a mangled name for a function */
|
||||||
final String nameRaw = f.getName(true);
|
final String nameRaw = f.getName(true);
|
||||||
|
|
||||||
// Internal symbols like intrinsics aren't mangled
|
// main() and extern "C" symbols get C name mangling
|
||||||
if (nameRaw.startsWith("_")) return nameRaw;
|
// (some other things, do, too, but just use extern "C" instead
|
||||||
|
// of making me find and list them all...)
|
||||||
|
return nameRaw == "main" ||
|
||||||
|
nameRaw.startsWith("extern_\"C\"::") ? mangleCFn (f)
|
||||||
|
: mangleCppFn(f);
|
||||||
|
}
|
||||||
|
|
||||||
// Other special cases
|
private static String mangleCFn(final Function f) throws Exception {
|
||||||
switch (nameRaw) {
|
/* Produce a C function mangled name
|
||||||
case "atexit": return "_atexit";
|
(MSVC does indeed do this despite the folk wisdom that only C++ gets
|
||||||
case "main" : return "_main" ;
|
name mangling; it is certainly simpler than the C++ sort, at least)
|
||||||
default : {}
|
*/
|
||||||
}
|
return switch (f.getCallingConventionName()) {
|
||||||
|
case "__cdecl" -> "_" + f.getName(false);
|
||||||
|
case "__stdcall" -> "_" + f.getName(false) + argSize(f);
|
||||||
|
case "__fastcall" -> "@" + f.getName(false) + argSize(f);
|
||||||
|
case "__thiscall" -> throw new Exception(
|
||||||
|
f.getName() +
|
||||||
|
"(): __thiscall not allowed for C symbols"
|
||||||
|
);
|
||||||
|
default -> throw new Exception(
|
||||||
|
f.getName() +
|
||||||
|
"(): Need to specify calling convention"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String argSize(final Function f) {
|
||||||
|
/* Produce the argument size suffix for a C function
|
||||||
|
The format is "@123" where "123" is however many bytes the arguments
|
||||||
|
occupy (each argument occupies at least four bytes).
|
||||||
|
*/
|
||||||
|
return "@" + Arrays.stream(f.getSignature(true).getArguments())
|
||||||
|
.map(ParameterDefinition::getDataType)
|
||||||
|
.map(t -> Math.max(t.getLength(), 4))
|
||||||
|
.reduce(0, Integer::sum)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mangleCppFn(final Function f) throws Exception {
|
||||||
|
/* Produce a C++ function mangled name */
|
||||||
|
final String nameRaw = f.getName(true);
|
||||||
|
|
||||||
final ArrayList<String> dict = new ArrayList<>();
|
final ArrayList<String> dict = new ArrayList<>();
|
||||||
|
|
||||||
final List<String> nameParts = Arrays.asList(nameRaw.split("::"));
|
final List<String> nameParts = Arrays.asList(nameRaw.split("::"));
|
||||||
Collections.reverse(nameParts);
|
Collections.reverse(nameParts);
|
||||||
final boolean isMethod = f.getCallingConventionName().equals("__thiscall") &&
|
final boolean isMethod = f.getCallingConventionName()
|
||||||
|
.equals("__thiscall") &&
|
||||||
nameParts.size() >= 2;
|
nameParts.size() >= 2;
|
||||||
final String name = mangleIdentifier(nameRaw, isMethod, f.getReturnType(), dict);
|
final String name = mangleIdentifier(nameRaw, isMethod, f.getReturnType(), dict);
|
||||||
|
|
||||||
|
|
@ -500,6 +538,11 @@ public class MSVC7Mangle extends GhidraScript{
|
||||||
);
|
);
|
||||||
|
|
||||||
// Other data
|
// Other data
|
||||||
|
if (name.startsWith("extern_\"C\"::")) {
|
||||||
|
final String[] nameParts = name.split("::");
|
||||||
|
return "_" + nameParts[nameParts.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
final ArrayList<String> dict = new ArrayList<>();
|
final ArrayList<String> dict = new ArrayList<>();
|
||||||
final String ident = mangleIdentifier(name, false, null, dict);
|
final String ident = mangleIdentifier(name, false, null, dict);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue