import ctypes
from ctypes import wintypes
import re

PROCESS_VM_READ = 0x0010
PROCESS_QUERY_INFORMATION = 0x0400

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
OpenProcess = kernel32.OpenProcess
OpenProcess.restype = wintypes.HANDLE
OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]

ReadProcessMemory = kernel32.ReadProcessMemory
ReadProcessMemory.restype = wintypes.BOOL
ReadProcessMemory.argtypes = [wintypes.HANDLE, wintypes.LPCVOID, wintypes.LPVOID, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)]

CloseHandle = kernel32.CloseHandle
CloseHandle.restype = wintypes.BOOL
CloseHandle.argtypes = [wintypes.HANDLE]

pid = 39484
h_proc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, False, pid)

base = 0x7FF6AFC20000
# .rdata VA=0x2e87000 VSize=0xb7c086
rdata_start = base + 0x2E87000
rdata_size = 0xB7C000

chunk_size = 1024 * 1024
buf = ctypes.create_string_buffer(chunk_size)
bytes_read = ctypes.c_size_t(0)

keywords = [b"Minimap", b"minimap", b"FogOfWar", b"fog_of_war", b"Explored", b"explored"]

print("Searching .rdata for keywords...")
for offset in range(0, rdata_size, chunk_size):
    cur_addr = rdata_start + offset
    n = min(chunk_size, rdata_size - offset)
    if ReadProcessMemory(h_proc, ctypes.c_void_p(cur_addr), buf, n, ctypes.byref(bytes_read)):
        data = bytes(buf)[:bytes_read.value]
        for kw in keywords:
            for m in re.finditer(re.escape(kw), data):
                pos = m.start()
                # print surrounding ascii string
                start_str = max(0, pos - 10)
                end_str = min(len(data), pos + 40)
                snippet = data[start_str:end_str]
                addr = cur_addr + pos
                # extract null-terminated string
                null_end = data.find(b'\x00', pos)
                if null_end != -1:
                    full_str = data[pos:null_end]
                else:
                    full_str = data[pos:pos+30]
                if len(full_str) > 3 and len(full_str) < 80:
                    try:
                        decoded = full_str.decode('utf-8', errors='ignore')
                        if decoded.isprintable():
                            print(f"  0x{addr:016X}: \"{decoded}\"")
                    except Exception:
                        pass

CloseHandle(h_proc)
