#!/usr/bin/env python3 """Read-only probe v3: discriminate "kits never ingested" from "ingested then freed". Staff was refetched by the client at 18:40:38, four minutes before the scan, and players are resident. If staff/badge/stadium records are resident but the two kits are not, the kits are being dropped specifically. """ import re import struct import subprocess import sys NEEDLES = { "PLAYER resourceId 83906881 (control, resident)": 83906881, "STAFF resourceId 9000081 (headcoach-ish)": 9000081, "STAFF resourceId 3000083 (x2)": 3000083, "STAFF resourceId 1000509": 1000509, "STAFF instance 100004870": 100004870, "BADGE resourceId 6000005": 6000005, "BADGE instance 100004875": 100004875, "STADIUM resourceId 6200000": 6200000, "STADIUM instance 100004876": 100004876, "KIT resourceId 6300006 (home)": 6300006, "KIT resourceId 6400003 (away)": 6400003, "KIT instance 100004874 (home)": 100004874, "KIT instance 100004873 (away)": 100004873, "KIT cardassetid 35": 35, } def find_pid(): out = subprocess.run(["pgrep", "-f", "FIFA17.exe"], capture_output=True, text=True).stdout.split() for p in out: try: with open(f"/proc/{p}/maps") as fh: if "CardsDLL" in fh.read(): return int(p) except OSError: continue return int(out[0]) if out else None def main(): pid = find_pid() if not pid: sys.exit("FIFA17.exe not running") print(f"pid={pid}") regs = [] with open(f"/proc/{pid}/maps") as fh: for line in fh: m = re.match(r"([0-9a-f]+)-([0-9a-f]+) (\S{4}) \S+ \S+ \S+\s*(.*)", line) if not m: continue lo, hi, perms, path = int(m.group(1), 16), int(m.group(2), 16), m.group(3), m.group(4) if "r" in perms and not path.startswith("/dev/") and (hi - lo) <= (512 << 20): regs.append((lo, hi)) hits = {k: [] for k in NEEDLES} pats = {k: struct.pack("