"""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()
