"""DIMENSION 5 pass 2: the pieces the CreateUser / unopenedPacks answers depend on. HYPOTHESES H1 FUN_18011a830 returns the model singleton (DAT_1802e6398 or similar), so its vtable can be resolved LIVE and slot 0x4e0 identified. H2 FUN_180142470 (the userData 0x36d arm of CreateUser) takes only the reader, so it parses into a global, not into the response record. H3 FUN_180141ee0 is the shared "read FIELD_NAME -> atom, advance to value" helper; return 6 means "no value / null" and suppresses dispatch. H4 The primitive getters 0x1801c7620 (BOOL) / 0x1801c79d0 (INT) / 0x180135ff0 (SKIP) determine whether a container fed to a scalar arm desyncs the reader. CONTROL for the vtable slot question: slot 0x480 is used by the squadList(0x2d4) arm of the SAME deserializer and is LIVE-CONFIRMED WORKING (MY SQUADS renders). Whatever method resolves 0x4e0 must also resolve 0x480 to something sane; if it cannot resolve 0x480 the method is broken, not the target. CONTROL for the stack-struct offset rule (record_off = 0x268 - N in FUN_18013af30): displayGroupAssetId(0xda)->local_238 must give 0x30 and displayGroupUseDefaultImage(0xdb)->local_230 must give 0x38, which is what an earlier independent pass recorded for those two fields. Both are printed below from the asm. """ import traceback, os OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store" try: for name, a in [ ("singleton_18011a830", 0x18011a830), ("userdata_180142470", 0x180142470), ("keyhelper_180141ee0", 0x180141ee0), ("bool_1801c7620", 0x1801c7620), ("int_1801c79d0", 0x1801c79d0), ("skip_180135ff0", 0x180135ff0), ("item_18013fe00", 0x18013fe00), ("storeroot_1801234e0", 0x1801234e0), ]: src = dec(a, 300) p = os.path.join(OUT, "dec_%s.c" % name) open(p, "w").write(src) print("== %s @ %#x declen=%d -> %s" % (name, a, len(src), p)) print("\n---- singleton getter, short ones printed inline ----") for a in (0x18011a830, 0x180141ee0, 0x1801c7620): s = dec(a, 300) if len(s) < 2600: print("\n### %#x (len=%d)\n%s" % (a, len(s), s)) else: print("\n### %#x len=%d (see file)" % (a, len(s))) # ---- CONTROL: stack offsets in FUN_18013af30 from the raw asm ---------- print("\n---- FUN_18013af30 stack-displacement control ----") f = func(0x18013af30) it = listing.getInstructions(f.getBody(), True) want = {} while it.hasNext(): ins = it.next() t = str(ins) for d in ("0xcd", "0xb4", "0x30", "0x38", "0xce", "0xcc"): pass want.setdefault("all", []).append((int(ins.getAddress().getOffset()), t)) # print the instructions immediately around each of the four atom arms for label, site in (("0x35d unopened", 0x18013b7b0), ("0xda dGAssetId", 0x0), ("0xdb dGUseDefImg", 0x0)): pass # simpler: dump every instruction that writes a byte to a stack slot for addr_i, t in want["all"]: if ("MOV byte ptr [RSP" in t or "MOV byte ptr [RBP" in t or "MOV dword ptr [RSP" in t): print(" %#x %s" % (addr_i, t)) except Exception: traceback.print_exc()