import ctypes
import ctypes.wintypes as w
import subprocess

k32 = ctypes.WinDLL("kernel32", use_last_error=True)
k32.OpenProcess.restype = w.HANDLE
k32.ReadProcessMemory.argtypes = [
    w.HANDLE, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)
]
k32.ReadProcessMemory.restype = w.BOOL

def rpm(h, addr, size):
    buf = (ctypes.c_ubyte * size)()
    got = ctypes.c_size_t(0)
    if not k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, size, ctypes.byref(got)):
        return None
    return bytes(buf[: got.value])

out = subprocess.check_output(['powershell', '-Command', '(Get-Process -Name *PathOfExile*).Id'])
pid = int(out.decode().split()[0])
h = k32.OpenProcess(0x1F0FFF, False, pid)

base = 0x7ff6afc20000
size = 0x4c9e000

print(f"Scanning .text for Atlas Fog pattern: F3 0F 59 51 ? F3 0F 58 C1 ...")
chunk_sz = 1024 * 1024
import re
pat = re.compile(b'\xf3\x0f\x59\x51.\xf3\x0f\x58\xc1', re.DOTALL)

for off in range(0, size, chunk_sz):
    b = rpm(h, base + off, chunk_sz + 16)
    if not b: continue
    for m in pat.finditer(b):
        hit_addr = base + off + m.start()
        print(f"FOUND Atlas Fog hit at {hit_addr:#x} (RVA +0x{hit_addr - base:x}): {b[m.start():m.start()+16].hex(' ')}")
