"""BATCH 9. The cast helper is vtable slot +0x18 (FUN_180009c80 calls (*(*svc))[0x18] with the interface GUID). So vtable_base = cast_stub_slot_addr - 0x18. - 0x10c80b96 class: stub ptr at 0x180215b28 -> base 0x180215b10 -> slot +0x40 must be FUN_1800e2a40 if the FUN_18003e370 link is real. (CONTROL for the arithmetic.) - 0xed84b12 class: stub ptr at 0x18021c2b8 -> base 0x18021c2a0 -> slot +0x270 is the other gate on TO_TRADE_PILE. """ import traceback OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/cards/adv2/q9_raw.txt" try: f = open(OUT, "w") def P(*a): f.write(" ".join(str(x) for x in a) + "\n") for nm, base, slots in (("iface 0x10c80b96 (CONTROL)", 0x180215B10, (0x18, 0x40)), ("iface 0xed84b12", 0x18021C2A0, (0x18, 0x270, 0x290, 0x2b0, 0x308, 0x148))): P("### %s vtable base %#x" % (nm, base)) for s in slots: v = qword(base + s) fn = fm.getFunctionAt(addr(v)) P(" +%#05x -> %#x %s" % (s, v, fn.getName() if fn else "")) P() for a in (0x1801B1CE0,): pass v = qword(0x18021C2A0 + 0x270) P("=== slot 0x270 body ===") P(dec(v, timeout=300)) P("=== xrefs to it ===") for frm, t, cf, e in xrefs_to(v): P(" %#x %s in %s@%#x" % (frm, t, cf, e)) f.close(); print("WROTE", OUT) except Exception: traceback.print_exc()