import ctypes
import struct

k32 = ctypes.windll.kernel32
pid = 43084
h = k32.OpenProcess(0x10 | 0x400, False, pid)
br = ctypes.c_size_t()

def rpm(addr, size):
    buf = (ctypes.c_char * size)()
    if k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, size, ctypes.byref(br)):
        return bytes(buf)
    return None

skill_icons = [
    (0x02AF2E0BA988, "MartialArtistMantraofIllusionsSkill.dds"),
    (0x02AF2E0BB888, "DruidWolfLeapAttack.dds"),
    (0x02AF2E0BBB88, "MonkTempestBell.dds"),
    (0x02AF2E0BBD08, "MonkChargedStaff.dds"),
    (0x02AF2E0BC188, "MonkTempestFlurry.dds"),
    (0x02AF2E0BC788, "DruidBearWarcry.dds")
]

print("=== Scanning references to Skill Icon strings ===")
# Scan committed memory for pointers to these strings
addr = 0x10000
mbi = (ctypes.c_byte * 48)()

targets = {addr: name for addr, name in skill_icons}

while k32.VirtualQueryEx(h, ctypes.c_void_p(addr), mbi, 48):
    base_addr = struct.unpack_from('<Q', bytes(mbi), 0)[0]
    region_size = struct.unpack_from('<Q', bytes(mbi), 24)[0]
    state = struct.unpack_from('<I', bytes(mbi), 32)[0]
    protect = struct.unpack_from('<I', bytes(mbi), 36)[0]

    if state == 0x1000 and (protect & 0xEE) and not (protect & 0x101):
        if region_size <= 64 * 1024 * 1024:
            buf = (ctypes.c_char * min(region_size, 4 * 1024 * 1024))()
            for off in range(0, region_size, len(buf)):
                cur_len = min(len(buf), region_size - off)
                if k32.ReadProcessMemory(h, ctypes.c_void_p(base_addr + off), buf, cur_len, ctypes.byref(br)):
                    raw = bytes(buf)[:br.value]
                    for i in range(0, len(raw) - 7, 8):
                        val = struct.unpack_from('<Q', raw, i)[0]
                        if val in targets:
                            holder = base_addr + off + i
                            print(f"Holder 0x{holder:012X} -> 0x{val:012X} ({targets[val]})")
                            # dump 64 bytes around holder
                            dump = rpm(holder - 32, 96)
                            if dump:
                                # show u64 values
                                u64s = [f"0x{struct.unpack_from('<Q', dump, k)[0]:X}" for k in range(0, 96, 8)]
                                print(f"    Context: {u64s}")
    addr = base_addr + region_size

k32.CloseHandle(h)
