"""DIMENSION 5 / unopenedPacks -- pass 1: dump the four deserializers end to end. HYPOTHESIS: (a) FutCreateUser deser 0x18014cc60 has arms for starterPack(0x2e5) and bonusPacks(0x5d) that call dedicated sub-deserializers; (b) userInfo 0x18013ec10 has an arm for unopenedPacks(0x35e) that calls a sub-deser and then a singleton vtbl slot; (c) pack element 0x18013af30 has an arm for packContentInfo(0x20c) calling a sub-deser that holds unopened(0x35d). CONTROL: 0x18013c6d0 (settings deser) is a deserializer of the SAME family with a KNOWN answer -- exactly one key `configs`(0xa2). If the dump/parse pipeline is sound, the settings dump must show 0xa2 and nothing else in its key ladder. Same syntactic form family (ladder), so it controls the extraction, not just the decompile. NO ABSENCE CLAIMS FROM THIS PASS: it only dumps. Full text goes to disk, lengths are printed so truncation is visible. """ import traceback, os OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/store" try: os.makedirs(OUT, exist_ok=True) targets = { "createuser_18014cc60": 0x18014cc60, "userinfo_18013ec10": 0x18013ec10, "packelem_18013af30": 0x18013af30, "settings_18013c6d0": 0x18013c6d0, # CONTROL } for name, a in targets.items(): src = dec(a, 300) p = os.path.join(OUT, "dec_%s.c" % name) with open(p, "w") as f: f.write(src) f2 = func(a) print("== %s @ %#x fn=%s body=%#x-%#x declen=%d" % ( name, a, f2.getName() if f2 else "?", int(f2.getEntryPoint().getOffset()) if f2 else 0, int(f2.getBody().getMaxAddress().getOffset()) if f2 else 0, len(src))) print(" written %s" % p) # Raw instruction-level immediate enumeration for each target, so the ladder / # switch / sub-dec forms are all visible regardless of how Ghidra renders them. for name, a in targets.items(): f2 = func(a) if f2 is None: print("!! no function at %#x" % a) continue lines = [] it = listing.getInstructions(f2.getBody(), True) while it.hasNext(): ins = it.next() lines.append("%#x %s" % (int(ins.getAddress().getOffset()), str(ins))) p = os.path.join(OUT, "asm_%s.txt" % name) with open(p, "w") as fh: fh.write("\n".join(lines)) print("== asm %s: %d instructions -> %s" % (name, len(lines), p)) except Exception: traceback.print_exc()