import pymem, struct

pm = pymem.Pymem(43084)
base = 0x7ff6afc20000

# Pattern for ASCII "Metadata/"
needle = b"Metadata/"
import re

# Find in memory regions of PathOfExile.exe
print("Searching for 'Metadata/' in process memory...")
regions = []
addr = 0x10000
import ctypes
from ctypes import wintypes

class MEMORY_BASIC_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("BaseAddress", ctypes.c_uint64),
        ("AllocationBase", ctypes.c_uint64),
        ("AllocationProtect", wintypes.DWORD),
        ("Alignment1", wintypes.WORD),
        ("RegionSize", ctypes.c_uint64),
        ("State", wintypes.DWORD),
        ("Protect", wintypes.DWORD),
        ("Type", wintypes.DWORD),
        ("Alignment2", wintypes.WORD),
    ]

k32 = ctypes.windll.kernel32
mbi = MEMORY_BASIC_INFORMATION()

matches = []
while k32.VirtualQueryEx(pm.process_handle, ctypes.c_void_p(addr), ctypes.byref(mbi), ctypes.sizeof(mbi)):
    if mbi.State == 0x1000 and (mbi.Protect & 0xEE) and not (mbi.Protect & 0x100): # MEM_COMMIT, readable, not PAGE_GUARD
        if 0x10000 <= mbi.RegionSize <= 64 * 1024 * 1024:
            try:
                chunk = pm.read_bytes(mbi.BaseAddress, mbi.RegionSize)
                idx = 0
                while True:
                    pos = chunk.find(needle, idx)
                    if pos == -1: break
                    str_addr = mbi.BaseAddress + pos
                    s = chunk[pos:pos+64].split(b'\x00')[0].decode('ascii', errors='ignore')
                    if any(k in s for k in ["Breach", "Ritual", "Shrine", "Delirium", "Boss", "Stash", "Waypoint", "NPC"]):
                        matches.append((str_addr, s))
                        if len(matches) >= 15: break
                    idx = pos + len(needle)
            except: pass
    if len(matches) >= 15: break
    addr = mbi.BaseAddress + mbi.RegionSize

print(f"Found {len(matches)} interesting Metadata strings:")
for sa, s in matches:
    print(f"  {hex(sa)}: {s}")
