"""Q5 — fix the atom lookup, then find the CONSUMER of atoms 0x36..0x3c (auctionLost*/auctionSold*/auctionWon*) and read the sold-related string neighbourhoods. """ import struct BASE = 0x1802D2760 TABLE_LO, TABLE_HI = 0x1802D2760, 0x1802D4800 def atom_id(name): """Every string with this exact spelling, then the pointer that lies INSIDE the atom table. Taking the first string match is wrong: common words appear in several unrelated tables.""" out = [] for sa in find_all(name.encode() + b"\x00", blocks=(".rdata", ".data")): for pa in find_all(struct.pack("=3 of the auction-outcome atoms 0x36..0x3c") print("=" * 78) WANT = set(range(0x36, 0x3D)) hits = {} fi = fm.getFunctions(True) n = 0 for f in fi: n += 1 ent = int(f.getEntryPoint().getOffset()) body = f.getBody() seen = set() it = listing.getInstructions(body, True) while it.hasNext(): ins = it.next() m = ins.getMnemonicString() if m not in ("CMP", "SUB", "MOV", "LEA"): continue for i in range(ins.getNumOperands()): for o in ins.getOpObjects(i): try: v = int(o.getValue()) except Exception: continue if v in WANT: seen.add(v) if len(seen) >= 3: hits[ent] = (f.getName(), sorted(hex(v) for v in seen)) print(f" scanned {n} functions") for ent, (nm, vals) in sorted(hits.items()): print(f" 0x{ent:x} {nm:28s} sees {vals}") print() print("=" * 78) print("== string neighbourhoods: SoldFromTradePile / SOLD / sold") print("=" * 78) for label, lo, hi in (("SoldFromTradePile", 0x1801EFA40, 0x1801EFB80), ("SOLD", 0x18020A040, 0x18020A140), ("sold@228bed", 0x180228B60, 0x180228C60)): print(f"-- {label}") a = lo while a < hi: s = rd_str(a, 70) if s and len(s) > 1 and s.isprintable(): print(f" 0x{a:x} {s!r}") a += len(s.encode()) + 1 else: a += 1