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

def inspect_pid(pid, expected_name, hp, mp, sta, lvl):
    hProc = kernel32.OpenProcess(0x0010 | 0x0400, False, pid)
    if not hProc:
        print(f"Cannot open PID {pid}")
        return
    
    # Read 4KB around 0x006DEC44
    base_addr = 0x006DE000
    size = 0x2000 # 8KB
    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]
        name_offset = 0x006DEC44 - base_addr
        name_in_ram = data[name_offset:name_offset+32].split(b'\0')[0].decode('ascii', errors='ignore')
        print(f"\n=======================================================")
        print(f"PID {pid} | Target Name: {expected_name} | Name at 0x006DEC44: '{name_in_ram}'")
        print(f"=======================================================")
        
        # Scan all occurrences of expected_name in process memory
        print(f"\nScanning all occurrences of '{expected_name}' across all RAM regions...")
        mbi = wintypes.MEMORY_BASIC_INFORMATION() if hasattr(wintypes, 'MEMORY_BASIC_INFORMATION') else None
        # Using VirtualQueryEx
        class MBI(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)
            ]
        mbi = MBI()
        addr = 0
        name_bytes = expected_name.encode('ascii')
        
        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 * 4)
                buf = (ctypes.c_char * size)()
                nread = ctypes.c_size_t()
                if kernel32.ReadProcessMemory(hProc, ctypes.c_void_p(addr), buf, size, ctypes.byref(nread)):
                    chunk = bytes(buf)[:nread.value]
                    idx = 0
                    while True:
                        idx = chunk.find(name_bytes + b'\0', idx)
                        if idx == -1: break
                        hit_addr = addr + idx
                        if hit_addr != 0x006DEC44:
                            print(f"\n  Found '{expected_name}' at HEAP: 0x{hit_addr:08X}")
                            # Dump -64 to +128
                            start_b = max(0, idx - 64)
                            end_b = min(len(chunk), idx + 128)
                            h_data = chunk[start_b:end_b]
                            for o in range(0, len(h_data), 16):
                                cur_a = addr + start_b + o
                                rel_n = cur_a - hit_addr
                                chx = " ".join(f"{b:02X}" for b in h_data[o:o+16])
                                c_ints = [struct.unpack_from('<i', h_data, o+j)[0] for j in range(0, min(16, len(h_data)-o), 4)]
                                print(f"    0x{cur_a:08X} ({rel_n:+04d}): {chx} | Ints: {c_ints}")
                        idx += len(name_bytes) + 1
            addr += mbi.RegionSize
            if addr >= 0x7FFFFFFF: break
    kernel32.CloseHandle(hProc)

inspect_pid(30076, "MeCuaCacCon", 548, 2455, 709, 47)
inspect_pid(32572, "BoCuaCacCon", 846, 2409, 924, 75)
inspect_pid(12768, "ConGailCung", 540, 1203, 687, 46)
inspect_pid(31164, "ConCuaBoMe", 612, 1419, 592, 49)
