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)
print(f"InGameState: {hex(igs)}")

# Find UI Root in InGameState
# Usually InGameState + 0x60, +0x80, +0x120, +0x240, +0x3E8...
for off in range(0x0, 0x500, 8):
    ptr = rpm_u64(igs + off)
    if 0x20000000000 <= ptr <= 0x30000000000:
        # Check if ptr looks like UI element (children vector at +0x20..+0x40 or similar)
        # Let's check VTable
        vtable = rpm_u64(ptr)
        if mod_base <= vtable <= mod_base + 0x4000000:
            print(f"InGameState + {hex(off)} -> ptr={hex(ptr)}, vtable={hex(vtable)} (RVA: +{hex(vtable - mod_base)})")

kernel32.CloseHandle(h_proc)
