import sys, struct, ctypes
from ctypes import wintypes

sys.stdout.reconfigure(encoding='utf-8')
kernel32 = ctypes.windll.kernel32
advapi32 = ctypes.windll.advapi32

def enable_debug():
    hToken = wintypes.HANDLE()
    if advapi32.OpenProcessToken(kernel32.GetCurrentProcess(), 0x0020 | 0x0008, ctypes.byref(hToken)):
        luid = wintypes.LARGE_INTEGER()
        if advapi32.LookupPrivilegeValueW(None, "SeDebugPrivilege", ctypes.byref(luid)):
            class TP(ctypes.Structure):
                _fields_ = [('Count', wintypes.DWORD), ('Luid', wintypes.LARGE_INTEGER), ('Attr', wintypes.DWORD)]
            tp = TP(1, luid, 2)
            advapi32.AdjustTokenPrivileges(hToken, False, ctypes.byref(tp), ctypes.sizeof(tp), None, None)
        kernel32.CloseHandle(hToken)
enable_debug()

pid = 30076 # MeCuaCacCon: HP=548, MP=2455, Sta=709
hProc = kernel32.OpenProcess(0x0010 | 0x0400, False, pid)
if not hProc:
    print(f"Cannot open PID {pid}")
    sys.exit(1)

base_addr = 0x10BC6500
size = 0x400 # 1024 bytes
buf = (ctypes.c_char * size)()
bytesRead = ctypes.c_size_t()

if kernel32.ReadProcessMemory(hProc, ctypes.c_void_p(base_addr), buf, size, ctypes.byref(bytesRead)):
    data = bytes(buf)[:bytesRead.value]
    print(f"Memory dump around 0x10BC65B4 (PID {pid}):")
    for i in range(0, len(data) - 4, 4):
        val = struct.unpack_from('<i', data, i)[0]
        val_u = struct.unpack_from('<I', data, i)[0]
        addr = base_addr + i
        rel = addr - 0x10BC65B4
        tag = ""
        if val == 548: tag = " <-- HP (548)"
        elif val == 2455: tag = " <-- MP (2455)"
        elif val == 709: tag = " <-- Stamina (709)"
        elif val == 47: tag = " <-- Level (47)"
        elif val > 0 and val < 100000:
            tag = f" (val={val})"
        print(f"  0x{addr:08X} [{rel:+04d}]: 0x{val_u:08X}{tag}")

kernel32.CloseHandle(hProc)
