#!/usr/bin/env python3 """Did clubPlayers actually land in the client, or was it eaten as the envelope key? Read-only. The argument cannot settle this; the client's own memory can. Chain, from the comment at utas_server.py:1076 (established earlier by two independent agents and two reviewers, so this probe TESTS that chain rather than assuming it): R = + 0x1fd70 (FUN_18011a810 is `lea rax,[rcx+0x1fd70]; ret`) clubPlayers -> R + 0x3c auctionCount -> R + 0x38 The server logged "HUB: clubPlayers=205 auctionCount=0" for this session. PREDICTIONS, stated before reading so this cannot be rationalised after the fact: * if R+0x3c reads 205, clubPlayers reached its arm. The flat two-key hub body is fine and the envelope worry does not apply to this root. * if R+0x3c reads 0 while R+0x38 reads 0 too, the result is ambiguous, because auctionCount is legitimately 0 this session. Say so rather than claiming a result. * if R+0x3c reads 0 and some other plausible field is populated, clubPlayers was eaten as the first key/value pair and the MY CLUB tile is showing a wrong number. """ import os import struct pid = None for d in os.listdir('/proc'): if d.isdigit(): try: if open('/proc/%s/comm' % d).read().strip() == 'FIFA17.exe': pid = int(d) break except Exception: pass if not pid: raise SystemExit("FIFA17.exe not running") base = None for ln in open('/proc/%d/maps' % pid): if 'CardsDLL' in ln: base = int(ln.split('-')[0], 16) if not base: raise SystemExit("CardsDLL not mapped: the client has not reached Ultimate Team") slide = base - 0x180000000 print("pid %d cardsdll %#x slide %#x" % (pid, base, slide)) fd = os.open('/proc/%d/mem' % pid, os.O_RDONLY) def rd(va, n): return os.pread(fd, n, va) # Prove the slide before trusting any address derived from it. pe = open('/mnt/games/FIFA 17/CardsDLL_Win64_retail.dll', 'rb').read() off = 0x180180D00 - 0x180000000 - 0x1000 + 0x400 ok = pe[off:off + 32] == rd(0x180180D00 + slide, 32) print("slide control (FNV prologue): %s" % ("MATCH" if ok else "MISMATCH -- STOP")) if not ok: raise SystemExit(1) model = struct.unpack('