#!/usr/bin/env python3 """Find IMMEDIATE stores of a constant to a struct offset, in a live module. immstore.py [disp_hex|any] [--exe] Only `C7 /0` (mov dword [reg+disp], imm32) can INTRODUCE a constant into a field; `89 /r` merely propagates one. Emits image VAs so they can be fed to ldis.py. Read-only. """ import glob import os import re import struct import sys CARDS_IMG = 0x180000000 EXE_IMG = 0x140000000 def pid(): for d in glob.glob("/proc/[0-9]*"): try: if open(os.path.join(d, "comm")).read().strip() == "FIFA17.exe": return int(os.path.basename(d)) except OSError: pass raise SystemExit("FIFA17.exe not running") P = pid() def module_base(n): for l in open(f"/proc/{P}/maps"): if n.lower() in l.lower(): return int(l.split("-")[0], 16) raise SystemExit(f"{n} not mapped") def text_spans(base): out = [] started = False for l in open(f"/proc/{P}/maps"): m = re.match(r"([0-9a-f]+)-([0-9a-f]+)\s+(\S{4})\s+\S+\s+\S+\s+\S+\s*(.*)", l) 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 lo == base: started = True continue if started: if not path.strip() and "x" in perms: out.append((lo, hi)) elif out: break return out args = [a for a in sys.argv[1:] if a != "--exe"] exe = "--exe" in sys.argv imm = int(args[0], 0) want_disp = None if len(args) < 2 or args[1] == "any" else int(args[1], 16) img = EXE_IMG if exe else CARDS_IMG base = module_base("FIFA17.exe" if exe else "CardsDLL") mem = open(f"/proc/{P}/mem", "rb", 0) immb = struct.pack("= 0: modrm = buf[i + 1] if i + 1 < len(buf) else 0 if (modrm & 0x38) == 0: # /0 mod, rm = modrm >> 6, modrm & 7 if mod == 1 and i + 7 <= len(buf): # disp8 disp, ib = buf[i + 2], i + 3 sz = 7 elif mod == 2 and i + 10 <= len(buf): # disp32 disp, ib = struct.unpack_from("