39 lines
1.8 KiB
Java
39 lines
1.8 KiB
Java
// Map virtual methods to classes via RTTI-labelled vftables.
|
|
// Usage (postScript): VTableMap.java <outFile.tsv>
|
|
// Writes: class, vftable_address, slot, function_address, function_name
|
|
import ghidra.app.script.GhidraScript;
|
|
import ghidra.program.model.address.*;
|
|
import ghidra.program.model.listing.*;
|
|
import ghidra.program.model.symbol.*;
|
|
import java.io.*;
|
|
import java.nio.file.*;
|
|
|
|
public class VTableMap extends GhidraScript {
|
|
@Override
|
|
public void run() throws Exception {
|
|
Path out = Paths.get(getScriptArgs()[0]);
|
|
int ptr = currentProgram.getDefaultPointerSize();
|
|
Listing listing = currentProgram.getListing();
|
|
SymbolTable st = currentProgram.getSymbolTable();
|
|
try (PrintWriter w = new PrintWriter(Files.newBufferedWriter(out))) {
|
|
w.println("class\tvftable\tslot\tfunction\tname");
|
|
for (Symbol s : st.getSymbols("vftable")) {
|
|
String cls = s.getParentNamespace().getName(true);
|
|
Address a = s.getAddress();
|
|
for (int slot = 0; slot < 512; slot++) {
|
|
Address p = a.add((long) slot * ptr);
|
|
if (slot > 0 && st.getPrimarySymbol(p) != null
|
|
&& st.getPrimarySymbol(p).getSource() != SourceType.DEFAULT) break; // next labelled object
|
|
long v = currentProgram.getMemory().getLong(p);
|
|
Address t;
|
|
try { t = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(v); }
|
|
catch (Exception e) { break; }
|
|
Function f = getFunctionAt(t);
|
|
if (f == null) break;
|
|
w.println(cls + "\t0x" + a + "\t" + slot + "\t0x" + t + "\t" + f.getName(true));
|
|
}
|
|
}
|
|
}
|
|
println("vtable map written");
|
|
}
|
|
}
|