"""D3 store-price q4: name the points gate. H10 The object at DAT_1802de0d0 has vtable PTR_FUN_1801ebaf0; slot +0x30 is the predicate that suppresses the "points" currency branch in FUN_18002c3c0. CONTROL: slot +0x00 and +0x08 must be functions (a real vtable), and the ctor FUN_180012a50 must be the only writer of that vtable pointer. """ import traceback OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store" try: w = open(OUT + "/q4_raw.txt", "w") def p(*a): s = " ".join(str(x) for x in a) print(s); w.write(s + "\n") p("vtable at 0x1801ebaf0 (first 24 slots)") for off, tgt, nm in vtable(0x1801ebaf0, 24): p(" +%#04x -> %#x %s" % (off, tgt, nm)) t = qword(0x1801ebaf0 + 0x30) p("") p("SLOT +0x30 target = %#x" % t) s = dec(t) p("len=%d FULL" % len(s)); p(s) # what else calls it / who else reads the gate the same way p("") p("=" * 60) p("other call sites of vtable+0x30 on this singleton -- decompile two readers") for a in (0x18007e7f0, 0x1800a5650): s = dec(a) p("") p("--- FUN_%x len=%d (first 4000 chars; FULL length stated)" % (a, len(s))) p(s[:4000]) w.close() except Exception: traceback.print_exc() try: w.write(traceback.format_exc()); w.close() except Exception: pass