Files
maple/maple-py/re/scripts/DecRow.java
T

80 lines
3.7 KiB
Java

// Decode the track-row builder: the function that maps a djmdContent record into
// the on-disk DeviceSQL row (offset 0x02 index_shift, 0x14 u4 hash, 0x18/0x1a u2).
// Decompiles FUN_141c04be0 (AnalysisDataPath/SearchStr/MasterContentID mapper) and
// FUN_141ae4860 (djmdContent), plus scans for code referencing the constant
// 0x21b4a7ab / 0xa7ab and for `<<5` row-index assignment.
// Output -> ~/ghidra_proj/decrow.txt
import java.io.PrintWriter;
import java.util.*;
import ghidra.app.script.GhidraScript;
import ghidra.app.decompiler.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.lang.OperandType;
public class DecRow extends GhidraScript {
PrintWriter out;
DecompInterface di;
Set<String> done = new HashSet<>();
FunctionManager fm;
void dec(String a, String why) {
Function f = fm.getFunctionContaining(currentProgram.getAddressFactory().getAddress(a));
if (f == null) { out.println("// no function at " + a + " (" + why + ")"); return; }
if (!done.add(f.getEntryPoint().toString())) return;
out.println("\n//===== " + f.getName() + " @ " + f.getEntryPoint() + " [" + why + "] =====");
DecompileResults r = di.decompileFunction(f, 90, monitor);
out.println(r != null && r.decompileCompleted() ? r.getDecompiledFunction().getC() : "// decompile failed");
}
@Override public void run() throws Exception {
out = new PrintWriter("/home/ntr/ghidra_proj/decrow.txt");
di = new DecompInterface(); di.openProgram(currentProgram);
fm = currentProgram.getFunctionManager();
dec("0x141c04be0", "AnalysisDataPath/SearchStr/MasterContentID mapper");
dec("0x141c07230", "SearchStr 2");
dec("0x141c076d0", "SearchStr 3");
dec("0x141ae4860", "djmdContent xrefs");
// Scan all instructions for the per-export constants used in 0x18/0x1a
// (0xa7ab=42923, 0x21b4=8628, combined u4 0x21b4a7ab=565353387) and for
// an immediate 0x20 / shift-by-5 pattern that would build index_shift.
long[] consts = {0xa7abL, 0x21b4L, 0x21b4a7abL, 0xa7ab21b4L};
Set<String> hitFns = new LinkedHashSet<>();
Listing lst = currentProgram.getListing();
InstructionIterator it = lst.getInstructions(true);
int scanned = 0;
while (it.hasNext() && !monitor.isCancelled()) {
Instruction ins = it.next();
scanned++;
for (int op = 0; op < ins.getNumOperands(); op++) {
Object[] objs = ins.getOpObjects(op);
for (Object o : objs) {
if (o instanceof Scalar) {
long v = ((Scalar) o).getUnsignedValue();
for (long c : consts) {
if (v == c) {
Function f = fm.getFunctionContaining(ins.getAddress());
String tag = "const 0x" + Long.toHexString(c) + " @" + ins.getAddress()
+ " in " + (f != null ? f.getName() + "@" + f.getEntryPoint() : "?")
+ " : " + ins.toString();
out.println("// SCAN " + tag);
if (f != null) hitFns.add(f.getEntryPoint().toString() + "|const0x" + Long.toHexString(c));
}
}
}
}
}
}
out.println("// scanned " + scanned + " instructions");
for (String h : hitFns) {
String[] parts = h.split("\\|");
dec("0x" + parts[0], parts[1]);
}
out.flush(); out.close();
println("wrote decrow.txt");
}
}