如何用Python自动定位Cheat Engine中的游戏动态内存地址
内存地址自动定位解决方案
实现逻辑
你的问题根源是硬编码了游戏运行时的临时动态地址,Windows ASLR(地址空间布局随机化)机制会让游戏每次启动的主模块加载基址发生变化,所以需要先自动获取游戏主模块基址,再遍历你已经在Cheat Engine中找到的指针偏移链,就能自动算出目标地址,不需要每次手动复制。
修改后的完整代码
import ctypes as c from ctypes import wintypes as w import psutil import time import os process_name = "TheIsleClient-Win64-Shipping.exe" pid = None module_base = None # 获取进程PID和主模块基址 for proc in psutil.process_iter(['name', 'pid', 'memory_maps']): if proc.name() == process_name: pid = proc.pid # 遍历模块找主程序基址 for mmap in proc.memory_maps(grouped=False): if process_name in mmap.path: module_base = int(mmap.addr.split('-')[0], 16) break break if not pid or not module_base: print("未找到游戏进程") exit() k32 = c.windll.kernel32 OpenProcess = k32.OpenProcess OpenProcess.argtypes = [w.DWORD,w.BOOL,w.DWORD] OpenProcess.restype = w.HANDLE ReadProcessMemory = k32.ReadProcessMemory ReadProcessMemory.argtypes = [w.HANDLE,w.LPCVOID,w.LPVOID,c.c_size_t,c.POINTER(c.c_size_t)] ReadProcessMemory.restype = w.BOOL WriteProcessMemory = k32.WriteProcessMemory WriteProcessMemory.argtypes = [w.HANDLE,w.LPVOID,c.c_void_p,c.c_size_t,c.POINTER(c.c_size_t)] WriteProcessMemory.restype = w.BOOL GetLastError = k32.GetLastError GetLastError.argtypes = None GetLastError.restype = w.DWORD CloseHandle = k32.CloseHandle CloseHandle.argtypes = [w.HANDLE] CloseHandle.restype = w.BOOL # 遍历指针偏移链获取最终地址 def get_final_address(process_handle, base, offsets): addr = base for offset in offsets[:-1]: addr += offset data = c.c_ulonglong() bytes_read = c.c_ulonglong() if not ReadProcessMemory(process_handle, c.c_void_p(addr), c.byref(data), c.sizeof(data), c.byref(bytes_read)): return None addr = data.value # 最后一级偏移直接加 addr += offsets[-1] return addr offsets = [0x30, 0x250, 0x130, 0x20, 0x258, 0x260, 0x734] while True: processHandle = OpenProcess(0x10 | 0x20, False, pid) if not processHandle: print("无法打开进程") break # 自动计算目标地址 target_addr = get_final_address(processHandle, module_base, offsets) if not target_addr: print("地址计算失败") CloseHandle(processHandle) time.sleep(1) continue data = c.c_ulonglong() bytesRead = c.c_ulonglong() result = ReadProcessMemory(processHandle, c.c_void_p(target_addr), c.byref(data), c.sizeof(data), c.byref(bytesRead)) e = GetLastError() if result: num = str(hex(data.value)) numR = num[-5:] numHex = int(numR, 16) os.system('cls') print(numHex) else: print(f"读取失败,错误码: {e}") CloseHandle(processHandle) time.sleep(1)
注意事项
- 运行代码需要管理员权限,否则无法读取游戏进程内存
- 偏移列表如果随游戏更新发生变化,同步修改代码里的
offsets数组即可 - 代码中已经合并了读写权限的进程句柄,不需要重复打开两次句柄
内容的提问来源于stack exchange,提问作者Airton Santos
相关产品推荐
相关产品推荐

