"""ADVERSARIAL BATCH 3. My batch-2 displacement census turned up FOUR +0x5c sites the other agent's constant-collecting scan did not report, including MOV dword [RDI+0x5c],0x5 and MOV dword [RDI+0x5c],0x6 in FUN_180147070 -- i.e. the client WRITES forSale and offered. Their claim "forSale(5) and offered(6): NEVER TESTED ANYWHERE" and the action "nothing reads them" are under direct attack here. Also under attack: - "no other code path can produce the greyout from wire data": FUN_1800bc580 is a THIRD +0x49 consumer (it counts untradeable squad members). What uses that count? - the FUN_1800e2a40 <-> FUN_18003e370 vtable link the agent flagged as a gap. - the +0x23f playStyle mapper, the 0x226 pile mapper, and the record-offset anchor inside FUN_18013fe00 (printed IN FULL, with len). CONTROL for the vtable hunt: I search for the 8-byte pointer to FUN_1800e2a40 AND, in the same pass, for the pointer to FUN_1801a7260 (which the agent reported has NO 8-byte pointer, only 4-byte .pdata RVAs) and to FUN_18003e370. A hunt that finds all three or none tells me the search itself is sound. """ import traceback, struct OUT = "/tmp/claude-1000/-home-alex-Documents-OpenFUT/8e521ca1-ca3e-4138-bb96-df1744dd1d30/scratchpad/cards/adv2/q3_raw.txt" try: f = open(OUT, "w") def P(*a): f.write(" ".join(str(x) for x in a) + "\n") P("=" * 25, "A. itemState WRITERS/READERS the other scan missed", "=" * 25) for a in (0x180147070, 0x1801A6FC0, 0x1800A47B0, 0x18011DC50, 0x1800D73D0): d = dec(a) P("### %#x len=%d xrefs:" % (a, len(d))) for frm, t, cf, e in xrefs_to(a): P(" %#x %s in %s@%#x" % (frm, t, cf, e)) P(d) P() P("=" * 25, "B. the third +0x49 consumer: who calls FUN_1800bc580", "=" * 25) for frm, t, cf, e in xrefs_to(0x1800BC580): P(" %#x %s in %s@%#x" % (frm, t, cf, e)) P("--- FUN_1801a8890 (the sibling predicate counted into param_2):") P(dec(0x1801A8890)) P("--- FUN_1801a80a0:") P(dec(0x1801A80A0)) P() P("=" * 25, "C. vtable link FUN_1800e2a40 <- FUN_18003e370 slot 0x40", "=" * 25) for nm, a in (("FUN_1800e2a40", 0x1800E2A40), ("FUN_1801a7260", 0x1801A7260), ("FUN_18003e370", 0x18003E370), ("FUN_1800eb850", 0x1800EB850)): pat = struct.pack("" % (i * 8, v)) break fn = fm.getFunctionAt(addr(v)) P(" +%#04x %#x %s%s" % (i * 8, v, fn.getName() if fn else "", " <== TARGET" if v == a else "")) P() P("=" * 25, "D. FUN_18013fe00 FULL", "=" * 25) d = dec(0x18013FE00, timeout=600) P("len(src) =", len(d)) P(d) P() P("=" * 25, "E. mappers", "=" * 25) for nm, a in (("playStyle FUN_180136480", 0x180136480), ("pile FUN_180142650", 0x180142650), ("owners helper FUN_1800d7b50", 0x1800D7B50), ("BOUGHT_FOR mapper FUN_1800d7b30", 0x1800D7B30), ("family FUN_1800d8330", 0x1800D8330)): P("### " + nm) dd = dec(a) P(" len=%d" % len(dd)) P(dd) P() f.close() print("WROTE", OUT) except Exception: traceback.print_exc()