import ctypes
import struct

PROCESS_ALL_ACCESS = 0x1F0FFF
kernel32 = ctypes.windll.kernel32
h_proc = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, 43084)

def rpm(addr, size):
    buf = ctypes.create_string_buffer(size)
    bytes_read = ctypes.c_size_t(0)
    if kernel32.ReadProcessMemory(h_proc, ctypes.c_void_p(addr), buf, size, ctypes.byref(bytes_read)):
        return buf.raw
    return None

def rpm_u64(addr):
    d = rpm(addr, 8)
    return struct.unpack("<Q", d)[0] if d else 0

mod_base = 0x7FF6AFC20000

# Search .rdata section for strings
# .rdata is typically mod_base + 0x2E87000, size ~ 0xB7C000
rdata_start = mod_base + 0x2E87000
rdata_size = 0xB7C000

print("Reading .rdata...")
rdata = rpm(rdata_start, rdata_size)
if not rdata:
    print("Failed to read .rdata")
    exit(1)

keywords = [
    b"Minimap", b"minimap", b"SubTerrain", b"Exploration", b"FogOfWar",
    b"visited", b"Visited", b"reveal", b"Reveal", b"Fog", b"fog"
]

found_strings = {}
for kw in keywords:
    idx = 0
    while True:
        pos = rdata.find(kw, idx)
        if pos == -1:
            break
        # find string start and end (null-terminated)
        start = pos
        while start > 0 and rdata[start-1] >= 0x20 and rdata[start-1] <= 0x7E:
            start -= 1
        end = pos
        while end < len(rdata) and rdata[end] >= 0x20 and rdata[end] <= 0x7E:
            end += 1
        s = rdata[start:end].decode("ascii", errors="ignore")
        addr = rdata_start + start
        if len(s) >= 4 and s not in found_strings:
            found_strings[s] = addr
        idx = pos + len(kw)

print(f"Found {len(found_strings)} unique strings.")
for s, addr in list(found_strings.items())[:40]:
    print(f"  {hex(addr)} (RVA: +{hex(addr - mod_base)}): \"{s}\"")

kernel32.CloseHandle(h_proc)
