#!/usr/bin/env python3 # wall2_resolver7.py - resolver6 + release-window injection + live-first ordering. # Fixes the resolver6 zero-page overwrite: candidates are injected good-first # (live_nz>0) and zero pages last, so the readable mapping wins by order if the # service keeps the newest write. # New: the GR init release windows (0x4b16000 size 0x1000 from the record page, # and any {VA,0x1000} record alongside) are injected from the size-0x1000 # memdescs of the same page. import subprocess, struct, time, sys, os RAM = "/dev/shm/vgpu-guest-ram" PARAM = "/sys/module/vgsp/parameters/sema_map_add" LOG = "/tmp/opencode/wall2_resolver7.log" WATCH_S = int(os.environ.get("W2_WATCH", "420")) PAIRS = [(0x4480000, 0x44a0000), (0x4ca0000, 0x4cc0000)] REL_WINS = [0x4b16000] logf = open(LOG, "a", buffering=1) def log(*a): s = " ".join(str(x) for x in a) print(s, flush=True) logf.write("[%s] %s\n" % (time.strftime("%H:%M:%S"), s)) img = open(RAM, "rb", buffering=0) def off2gpa(off): return off if off < 0x80000000 else 0x100000000+(off-0x80000000) def gpa2off(pa): if pa < 0x80000000: return pa if pa < 0x180000000: return 0x80000000 + (pa - 0x100000000) return None def rd(pa, n): off = gpa2off(pa) if off is None: return None img.seek(off); return img.read(n) def inject(va, pa, ln=0x1000, ap=1): cmd = "echo 0x%x,0x%x,0x%x,%d > %s" % (va, pa, ln, ap, PARAM) r = subprocess.run(["sudo", "sh", "-c", cmd], capture_output=True, text=True) if r.returncode == 0: log("INJECT va=0x%x -> pa=0x%x" % (va, pa)) return True log("inject FAIL rc=%d %s" % (r.returncode, r.stderr.strip())) return False def find_qpair(a, b): img.seek(0, 2); fsz = img.tell() pat = struct.pack("0 first, zeros last) for (pva, _rva) in PAIRS: cands = [(o, sz, pa) for (o, sz, pa) in descs if sz == 0x20000] order = [] for (o, sz, pa) in cands: pd = rd(pa, 0x40) nz = sum(1 for b in pd if b) if pd else -1 log("pair=0x%x page=0x%x desc@0x%x pa=0x%x live_nz=%d" % (pva, page, o, pa, nz)) order.append((nz, o, pa)) order.sort(key=lambda t: t[0]) # zeros first, live last for (nz, o, pa) in order: key = (pva, page, o) if key in injected: continue if inject(pva, pa): injected.add(key) # release windows: any {VA, 0x1000} record on the page -> size-0x1000 descs for (va, sz) in wins: if va not in REL_WINS and not (0x4b00000 <= va <= 0x4b20000): continue for (o, dsz, pa) in descs: if dsz != sz: continue key = (va, page, o) if key in injected: continue if inject(va, pa): injected.add(key) time.sleep(1) log("=== resolver7 done: %d injection(s) ===" % len(injected)) return 0 if __name__ == "__main__": sys.exit(main())