mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 02:07:02 +03:00
Compare commits
2 commits
d435282a8b
...
fd6815ae42
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd6815ae42 | ||
|
|
92179ea9bd |
4 changed files with 1394 additions and 1272 deletions
|
|
@ -70,14 +70,14 @@ public class EnhancedExport extends GhidraScript{
|
|||
(f.isInline() ? "inline" : "notinline") + "\t" +
|
||||
Optional.ofNullable(f.getCallFixup())
|
||||
.orElse("nofixup") + "\t" +
|
||||
f.getName(true) +
|
||||
f.getName(true) + "\t" +
|
||||
String.join(
|
||||
"\t",
|
||||
Arrays.stream(f.getSignature(true)
|
||||
.getArguments())
|
||||
.map(arg ->
|
||||
"\t" + arg.getDataType().getDisplayName() +
|
||||
"\t" + arg.getName()
|
||||
arg.getDataType().getDisplayName() + "\t" +
|
||||
arg.getName()
|
||||
).toArray(String[]::new)
|
||||
) +
|
||||
(f.hasVarArgs() ? "\t..." : "") + "\n"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,12 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.data.ArrayDataType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.Undefined4DataType;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.program.model.listing.ParameterImpl;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
|
|
@ -50,23 +54,26 @@ public class EnhancedImport extends GhidraScript{
|
|||
final Address addr,
|
||||
final String[] parts
|
||||
) throws Exception {
|
||||
final String name = unqualified(parts[3]);
|
||||
|
||||
print("Importing data symbol \"" + parts[3] + "\"...");
|
||||
|
||||
// Create symbol
|
||||
final Namespace ns = importNamespace(parts[3]);
|
||||
final Symbol s = Optional.ofNullable(getSymbolAt(addr))
|
||||
.orElse(createLabel(addr, name, ns, true, SourceType.USER_DEFINED));
|
||||
.orElse(createLabel(
|
||||
addr,
|
||||
unqualified(parts[3]),
|
||||
ns,
|
||||
true,
|
||||
SourceType.USER_DEFINED
|
||||
));
|
||||
|
||||
// Create data
|
||||
final Optional<DataType> t_maybe = makeType(parts[2]);
|
||||
if (t_maybe.orElse(null) instanceof DataType t) {
|
||||
if (makeType(parts[2]).orElse(null) instanceof DataType t) {
|
||||
clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1));
|
||||
currentProgram.getListing().createData(addr, t);
|
||||
|
||||
println(" done.");
|
||||
} else println(", skipping.");
|
||||
} else println(" skipping.");
|
||||
}
|
||||
|
||||
private static String unqualified(final String qualifiedName) {
|
||||
|
|
@ -98,7 +105,7 @@ public class EnhancedImport extends GhidraScript{
|
|||
.getService(DataTypeQueryService.class)
|
||||
.findDataTypes(baseName, null);
|
||||
if (foundTypes.size() == 0) {
|
||||
print(" can't find data type \"" + baseName + "\"");
|
||||
print(" can't find data type \"" + baseName + "\",");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +160,38 @@ public class EnhancedImport extends GhidraScript{
|
|||
final Address addr,
|
||||
final String[] parts
|
||||
) throws Exception {
|
||||
println("TODO: function \"" + parts[6] + "\"");
|
||||
print("Importing function symbol \"" + parts[6] + "\"...");
|
||||
|
||||
final Function f = Optional.ofNullable(getFunctionAt(addr))
|
||||
.orElse(createFunction(addr, parts[6]));
|
||||
|
||||
if (makeType(parts[2]).orElse(null) instanceof DataType t)
|
||||
f.setReturnType(t, SourceType.USER_DEFINED);
|
||||
f.setInline(parts[4].equals("inline"));
|
||||
f.setCallFixup(parts[5].equals("nofixup") ? null : parts[5]);
|
||||
f.setName(unqualified(parts[6]), SourceType.USER_DEFINED);
|
||||
if (importNamespace(parts[6]) instanceof Namespace ns)
|
||||
f.setParentNamespace(ns);
|
||||
|
||||
final ArrayList<Parameter> args = new ArrayList<>();
|
||||
for (int i = 7; i < parts.length - 1; i += 2)
|
||||
args.add(new ParameterImpl(
|
||||
parts[i+1],
|
||||
makeType(parts[i]).orElse(Undefined4DataType.dataType),
|
||||
currentProgram
|
||||
));
|
||||
|
||||
f.updateFunction(
|
||||
parts[3],
|
||||
null,
|
||||
args,
|
||||
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS,
|
||||
true,
|
||||
SourceType.USER_DEFINED
|
||||
);
|
||||
|
||||
f.setVarArgs(parts[parts.length - 1].equals("..."));
|
||||
|
||||
println(" done.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
// appear in objdiff, replacing spaces with underscores, e.g. "operator_new"
|
||||
// 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
|
||||
// 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
|
||||
|
|
@ -135,21 +138,56 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
/* Generate a mangled name for a function */
|
||||
final String nameRaw = f.getName(true);
|
||||
|
||||
// Internal symbols like intrinsics aren't mangled
|
||||
if (nameRaw.startsWith("_")) return nameRaw;
|
||||
// main() and extern "C" symbols get C name mangling
|
||||
// (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
|
||||
switch (nameRaw) {
|
||||
case "atexit": return "_atexit";
|
||||
case "main" : return "_main" ;
|
||||
default : {}
|
||||
}
|
||||
private static String mangleCFn(final Function f) throws Exception {
|
||||
/* Produce a C function mangled name
|
||||
(MSVC does indeed do this despite the folk wisdom that only C++ gets
|
||||
name mangling; it is certainly simpler than the C++ sort, at least)
|
||||
*/
|
||||
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 List<String> nameParts = Arrays.asList(nameRaw.split("::"));
|
||||
Collections.reverse(nameParts);
|
||||
final boolean isMethod = f.getCallingConventionName().equals("__thiscall") &&
|
||||
final boolean isMethod = f.getCallingConventionName()
|
||||
.equals("__thiscall") &&
|
||||
nameParts.size() >= 2;
|
||||
final String name = mangleIdentifier(nameRaw, isMethod, f.getReturnType(), dict);
|
||||
|
||||
|
|
@ -500,6 +538,11 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
);
|
||||
|
||||
// Other data
|
||||
if (name.startsWith("extern_\"C\"::")) {
|
||||
final String[] nameParts = name.split("::");
|
||||
return "_" + nameParts[nameParts.length - 1];
|
||||
}
|
||||
|
||||
final ArrayList<String> dict = new ArrayList<>();
|
||||
final String ident = mangleIdentifier(name, false, null, dict);
|
||||
|
||||
|
|
|
|||
2544
ghidra/symboltable.tsv
Normal file → Executable file
2544
ghidra/symboltable.tsv
Normal file → Executable file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue