#!/usr/bin/env python3 # wall2_resolver5.py - final: continuous scan, all-candidate injection. # # Structure (r675, verified): an RM page holds the client channel's window # records and memdescs: # {0x4480000, 0x20000} push window record # {0x44a0000, 0x40000} ring window record # {0x20000, 0x03008000, PUSH_PA} push window memdesc # {0x40000, 0x03008000, RING_PA} ring window memdesc (PA == validated ring pa) # The resolver scans CONTINUOUSLY (no ring-line gate), finds pages holding the # pair of window records, and injects 0x4480000 -> every 0x20000 memdesc PA in # the same page (last write wins in the service; content check arbitrates). import subprocess, struct, time, sys, os RAM = "/dev/shm/vgpu-guest-ram" PARAM = "/sys/module/vgsp/parameters/sema_map_add" LOG = "/tmp/opencode/wall2_resolver5.log" PUSH_VA = 0x4480000 RING_VA = 0x44a0000 WATCH_S = int(os.environ.get("W2_WATCH", "600")) 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 gpa2off(pa): if pa < 0x80000000: return pa if pa < 0x180000000: return 0x80000000 + (pa - 0x100000000) return None def off2gpa(off): return off if off < 0x80000000 else 0x100000000 + (off - 0x80000000) 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("