// Comprehensive decompile of the vehicleSubSystems Make dispatcher, the whole // SubsystemCluster family, and the sub-gauge ctors they build. Also dumps the // per-group geometry table and the relevant vtables. Writes to scratchpad. import ghidra.app.script.GhidraScript; import ghidra.app.decompiler.*; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.mem.*; import ghidra.program.model.symbol.*; import java.io.*; public class DecompVSS extends GhidraScript { public void run() throws Exception { String outPath = "C:\\Users\\epilectrik\\AppData\\Local\\Temp\\claude\\C--git-bt411\\09bf24bb-f92d-423a-b815-1eb662736f58\\scratchpad\\vss_sub.txt"; PrintWriter out = new PrintWriter(new FileWriter(outPath)); FunctionManager fm = currentProgram.getFunctionManager(); Memory mem = currentProgram.getMemory(); DecompInterface dec = new DecompInterface(); dec.openProgram(currentProgram); long[] targets = { // btl4gau2 sub-gauge ctors that must be reconstructed 0x4c70a4L, 0x4c7134L, 0x4c3134L, // CoolingLoop/AnimatedSubsystemLamp + dtor + connection 0x4c7160L, 0x4c71f0L, 0x4c31ecL, // PowerSource/AnimatedSourceLamp + dtor + connection 0x4c721cL, 0x4c72acL, 0x4c733cL, // ScalarBarGauge/GeneratorVoltage + ctor2 + dtor 0x4c6d80L, 0x4c6e54L, 0x4c6ee0L, // ConfigMapGauge + dtor + SetColor 0x4c6f34L, // ConfigMapGauge Execute (guess) // SubsystemCluster helpers 0x4c89c4L, 0x4c8820L, 0x4c8990L, 0x4c8a28L, 0x4c2ec4L, // Weapon/Ballistic extra vtable slots 0x4c92e4L, 0x4c9b24L, 0x4c9b50L, 0x4c8990L, // connections 0x4749deL, 0x474855L, 0x4c3288L, }; for (long t : targets) { Address a = toAddr(t); Function f = fm.getFunctionContaining(a); if (f == null) { try { disassemble(a); f = createFunction(a, "FUN_" + Long.toHexString(t)); } catch (Exception e) { out.println("// could not create fn at " + a + ": " + e); } } out.println("\n//===================================================================="); out.println("// FUN_" + Long.toHexString(t) + (f!=null ? " ("+f.getName()+")" : "")); out.println("//===================================================================="); if (f == null) { out.println("// NO FUNCTION"); continue; } DecompileResults r = dec.decompileFunction(f, 60, monitor); if (r != null && r.decompileCompleted()) out.println(r.getDecompiledFunction().getC()); else out.println("// decompile failed: " + (r!=null?r.getErrorMessage():"null")); } // vtables for the cluster family long[] vts = { 0x51a020L /*SubsystemCluster*/, 0x519fd4L /*HeatSink*/, 0x519f88L /*Myomer*/, 0x519f38L /*Weapon*/, 0x519ee8L /*Energy*/, 0x519e98L /*Ballistic*/ }; out.println("\n//==== cluster vtables ===="); for (long vt : vts) { StringBuilder sb = new StringBuilder(String.format("vt 0x%x: ", vt)); for (int i=0;i<20;i++){ long v = mem.getInt(toAddr(vt+i*4))&0xffffffffL; sb.append(String.format("[%d]=0x%x ",i,v)); } out.println(sb.toString()); } // geometry table out.println("\n//==== geometry table @0x51bf34 (12 groups x 7 dwords) ===="); for (int g=0; g<12; g++) { StringBuilder sb = new StringBuilder("group "+(g+1)+": "); for (int k=0;k<7;k++){ long v = mem.getInt(toAddr(0x51bf34L+(g*7L+k)*4))&0xffffffffL; sb.append(String.format("0x%x ",v)); } out.println(sb.toString()); } out.close(); println("DecompVSS full done -> " + outPath); } }