mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 02:07:02 +03:00
Begin Ghidra mangling script
Looks like we'll be writing our own Ghidra scripts. At least these should enable pretty thorough sharing of work and decent UX.
This commit is contained in:
parent
e668b52cd0
commit
76e39fdd27
1 changed files with 111 additions and 0 deletions
111
ghidra/ghidra_scripts/MSVC7Mangle.java
Normal file
111
ghidra/ghidra_scripts/MSVC7Mangle.java
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Applies Visual C++ 7.0 name mangling to the symbols within the selected
|
||||
// address range (or the whole program if nothing is selected).
|
||||
//
|
||||
// Be aware that the mangling implementation is only partial.
|
||||
//
|
||||
// @category Symbol
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.Enum;
|
||||
import ghidra.program.model.data.IntegerDataType;
|
||||
import ghidra.program.model.data.VoidDataType;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MSVC7Mangle extends GhidraScript{
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
final SymbolIterator iter = currentProgram.getSymbolTable()
|
||||
.getPrimarySymbolIterator(currentSelection, true);
|
||||
|
||||
while (iter.hasNext() && !monitor.isCancelled()) {
|
||||
final Symbol s = iter.next();
|
||||
|
||||
switch (s.getObject()) {
|
||||
case Function f -> demangleFn(f);
|
||||
case Data d -> demangleData(s);
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void demangleFn(final Function f) throws Exception {
|
||||
// Gather everything needed for mangling
|
||||
final List<String> name = Arrays.asList(f.getName(true)
|
||||
.split("::"));
|
||||
Collections.reverse(name);
|
||||
final String callc = f.getCallingConventionName();
|
||||
final DataType ret = f.getReturnType();
|
||||
final DataType[] args = Arrays.stream(f.getSignature(true)
|
||||
.getArguments())
|
||||
.map(x -> x.getDataType())
|
||||
.toArray(DataType[]::new);
|
||||
|
||||
// Construct mangled name
|
||||
final String mangled =
|
||||
"?" + String.join("@", name) + "@@" +
|
||||
switch (callc) {
|
||||
case "__cdecl" -> "YA";
|
||||
case "__thiscall" -> isVirtual(f) ? "UAE" :
|
||||
"QAE";
|
||||
case "__fastcall" -> ""; // TODO
|
||||
default -> throw new Exception(
|
||||
"Need to specify calling convention"
|
||||
);
|
||||
} +
|
||||
mangleType(ret) +
|
||||
mangleArgs(args) +
|
||||
"Z";
|
||||
|
||||
f.setName(mangled, SourceType.USER_DEFINED);
|
||||
}
|
||||
|
||||
private void demangleData(final Symbol s) {
|
||||
// TODO
|
||||
printf("TODO: data symbol \"%s\"\n", s.getName(true));
|
||||
}
|
||||
|
||||
private boolean isVirtual(final Function f) {
|
||||
/* Attempt to determine whether a method is virtual
|
||||
We essentially try to figure out if any references are from a vtable.
|
||||
*/
|
||||
final Reference[] refs = getReferencesTo(f.getEntryPoint());
|
||||
|
||||
// TODO
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private String mangleType(final DataType t) throws Exception {
|
||||
/* Mangle a data type in a function name */
|
||||
return switch(t) {
|
||||
case Enum e -> "W4" + e.getName() + "@@";
|
||||
case IntegerDataType x -> "H";
|
||||
case VoidDataType x -> "X";
|
||||
default -> throw new Exception(
|
||||
"Unhandled data type \"" + t.toString() + "\""
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private String mangleArgs(final DataType[] args) throws Exception {
|
||||
/* Mangle the arguments for a function */
|
||||
if (args.length == 0) return "X";
|
||||
else {
|
||||
String encoded = "";
|
||||
for (int i = 0; i < args.length; i++)
|
||||
encoded += mangleType(args[i]);
|
||||
return encoded + "@";
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue