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
for off in [0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360]:
    ptr = struct.unpack("<Q", rpm(h, igs + off, 8))[0]
    print(f"igs+{off:#x}: {ptr:#x}")
    if 0x100000000 <= ptr <= 0x7FFFFFFFFFF:
        b = rpm(h, ptr, 0x100)
        if b:
            vt = struct.unpack("<Q", b[:8])[0]
            print(f"  vtable: {vt:#x}")
            # check floats in object
            floats = []
            for fo in range(0, 0x100, 4):
                fv = struct.unpack_from("<f", b, fo)[0]
                if 1.0 <= abs(fv) <= 1000.0:
                    floats.append((fo, fv))
            if floats:
                print(f"  floats: {floats[:8]}")
