import ctypes
import ctypes.wintypes as w
import struct
import subprocess

k32 = ctypes.WinDLL("kernel32", use_last_error=True)
k32.OpenProcess.restype = w.HANDLE
k32.ReadProcessMemory.argtypes = [
    w.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)
]
k32.ReadProcessMemory.restype = w.BOOL

def rpm(h, addr, size):
    buf = (ctypes.c_ubyte * size)()
    got = ctypes.c_size_t(0)
    if not k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, size, ctypes.byref(got)):
        return None
    return bytes(buf[: got.value])

out = subprocess.check_output(['powershell', '-Command', '(Get-Process -Name *PathOfExile*).Id'])
pid = int(out.decode().split()[0])
h = k32.OpenProcess(0x1F0FFF, False, pid)

igs = 0x48514e50f10
cam368 = struct.unpack("<Q", rpm(h, igs + 0x368, 8))[0]
cam378 = struct.unpack("<Q", rpm(h, igs + 0x378, 8))[0]

print(f"cam368 = {cam368:#x}")
b368 = rpm(h, cam368, 0x600)
vt368 = struct.unpack("<Q", b368[:8])[0]
z368 = struct.unpack_from("<f", b368, 0x528)[0]
m368 = struct.unpack_from("<4f", b368, 0x1A0)
print(f"  vtable={vt368:#x}, zoom@+528={z368}, matrix[0..3]={m368}")

print(f"cam378 = {cam378:#x}")
b378 = rpm(h, cam378, 0x600)
vt378 = struct.unpack("<Q", b378[:8])[0]
z378 = struct.unpack_from("<f", b378, 0x528)[0] if len(b378) > 0x52c else 0.0
m378 = struct.unpack_from("<4f", b378, 0x1A0) if len(b378) > 0x1b0 else (0,0,0,0)
print(f"  vtable={vt378:#x}, zoom@+528={z378}, matrix[0..3]={m378}")
