使用Python从exe程序获取信息,内存读取/注入及Cheat Engine定位问题求解
动态内存变量定位与提取解决方案
1. 无精确值场景下的Cheat Engine定位流程
不需要提前知道目标字段的精确值也可以完成地址定位,按以下步骤操作即可:
- 首次扫描时选择扫描类型为 未知的初始值,数值类型暂选 所有类型 覆盖所有可能的变量格式,执行首轮全内存扫描
- 手动触发目标字段的数值变化:比如要提取的是程序内的计数、状态、属性值,操作程序让该字段对应数值增加、减少或切换状态
- 每次字段变化后,将CE的扫描类型切换为 变动的数值 执行增量扫描,字段无变化时选择 未变动的数值 过滤无关结果,重复3-7次后扫描结果会收敛到10个以内
- 对剩余的候选地址逐一做修改验证:在CE内修改地址对应的数值,切回目标程序查看对应字段是否同步变更,即可确认目标动态地址
- 确认动态地址后,使用CE的 指针扫描 功能生成静态基址+多级偏移的地址表达式,只要程序版本不更新,该表达式可以稳定计算出每次启动后的动态地址,无需重复扫描
- 若目标程序带反调试机制,扫描前先开启CE的反调试绕过选项,避免程序崩溃或扫描被拦截
2. 无需注入的内存读取实现
拿到静态基址+偏移组合后,无需注入即可跨进程读取变量值,Windows平台核心API调用逻辑如下:
- 先通过进程名获取目标进程ID,调用
OpenProcess接口传入PROCESS_VM_READ权限获取进程句柄 - 通过基址+多级偏移计算得到当前运行时的动态内存地址
- 调用
ReadProcessMemory接口直接读取对应地址的变量值 - 核心C++代码片段参考:
#include <windows.h> #include <iostream> int main() { DWORD pid = 0; // 替换为实际目标进程ID uintptr_t baseAddr = 0x00400000; // 替换为CE扫描得到的静态基址 int offset = 0x1A; // 替换为实际偏移值 int targetValue = 0; HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pid); if (hProcess == NULL) { std::cout << "进程打开失败" << std::endl; return 1; } uintptr_t dynamicAddr = baseAddr + offset; // 多偏移场景按顺序逐级读取即可:dynamicAddr = *(uintptr_t*)(baseAddr + offset1) + offset2; ReadProcessMemory(hProcess, (LPCVOID)dynamicAddr, &targetValue, sizeof(targetValue), NULL); std::cout << "读取到的目标值:" << targetValue << std::endl; CloseHandle(hProcess); return 0; }
3. 注入方案的极简实现
如果目标变量仅存在于程序运行时的寄存器或加密内存中,跨进程读取不到时再使用注入方案:
- 优先使用DLL注入方式,注入后代码运行在目标进程的地址空间内,无需跨进程读取权限
- 已经通过CE确认地址表达式的情况下,注入的DLL中直接按表达式计算地址并取值即可,不需要额外编写Hook逻辑
内容的提问来源于stack exchange,提问作者Jaan Kannel
相关产品推荐
相关产品推荐

