"""probe_rsd3d_lost.py Walk s_Resources, find lost (m_bIsLost=1) RenderSurfaceD3D entries (vfptr=0x00801a94), sample 5 of them, print m_pSurfaceBits state. v20-active client: m_pSurfaceBits should be NULL on lost entries (RS::Destroy ran) v20-absent client: m_pSurfaceBits often non-NULL on lost entries (PurgeResource only) m_pSurfaceBits is at primary+0x114. Entry IS GR-view (= primary + 0x30). So accessed at entry + (0x114 - 0x30) = entry + 0xE4.""" import ctypes, ctypes.wintypes as wt, sys, struct PROCESS_VM_READ = 0x10 PROCESS_QUERY_INFORMATION = 0x400 k = ctypes.windll.kernel32 k.OpenProcess.argtypes = [wt.DWORD, wt.BOOL, wt.DWORD]; k.OpenProcess.restype = wt.HANDLE k.ReadProcessMemory.argtypes = [wt.HANDLE, wt.LPCVOID, wt.LPVOID, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)] k.ReadProcessMemory.restype = wt.BOOL S_RESOURCES_M_DATA = 0x008398C4 S_RESOURCES_M_NUM = 0x008398CC RSD3D_VTABLE = 0x00801a94 def rd(h, va, n): buf = (ctypes.c_ubyte * n)(); sz = ctypes.c_size_t(0) if not k.ReadProcessMemory(h, va, buf, n, ctypes.byref(sz)): return None return bytes(buf[:sz.value]) def rd_u32(h, va): b = rd(h, va, 4); return struct.unpack('