"""DIMENSION 5 pass 5: (a) the CreateUser response object's own handler, which is what consumes starterPack/bonusPacks; (b) the other writer of model+0x20950; (c) the two 0x273d event handlers; (d) callers of FUN_180017390 (the second caller of the count setter). Correction carried into this pass: pass 4's "model=False" filter was TOO NARROW. The userInfo deser reaches the model through the raw singleton FUN_18011a830, but UI code reaches the SAME object through the ref-counted service locator FUN_180009c80(&out, FUN_1800d7170()). Both then call slots 0x160 / 0x4d8 / 0x4e0 / 0x530 on it, so the locator form is the same class. Do not read pass 4's False column as "not the model". CONTROL for the response-vtable walk: slot +0x08 of the resolved vtable must be the known deserializer 0x18014cc60. If it is not, the vtable is the wrong one and every other slot read from it is meaningless. """ import traceback, os OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store" try: print("### FUN_18014c810 (CreateUser response ctor)") src = dec(0x18014c810, 300) print(src) open(os.path.join(OUT, "dec_ctor_18014c810.c"), "w").write(src) # find the vtable it installs: any .rdata address referenced whose +8 is 0x18014cc60 print("\n### hunting the response vtable (control: slot +0x08 == 0x18014cc60)") hits = find_all((0x18014cc60).to_bytes(8, "little"), blocks=(".rdata", ".data")) for h in hits: vt = h - 8 print(" candidate vtable %#x (slot+8 = deser)" % vt) for i in range(0, 0x60, 8): t = qword(vt + i) fn = fm.getFunctionAt(addr(t)) if 0x180000000 <= t < 0x181000000 else None print(" +%#04x -> %#x %s" % (i, t, fn.getName() if fn else "")) for frm, typ, fn, ent in xrefs_to(vt): print(" vtable xref from %#x in %s @ %#x" % (frm, fn, ent)) print("\n### callers of FUN_180017390 (second caller of the 0x4e0 count setter)") for frm, typ, fn, ent in xrefs_to(0x180017390): print(" from %#x (%s) in %s @ %#x" % (frm, typ, fn, ent)) print("\n### FUN_180199cc0 (raises 0x273d)") s = dec(0x180199cc0, 300) print(s) open(os.path.join(OUT, "dec_fn_180199cc0.c"), "w").write(s) for a, nm in ((0x18010cdc0, "writer2_18010cdc0"), (0x18007e7f0, "evt_18007e7f0"), (0x1800b3900, "evt_1800b3900")): s = dec(a, 300) open(os.path.join(OUT, "dec_%s.c" % nm), "w").write(s) print("\n### %s len=%d -> file" % (nm, len(s))) except Exception: traceback.print_exc()