尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python自动化内存读写:基于Cheat Engine原理的游戏辅助脚本开发指南

Python自动化内存读写:基于Cheat Engine原理的游戏辅助脚本开发指南 在实际游戏开发、逆向分析或自动化测试领域经常会遇到需要理解程序内部数据结构和运行机制的场景。Cheat Engine简称CE作为一款经典的内存扫描与调试工具是许多开发者、安全研究员和自动化脚本作者入门逆向工程的“第一课”。它不局限于游戏修改更是一种理解进程内存布局、动态数据追踪和外部程序交互的实践窗口。结合Python这类强大的脚本语言我们可以将CE的手动分析过程转化为可重复、可扩展的自动化脚本从而构建出具有一定智能AI特性的辅助工具用于数据分析、行为模拟或测试验证。本文面向有一定Python基础希望了解如何将CE的手动操作流程自动化并初步探索“AI外挂脚本”开发思路的开发者。我们将从CE的核心概念讲起逐步搭建一个能够与目标进程交互的Python环境并完成一个简单的内存数据读取与修改的自动化案例。学习完成后你将能够理解CE工具的基本原理并掌握使用Python控制CE或直接操作进程内存的基础方法为后续更复杂的自动化逻辑开发打下基础。1. 理解 Cheat Engine 的核心工作机制在开始编写任何自动化脚本之前必须清楚CE在背后做了什么。这并非鼓励违规行为而是理解Windows程序如何与内存交互的关键知识广泛应用于软件调试、性能分析和自动化测试。1.1 进程、内存与指针数据存在的形式一个运行中的程序进程在操作系统中拥有自己独立的虚拟内存空间。游戏中的金币、血量、坐标等数据都以特定值整数、浮点数、字符串等的形式存储在这个内存空间的某个地址上。这个地址类似于门牌号而值就是房间里的物品。然而每次程序重启由于动态链接库加载、堆分配等因素数据存放的“绝对地址”很可能发生变化。为了解决这个问题程序普遍采用“基地址偏移”的多级指针寻址方式。基地址通常指向一个模块如.exe或.dll的起始位置这个位置相对固定。通过基地址找到一块动态内存区域再经过一层或多层偏移最终定位到存储目标数据的“动态地址”。CE的核心功能之一就是帮我们找到这个稳定的寻址路径。1.2 Cheat Engine 的工作流程扫描、锁定与注入CE的典型使用流程揭示了与进程交互的基本步骤附加进程CE需要获得目标进程的调试或读取权限才能访问其内存空间。首次扫描根据已知数值如100点血量在进程内存中搜索所有匹配该值的内存地址。结果可能成千上万。过滤扫描改变游戏内数值如血量变为95然后在首次扫描的结果中搜索数值发生相应变化的地址。反复几次就能精确定位到存储目标数据的唯一或少数几个地址。分析访问/改写代码找到地址后CE可以查看是哪些汇编指令读取或改写了这个地址这有助于理解游戏逻辑。生成指针CE可以帮我们分析出指向这个动态地址的稳定指针路径基地址与偏移。修改与锁定可以手动修改该地址的值或者开启“锁定”功能让CE定时将其恢复为指定值实现“无限血量”等效果。自动化脚本的目标就是用Python代码复现步骤1、3、5、6并加入决策逻辑。1.3 从手动到自动Python 的角色Python可以通过ctypes、pymem等库直接调用Windows API如ReadProcessMemory,WriteProcessMemory来读写进程内存实现CE的核心读写功能。更高级的自动化可能涉及模式扫描替代CE的扫描界面用算法在内存中搜索特定字节序列。行为决策基于读取到的内存值如敌人坐标、自身状态由脚本逻辑决定执行什么操作如移动、攻击。模拟输入通过pyautogui、pydirectinput等库模拟键盘鼠标操作影响游戏。图像识别作为内存读取的补充使用opencv识别屏幕内容应对无法直接从内存获取信息的情况。这种基于状态感知读内存/识图和动作执行写内存/模拟操作的循环构成了所谓“AI外挂脚本”的雏形。2. 环境准备与依赖配置工欲善其事必先利其器。我们需要配置一个能够进行进程内存操作的Python开发环境。请注意以下操作仅用于学习与研究请在合法授权的程序上进行实践。2.1 Python 环境与编辑器确保你已安装Python推荐3.8及以上版本。可以使用Anaconda或直接安装官方Python。通过命令行验证python --version选择一个顺手的代码编辑器如VSCode。在VSCode中安装Python扩展后可以方便地运行和调试脚本。2.2 核心 Python 库安装我们将使用几个关键的库。通过pip在命令行中安装pip install pymem pip install pywin32 pip install keyboard pip install pyautoguipymem一个封装了Windows内存操作API的友好库比直接使用ctypes更简单。pywin32提供对Windows API更广泛的访问某些高级操作会用到。keyboard/pyautogui用于模拟用户输入。注意pyautogui的模拟可能被某些游戏屏蔽此时可考虑pydirectinput需额外安装。2.3 目标程序与 Cheat Engine准备一个用于学习的目标程序。强烈建议使用专门为内存修改学习设计的单机小游戏例如“植物大战僵尸”、“经典扫雷”或“Cheat Engine自带教程程序”。切勿在在线多人游戏或受保护商业软件上尝试这可能导致法律纠纷或封号。同时下载并安装Cheat Engine。我们将用它进行手动分析获取我们自动化脚本所需的关键地址和偏移信息。3. 实战从 CE 分析到 Python 自动化脚本我们以一个假设的、简单的单机游戏为例目标是自动化修改游戏中的“金币”数量。假设游戏进程名为MyTestGame.exe。3.1 第一步使用 CE 手动定位金币地址与指针这是自动化之前不可或缺的“侦察”阶段。打开游戏和CE运行MyTestGame.exe记下当前金币数量例如500。CE附加进程在CE中点击左上角电脑图标选择MyTestGame.exe进程。首次扫描数值类型选择“4字节”许多游戏整数用4字节存储在数值框输入“500”点击“首次扫描”。改变数值并过滤回到游戏通过正常操作让金币发生变化如消费变成450。回到CE在数值框输入新值“450”点击“再次扫描”。定位地址重复步骤4直到左侧地址列表只剩下少数几个地址。尝试逐个修改这些地址的值并在游戏中确认金币是否变化从而找到真正的金币地址。假设找到的动态地址是0x1A2B3C4D。找出指针右键点击找到的地址选择“找出是什么改写了这个地址”。然后在游戏中触发一次金币变化如再消费CE会记录下访问该地址的汇编指令。更重要的是我们可以点击“找出访问该地址的指针”。经过分析CE可能会给出一个指针路径例如MyTestGame.exe002A34D0 - 偏移 18 - 偏移 10 - 偏移 5C这里的MyTestGame.exe002A34D0就是模块基址静态偏移后面的18105C是逐级偏移。3.2 第二步编写 Python 脚本读取进程内存现在我们使用Python和pymem来复现CE的读取功能。首先创建一个Python脚本文件game_helper.py。import pymem import pymem.process import sys def find_game_process(process_name): 查找目标游戏进程 try: pm pymem.Pymem(process_name) print(f[] 成功附加进程: {process_name} (PID: {pm.process_id})) return pm except pymem.exception.ProcessNotFound: print(f[-] 未找到进程: {process_name}请确保游戏已运行。) sys.exit(1) except Exception as e: print(f[-] 附加进程时发生未知错误: {e}) sys.exit(1) def read_pointer_chain(pm, module_name, base_offset, offsets): 通过多级指针链读取最终值 :param pm: Pymem对象 :param module_name: 模块名如 MyTestGame.exe :param base_offset: 模块基址的静态偏移 :param offsets: 偏移量列表如 [0x18, 0x10, 0x5C] :return: 读取到的整数 try: # 获取模块基地址 module_base pymem.process.module_from_name(pm.process_handle, module_name).lpBaseOfDll print(f[*] 模块 {module_name} 基地址: {hex(module_base)}) # 计算第一级地址 addr module_base base_offset print(f[*] 基址静态偏移: {hex(addr)}) # 逐级遍历指针链 for i, offset in enumerate(offsets): # 读取当前地址存储的值这个值就是下一级的地址 addr pm.read_int(addr) if addr 0: raise ValueError(f在偏移 {i} 处读到空指针(0)。) addr offset print(f[*] 第{i1}级 - 地址: {hex(addr - offset)} 加偏移{hex(offset)} - {hex(addr)}) # 读取最终地址的值 value pm.read_int(addr) print(f[] 读取成功地址 {hex(addr)} 的值为: {value}) return value, addr except Exception as e: print(f[-] 读取指针链失败: {e}) return None, None if __name__ __main__: PROCESS_NAME MyTestGame.exe MODULE_NAME MyTestGame.exe BASE_OFFSET 0x002A34D0 # 从CE获取的静态偏移 OFFSETS [0x18, 0x10, 0x5C] # 从CE获取的多级偏移 # 1. 附加进程 pm find_game_process(PROCESS_NAME) # 2. 尝试读取金币 gold_value, gold_address read_pointer_chain(pm, MODULE_NAME, BASE_OFFSET, OFFSETS) if gold_value is not None: print(f当前金币数量: {gold_value}) # 这里可以加入更多逻辑比如判断金币少于某个值时自动修改关键代码解释pymem.Pymem(process_name)核心对象用于连接和操作目标进程。pm.read_int(address)从指定内存地址读取一个4字节整数。根据数据类型还有read_floatread_string等方法。指针链遍历这是最关键的逻辑。我们从一个“基地址静态偏移”的地址开始读出的值是一个指针加上下一个偏移得到新地址再读再加偏移……直到最后一级偏移读出的值才是我们想要的数据。错误处理内存操作极易因地址无效、权限不足、进程退出而失败必须用try-except包裹。3.3 第三步实现自动化修改与简单逻辑现在我们为脚本增加写入内存和基于条件的自动化逻辑。def write_memory_int(pm, address, value): 向指定地址写入一个整数 try: old_value pm.read_int(address) pm.write_int(address, value) print(f[] 写入成功地址 {hex(address)} 的值从 {old_value} 改为 {value}) return True except Exception as e: print(f[-] 写入内存失败: {e}) return False def auto_gold_maintain(pm, module_name, base_offset, offsets, threshold1000, set_value5000): 自动维护金币当金币低于阈值时自动设置为指定值 :param threshold: 金币阈值 :param set_value: 要设置的金币值 print(f[*] 启动金币自动维护阈值: {threshold}, 设置值: {set_value}) try: while True: gold_value, gold_address read_pointer_chain(pm, module_name, base_offset, offsets) if gold_value is None: print([-] 读取金币失败循环终止。) break if gold_value threshold: print(f[!] 金币 {gold_value} 低于阈值 {threshold}尝试修改...) if write_memory_int(pm, gold_address, set_value): print([] 金币修改完成) else: print([-] 金币修改失败。) else: print(f[*] 金币充足: {gold_value} 无需操作。) # 等待一段时间再检查避免循环过密 import time time.sleep(2) # 每2秒检查一次 except KeyboardInterrupt: print(\n[!] 用户中断退出自动维护。) except Exception as e: print(f[-] 自动维护循环发生错误: {e}) # 在主函数中调用自动化逻辑 if __name__ __main__: PROCESS_NAME MyTestGame.exe MODULE_NAME MyTestGame.exe BASE_OFFSET 0x002A34D0 OFFSETS [0x18, 0x10, 0x5C] pm find_game_process(PROCESS_NAME) # 选择模式 print(选择模式1. 单次读取 2. 自动维护金币) choice input(请输入选项 (1 或 2): ) if choice 1: gold_value, _ read_pointer_chain(pm, MODULE_NAME, BASE_OFFSET, OFFSETS) if gold_value is not None: print(f 当前金币: {gold_value} ) elif choice 2: # 启动自动维护循环 auto_gold_maintain(pm, MODULE_NAME, BASE_OFFSET, OFFSETS, threshold1000, set_value5000) else: print(无效选择。)这个脚本实现了一个简单的“AI决策”持续监控金币数值当低于1000时自动将其修改为5000。这就是自动化脚本从“读取”到“决策”再到“写入”的基本闭环。4. 运行验证、问题排查与进阶思考4.1 如何运行与验证脚本首先运行目标游戏MyTestGame.exe。在命令行或VSCode中运行你的Python脚本python game_helper.py。根据提示选择模式。如果选择模式2脚本会开始循环打印日志。此时你可以在游戏中消费金币观察脚本日志是否会检测到并执行修改同时查看游戏内金币是否真的被改回5000。注意首次运行时很可能失败因为从CE获取的BASE_OFFSET和OFFSETS是基于你当时游戏进程的。如果游戏重启基地址可能变化但“模块名静态偏移”通常不变。如果指针链失效需要重新用CE分析。4.2 常见问题排查表在开发此类脚本时你会遇到各种问题。下表列出了常见现象、原因及解决思路问题现象可能原因检查与解决思路ProcessNotFound错误1. 进程名错误。2. 游戏未启动或已关闭。3. 权限不足。1. 使用任务管理器确认精确的进程名不带.exe。2. 确保游戏已运行。3. 尝试以管理员身份运行Python脚本。读取到的值始终是0或垃圾数字1. 指针链地址错误或已失效。2. 数据类型不匹配如该读4字节却读了8字节。3. 偏移量错误十进制/十六进制混淆。1.最重要重新用CE分析指针确认游戏未重启。确保使用“找出指针”功能并勾选“指针”。2. 在CE中查看目标地址的数据类型在Python中使用对应的read_*函数。3. 确认偏移量是十进制还是十六进制。代码中0x开头表示十六进制。写入成功但游戏内无变化1. 写入的地址并非真实数据地址可能是显示值真实值在别处。2. 游戏有服务器校验或内存保护如反作弊。3. 写入的值超出合理范围被游戏纠正。1. CE中找到地址后尝试手动修改并冻结看游戏是否生效。如果不生效说明找错了。2.对于在线游戏此路不通且违规。仅限学习单机程序。3. 尝试写入一个合理范围内的值。脚本运行一次后崩溃1. 游戏进程退出或被结束。2. 内存访问违规地址无效。3. 代码逻辑错误如除零。1. 增加异常捕获在read_pointer_chain和主循环中做好异常处理。2. 在每次读取前可以尝试用pm.is_process_alive()检查进程是否存活。3. 使用调试器或打印语句逐步定位崩溃行。基地址每次重启都变这是正常现象。基地址是模块加载到内存的起始地址每次启动可能不同。我们使用的“模块名静态偏移”如MyTestGame.exe002A34D0中的002A34D0就是相对于模块基址的偏移是固定的。pymem会自动帮我们计算当前运行的模块基址。4.3 从基础修改到“AI”决策的扩展当前的脚本只是一个条件判断。真正的“AI”或自动化逻辑可以更复杂状态机驱动定义游戏角色的不同状态如“寻找敌人”、“攻击”、“拾取物品”、“回血”根据内存读取的坐标、血量、敌人信息等在不同状态间切换。class BotState: IDLE 0 MOVING 1 ATTACKING 2 PICKING 3 current_state BotState.IDLE while True: hp read_hp(pm) enemy_nearby check_enemy(pm) if hp danger_threshold: current_state BotState.IDLE # 触发回城或使用血瓶逻辑 elif enemy_nearby: current_state BotState.ATTACKING # ... 根据状态执行不同操作图像识别辅助当某些信息无法从内存获取时如任务提示、特定图标使用opencv进行模板匹配或OCR识别作为决策的输入。路径与行为规划结合游戏地图坐标实现自动寻路、打怪、完成任务序列的自动化。机器学习应用高级收集游戏状态数据内存值、屏幕截图和成功操作记录训练一个简单的模型来预测最佳操作。这属于更前沿的研究领域。4.4 最佳实践与重要警告仅用于授权环境与学习目的所有技术应应用于自己拥有完全控制权的程序如自己开发的程序、明确允许修改的单机游戏、CE教程程序。在在线游戏、商业软件上使用可能导致账号封禁、法律诉讼。注重代码健壮性内存操作极不稳定。务必进行全面的异常处理try-except检查指针有效性并加入适当的延迟time.sleep避免因循环过快导致游戏卡顿或脚本崩溃。模块化与配置化将指针偏移、扫描模式、关键地址等易变参数写在配置文件如JSON中与代码分离。这样当游戏更新导致地址变化时只需更新配置无需修改代码。理解原理而非复制代码本文示例代码是高度简化的。真实游戏中的数据结构可能复杂得多数组、链表、结构体。深入理解CE的“分析内存结构”功能学习汇编基础才能应对复杂情况。反作弊对抗是另一个维度现代游戏普遍采用强大的反作弊系统如 BattlEye EasyAntiCheat。它们会检测内存修改、调试器附加和异常API调用。绕过它们属于安全攻防范畴复杂度极高且法律风险巨大绝非初学者应涉足的领域。通过本课的学习你应该已经掌握了使用Python配合CE进行基础内存扫描与修改自动化的全流程。这项技术的核心价值在于理解软件运行机制和实现自动化测试请务必在合法合规的范围内运用这些知识。下一步你可以尝试分析更复杂的数据类型浮点数、字符串、数组或者结合图像识别库打造一个混合型的信息获取与自动化框架。
返回列表