"""find_d3d9_via_iat.py Find d3d9.dll's load address by walking AC's import table. Strategy: locate the string "Direct3DCreate9" in AC's image, then find the IAT entry that resolves it. The IAT slot holds the runtime address of Direct3DCreate9 (= address INSIDE d3d9.dll). VirtualQuery on that address gives us d3d9.dll's base + size.""" import ctypes, ctypes.wintypes as wt, sys, struct PROCESS_VM_READ = 0x10 PROCESS_QUERY_INFORMATION = 0x400 k = ctypes.windll.kernel32 k.OpenProcess.argtypes = [wt.DWORD, wt.BOOL, wt.DWORD]; k.OpenProcess.restype = wt.HANDLE k.ReadProcessMemory.argtypes = [wt.HANDLE, wt.LPCVOID, wt.LPVOID, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)] k.ReadProcessMemory.restype = wt.BOOL k.VirtualQueryEx.argtypes = [wt.HANDLE, wt.LPCVOID, ctypes.c_void_p, ctypes.c_size_t] k.VirtualQueryEx.restype = ctypes.c_size_t class MBI(ctypes.Structure): _fields_ = [("BaseAddress", ctypes.c_void_p), ("AllocationBase", ctypes.c_void_p), ("AllocationProtect", wt.DWORD), ("RegionSize", ctypes.c_size_t), ("State", wt.DWORD), ("Protect", wt.DWORD), ("Type", wt.DWORD)] def rd(h, va, n): buf = (ctypes.c_ubyte * n)(); sz = ctypes.c_size_t(0) if not k.ReadProcessMemory(h, va, buf, n, ctypes.byref(sz)): return None return bytes(buf[:sz.value]) pid = int(sys.argv[1]) h = k.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, False, pid) if not h: print("OpenProcess fail"); sys.exit(2) # AC's image starts at 0x00400000. Read its full size from PE header. hdr = rd(h, 0x00400000 + 0x3C, 4) if not hdr: print("can't read AC PE header"); sys.exit(2) pe_off = struct.unpack('" else: # entry is an RVA to a Hint/Name struct: hint(2) + name(asciiz) func_name = ac[entry+2:entry+64].split(b'\x00', 1)[0].decode(errors='replace') # Read the IAT slot value (runtime address) iat_slot_va = 0x00400000 + fthunk + idx*4 iat_val = struct.unpack(' 0x{iat_val:08x}") if func_name == 'Direct3DCreate9': # Use this to find d3d9.dll's range mbi = MBI() if k.VirtualQueryEx(h, iat_val, ctypes.byref(mbi), ctypes.sizeof(mbi)): ab = mbi.AllocationBase or 0 # Get image size from PE hdr2 = rd(h, ab + 0x3C, 4) pe2 = struct.unpack('