52 lines
2.8 KiB
Java
52 lines
2.8 KiB
Java
// Find the DeviceSQL row-index code that computes index_shift = slot << 5.
|
|
// Heuristic: functions that contain BOTH a left-shift-by-5 (SHL r,5 / LEA r,[r*0x20])
|
|
// AND reference the row-index masks (0x1fff / 0x7ff) or stride 0x24, AND a u2 store.
|
|
// Output -> ~/ghidra_proj/findshift.txt
|
|
import java.io.PrintWriter;
|
|
import java.util.*;
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.listing.*;
|
|
import ghidra.program.model.scalar.Scalar;
|
|
|
|
public class FindShift extends GhidraScript {
|
|
@Override public void run() throws Exception {
|
|
PrintWriter out = new PrintWriter("/home/ntr/ghidra_proj/findshift.txt");
|
|
FunctionManager fm = currentProgram.getFunctionManager();
|
|
Listing lst = currentProgram.getListing();
|
|
// accumulate per-function evidence
|
|
Map<String,Set<String>> ev = new HashMap<>();
|
|
InstructionIterator it = lst.getInstructions(true);
|
|
while (it.hasNext() && !monitor.isCancelled()) {
|
|
Instruction ins = it.next();
|
|
Function f = fm.getFunctionContaining(ins.getAddress());
|
|
if (f == null) continue;
|
|
String key = f.getEntryPoint().toString();
|
|
String mn = ins.getMnemonicString();
|
|
String txt = ins.toString();
|
|
boolean shl5 = (mn.equalsIgnoreCase("SHL") && txt.endsWith(",0x5"))
|
|
|| (mn.equalsIgnoreCase("LEA") && txt.contains("*0x20"));
|
|
if (shl5) ev.computeIfAbsent(key,k->new HashSet<>()).add("shl5@"+ins.getAddress());
|
|
for (int op=0; op<ins.getNumOperands(); op++)
|
|
for (Object o : ins.getOpObjects(op))
|
|
if (o instanceof Scalar) {
|
|
long v = ((Scalar)o).getUnsignedValue();
|
|
if (v==0x1fff) ev.computeIfAbsent(key,k->new HashSet<>()).add("mask1fff@"+ins.getAddress());
|
|
if (v==0x7ff) ev.computeIfAbsent(key,k->new HashSet<>()).add("mask7ff@"+ins.getAddress());
|
|
if (v==0x24) ev.computeIfAbsent(key,k->new HashSet<>()).add("stride24@"+ins.getAddress());
|
|
}
|
|
}
|
|
// report functions that have shl5 AND (mask or stride)
|
|
for (Map.Entry<String,Set<String>> e : ev.entrySet()) {
|
|
Set<String> tags = e.getValue();
|
|
boolean hasShl = tags.stream().anyMatch(t->t.startsWith("shl5"));
|
|
boolean hasCtx = tags.stream().anyMatch(t->t.startsWith("mask1fff")||t.startsWith("mask7ff")||t.startsWith("stride24"));
|
|
if (hasShl && hasCtx) {
|
|
Function f = fm.getFunctionContaining(currentProgram.getAddressFactory().getAddress(e.getKey()));
|
|
out.println("CANDIDATE " + (f!=null?f.getName():"?") + " @" + e.getKey() + " : " + tags);
|
|
}
|
|
}
|
|
out.flush(); out.close();
|
|
println("wrote findshift.txt");
|
|
}
|
|
}
|