import ctypes
import struct

PROCESS_ALL_ACCESS = 0x1F0FFF
kernel32 = ctypes.windll.kernel32
h_proc = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, 43084)

def rpm(addr, size):
    buf = ctypes.create_string_buffer(size)
    bytes_read = ctypes.c_size_t(0)
    if kernel32.ReadProcessMemory(h_proc, ctypes.c_void_p(addr), buf, size, ctypes.byref(bytes_read)):
        return buf.raw
    return None

def rpm_u64(addr):
    d = rpm(addr, 8)
    return struct.unpack("<Q", d)[0] if d else 0

mod_base = 0x7FF6AFC20000
igs = rpm_u64(mod_base + 0x4430108)
area = rpm_u64(igs + 0x290)
print(f"AreaInstance: {hex(area)}")

# Scan AreaInstance from 0 to 0x1200 for embedded objects or pointers to objects
for off in range(0, 0x1200, 8):
    ptr = rpm_u64(area + off)
    if 0x20000000000 <= ptr <= 0x30000000000:
        vt = rpm_u64(ptr)
        if mod_base <= vt <= mod_base + 0x4000000:
            # Found an OOP object pointer!
            # Let's see if we can find its type name or RTTI
            print(f"Area + {hex(off)} -> ptr={hex(ptr)}, vtable={hex(vt)} (RVA: +{hex(vt - mod_base)})")

kernel32.CloseHandle(h_proc)
