mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 10:17:03 +03:00
Compare commits
3 commits
e9b0c3c6bc
...
0e84f9ab1f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e84f9ab1f | ||
|
|
53b0e82417 | ||
|
|
55046bf009 |
2 changed files with 55 additions and 20 deletions
|
|
@ -65,8 +65,11 @@ delink() {
|
|||
export MSYS_NO_PATHCONV=1
|
||||
|
||||
"$1/support/analyzeHeadless$suffix" "$2" "$3"\
|
||||
-readOnly\
|
||||
-process default.xbe\
|
||||
-noanalysis\
|
||||
-scriptPath ghidra_scripts\
|
||||
-preScript MSVC7Mangle.java $4\
|
||||
-postScript DelinkProgram.java\
|
||||
/exporter 'COFF relocatable object'\
|
||||
$(printf "/include-range %s " $4)\
|
||||
|
|
|
|||
|
|
@ -7,17 +7,20 @@
|
|||
// permissive form (public, non-const, etc.).
|
||||
//
|
||||
// Special symbol names like "operator new" or "scalar deleting destructor"
|
||||
// are given unique mangling. To properly demangle these, name them as they
|
||||
// are given unique mangling. To properly mangle these, name them as they
|
||||
// appear in objdiff, replacing spaces with underscores, e.g. "operator_new"
|
||||
// and "`scalar_deleting_destructor'" (notice the ` and ').
|
||||
//
|
||||
// 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
|
||||
// correct if the mangling is done in preparation for exporting functions).
|
||||
//
|
||||
// @category Symbol
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionSignature;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.data.Array;
|
||||
import ghidra.program.model.data.BooleanDataType;
|
||||
import ghidra.program.model.data.CharDataType;
|
||||
|
|
@ -38,6 +41,7 @@ import ghidra.program.model.data.StringDataInstance;
|
|||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.data.TerminatedUnicodeDataType;
|
||||
import ghidra.program.model.data.TypeDef;
|
||||
import ghidra.program.model.data.Undefined;
|
||||
import ghidra.program.model.data.Union;
|
||||
import ghidra.program.model.data.UnsignedCharDataType;
|
||||
import ghidra.program.model.data.UnsignedIntegerDataType;
|
||||
|
|
@ -46,6 +50,9 @@ import ghidra.program.model.data.UnsignedLongLongDataType;
|
|||
import ghidra.program.model.data.UnsignedShortDataType;
|
||||
import ghidra.program.model.data.VoidDataType;
|
||||
import ghidra.program.model.data.WideCharDataType;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionSignature;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
|
|
@ -65,6 +72,22 @@ import java.util.zip.CRC32;
|
|||
public class MSVC7Mangle extends GhidraScript{
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
// Get selected ranges from arguments if invoked headless
|
||||
if (isRunningHeadless()) {
|
||||
final String[] args = getScriptArgs();
|
||||
final AddressSet addr = new AddressSet();
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
final String[] range = args[i].split("-");
|
||||
addr.add(
|
||||
currentAddress.getAddress(range[0]),
|
||||
currentAddress.getAddress(range[1])
|
||||
);
|
||||
}
|
||||
|
||||
setCurrentSelection(addr);
|
||||
}
|
||||
|
||||
final SymbolIterator iter = currentProgram.getSymbolTable()
|
||||
.getPrimarySymbolIterator(currentSelection, true);
|
||||
|
||||
|
|
@ -86,6 +109,9 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
s.setName(mangled, SourceType.USER_DEFINED);
|
||||
makeGlobal(s);
|
||||
}
|
||||
|
||||
// TODO: in headless mode, also mangle everything
|
||||
// referenced by functions
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,24 +264,29 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
}
|
||||
|
||||
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
|
||||
by checking if they lie in non-executable memory, or from a scalar
|
||||
deleting destructor.
|
||||
/* Determine whether a method is virtual
|
||||
We essentially check whether any references are from a vtable or a
|
||||
scalar deleting destructor.
|
||||
*/
|
||||
final Reference[] refs = getReferencesTo(f.getEntryPoint());
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
final Address addr = refs[i].getFromAddress();
|
||||
final Optional<String> caller = Optional.ofNullable(getFunctionContaining(addr))
|
||||
.map(x -> x.getName(false));
|
||||
final Data data = getDataContaining (refs[i].getFromAddress());
|
||||
final Function func = getFunctionContaining(refs[i].getFromAddress());
|
||||
|
||||
if (
|
||||
!getMemoryBlock(addr).isExecute() ||
|
||||
caller.map(x -> x.equals("`scalar_deleting_destructor'"))
|
||||
.orElse(false) ||
|
||||
caller.map(x -> x.startsWith("??_G")) // From mangled name
|
||||
.orElse(false)
|
||||
) return true;
|
||||
if (data != null) {
|
||||
final String name = getSymbolAt(data.getRoot()
|
||||
.getAddress()).getName(false);
|
||||
if (
|
||||
name.equals("`vftable'") ||
|
||||
name.startsWith("??_7")
|
||||
) 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;
|
||||
|
|
@ -305,7 +336,7 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
*/
|
||||
if (t == null) throw new Exception (
|
||||
"A data type was reported as null. Ensure that all " +
|
||||
"data types in the demangled code/data have been " +
|
||||
"data types in the code/data to mangle have been " +
|
||||
"defined."
|
||||
);
|
||||
|
||||
|
|
@ -336,7 +367,8 @@ public class MSVC7Mangle extends GhidraScript{
|
|||
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\". All data types must be defined.");
|
||||
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() + "\"");
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue