"""Q2: two string clusters that look like family-name tables. Q1 found 'badge' 0x18022a220, 'kit' 0x18022a228, 'leagueLogo' 0x18022a230, 'ball' 0x18022a278 packed together, and a second cluster 'badge' 0x1802303c8, 'ball' 0x1802303dc, 'equippables' 0x180230f48, 'leagueLogo' 0x180231608. HYPOTHESIS: cluster 1 is the value list of a {name -> code} enum table like the itemState one (stride 0x10: char* then int). Cluster 2 is the club?type= route vocabulary. CONTROL: the itemState table itself. My Q1 read started mid-table (row0 = activeBadge with code 0x64, while the doc's list starts at WAITING_FOR_GAME), so this query re-walks BACKWARDS from 0x180229d20 to find the real table start and prints it in full. If the ten documented names do not appear in order, my table walker is wrong. Then: for every string in each cluster, find the .rdata qword that points at it (the table row) and print the row's neighbours, plus xrefs. """ import traceback def dump_strings(lo, hi, label): print("=== strings %s %#x..%#x ===" % (label, lo, hi)) p = lo while p < hi: try: b = mem.getByte(addr(p)) & 0xFF except Exception: p += 1 continue if 0x20 <= b < 0x7F: s = rd_str(p, 96) if len(s) >= 2: print(" %#x %r" % (p, s)) p += max(1, len(s)) + 1 else: p += 1 def walk_table(start, n, back=0): print("--- table walk from %#x, %d rows (stride 0x10) ---" % (start, n)) for i in range(-back, n): e = start + i * 0x10 try: q0, q1 = qword(e), qword(e + 8) except Exception: continue s = "" if 0x180000000 <= q0 < 0x181000000: try: s = rd_str(q0, 64) except Exception: s = "?" print(" [%3d] %#x ptr=%#x %-26r val=%#x" % (i, e, q0, s, q1)) try: walk_table(0x180229D20, 8, back=14) print() dump_strings(0x18022A200, 0x18022A380, "cluster1") print() dump_strings(0x180230300, 0x180230420, "cluster2a") print() dump_strings(0x180230F00, 0x180230FA0, "cluster2b") print() dump_strings(0x180231380, 0x180231680, "cluster2c") print() print("=== xrefs / pointer-rows for cluster strings ===") for name, a in [("badge", 0x18022A220), ("kit", 0x18022A228), ("leagueLogo", 0x18022A230), ("ball", 0x18022A278), ("badge2", 0x1802303C8), ("ball2", 0x1802303DC), ("equippables", 0x180230F48), ("leagueLogo2", 0x180231608), ("itemState", 0x180231490)]: print(" %s @%#x" % (name, a)) for frm, typ, fn, ent in xrefs_to(a): print(" xref from %#x %s in %s(%#x)" % (frm, typ, fn, ent)) ptrs = find_all(a.to_bytes(8, "little"), blocks=(".rdata", ".data")) for pa in ptrs[:8]: print(" ptr-row @%#x next-q=%#x prev-q=%#x" % (pa, qword(pa + 8), qword(pa - 8))) for frm, typ, fn, ent in xrefs_to(pa): print(" row xref %#x %s in %s(%#x)" % (frm, typ, fn, ent)) except Exception: traceback.print_exc()