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()

class MEMORY_BASIC_INFORMATION(ctypes.Structure):
    _fields_ = [
        ('BaseAddress', ctypes.c_void_p),
        ('AllocationBase', ctypes.c_void_p),
        ('AllocationProtect', wintypes.DWORD),
        ('RegionSize', ctypes.c_size_t),
        ('State', wintypes.DWORD),
        ('Protect', wintypes.DWORD),
        ('Type', wintypes.DWORD),
    ]

pid = 30076
hProc = kernel32.OpenProcess(0x0010 | 0x0400, False, pid)
if not hProc: sys.exit(1)

mbi = MEMORY_BASIC_INFORMATION()
addr = 0
pat_mp = struct.pack('<i', 2455)

print("Scanning for MP=2455...")
while kernel32.VirtualQueryEx(hProc, ctypes.c_void_p(addr), ctypes.byref(mbi), ctypes.sizeof(mbi)):
    if mbi.State == 0x1000 and (mbi.Protect & 0xEE) != 0 and (mbi.Protect & 0x01) == 0:
        size = min(mbi.RegionSize, 1024 * 1024 * 8)
        buf = (ctypes.c_char * size)()
        bytesRead = ctypes.c_size_t()
        if kernel32.ReadProcessMemory(hProc, ctypes.c_void_p(addr), buf, size, ctypes.byref(bytesRead)):
            data = bytes(buf)[:bytesRead.value]
            idx = 0
            while True:
                idx = data.find(pat_mp, idx)
                if idx == -1: break
                m_addr = addr + idx
                rel_hp = m_addr - 0x10BC65B4
                print(f"  MP (2455) at 0x{m_addr:08X} (rel to HP 0x10BC65B4: {rel_hp:+d})")
                idx += 4
    addr += mbi.RegionSize
    if addr >= 0x7FFFFFFF: break

kernel32.CloseHandle(hProc)
