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

mod_base = 0x7FF6AFC20000

targets = {
    "Minimap_Visibility": 0x7ff6b2da9200,
    "RenderVisibility": 0x7ff6b2da9218,
    "revealed_bound": 0x7ff6b2da9250,
    "use_revealed_bound": 0x7ff6b2da9290,
    "visibility_fully_revealed": 0x7ff6b2da92c8,
    "Minimap Visibility": 0x7ff6b2da92e8,
}

# Scan chunk by chunk in .text
text_start = mod_base + 0x1000
text_size = 0x2E85000
chunk_size = 2 * 1024 * 1024

print("Searching for RIP references to shader strings...")

curr = text_start
end = text_start + text_size

# Since chunk size is 2MB, let's unpack all int32s in memory
import array

while curr < end:
    read_len = min(chunk_size, end - curr)
    data = rpm(curr, read_len)
    if not data:
        curr += chunk_size
        continue
    
    # We search for targets
    # An instruction: 48 8D ?? [disp32]
    # disp32 is at offset k+3
    # next instruction is curr + k + 7
    # target = next_instruction + disp32
    # So disp32 = target - (curr + k + 7)
    # We can check positions where byte is 0x8D (lea) preceded by 0x48/0x4C
    k = 0
    while True:
        pos = data.find(b'\x8d', k)
        if pos == -1 or pos >= len(data) - 6:
            break
        if pos > 0 and (data[pos-1] == 0x48 or data[pos-1] == 0x4C):
            disp = struct.unpack("<i", data[pos+2:pos+6])[0]
            instr_addr = curr + pos - 1
            dest = (instr_addr + 7) + disp
            for name, t_addr in targets.items():
                if dest == t_addr:
                    print(f"[{name}] at {hex(instr_addr)} (RVA: +{hex(instr_addr - mod_base)})")
                    win = rpm(instr_addr - 32, 96)
                    print("   Hex:", win.hex() if win else "")
        k = pos + 1

    curr += read_len - 16

kernel32.CloseHandle(h_proc)
