#!/usr/bin/env python3 # r673: find the push page. Patterns: ring entry raw qwords, the sem VA, and # method-stream signatures. Dump contexts. import numpy as np, struct, os, time RAM="/dev/shm/vgpu-guest-ram" img=open(RAM,"rb"); fsz=os.path.getsize(RAM) 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 or off+n>fsz: return None img.seek(off); return img.read(n) pats=[ ("entry0raw", 0x0005980004500000), ("entry1raw", 0x0000040004500598), ("entry2raw", 0x0003d0000450059c), ("sem_va", 0x4500598), ("sem_va2", 0x450059c), ("m20038090", 0x20038090), ("push_va", 0x4500000), ] CH=64<<20 for name,pat in pats: hits=[] t0=time.time() for pos in range(0,fsz,CH): img.seek(pos); d=img.read(min(CH,fsz-pos)) n=len(d)//8 a=np.frombuffer(d[:n*8],dtype=np.uint64) idx=np.nonzero(a==np.uint64(pat))[0] for i in idx: hits.append(pos+int(i)*8) print("== %s pat=0x%x hits=%d (%.1fs)" % (name,pat,len(hits),time.time()-t0)) for off in hits[:12]: gpa=off2gpa(off); page=gpa&~0xfff d=rd(page,0x1000) ro=gpa-page s=max(0,ro-24); e=min(0x1000,ro+40) print(" gpa=0x%x page=0x%x off=0x%x ctx=%s" % (gpa,page,ro,d[s:e].hex() if d else "?")) if len(hits)>12: print(" ... %d more" % (len(hits)-12))