ReadProcessMemory和WriteProcessMemory是Windows下跨进程内存读写的直接API,但需权限、架构匹配、地址有效且常受反调试保护。

Windows 下用 ReadProcessMemory 和 WriteProcessMemory 读写目标进程内存
这两个 API 是 Windows 平台实现跨进程内存操作最直接的手段,但前提是你的进程有对应权限。它们不处理地址转换、页保护或 ASLR 偏移,只是“裸”读写——你给什么地址,它就去读什么地址(如果能访问的话)。
常见错误现象:ReadProcessMemory 返回 FALSE,GetLastError() 返回 ERROR_ACCESS_DENIED(权限不足)或 ERROR_PARTIAL_COPY(目标地址不可读/被保护)。
- 必须先用
OpenProcess获取目标进程句柄,且至少带PROCESS_VM_READ(读)或PROCESS_VM_WRITE(写)标志;PROCESS_ALL_ACCESS在现代系统上基本拿不到,别硬试 - 目标进程如果是 64 位,而你的外挂是 32 位(或反之),
ReadProcessMemory会失败——架构必须匹配,否则连句柄都打不开 - 拿到的地址通常是模块基址 + 偏移(比如
game.exe+0x1A2B3C),但每次游戏重启、更新、甚至开不同存档,这个偏移都可能变;不能硬编码 - 读写前建议用
VirtualQueryEx检查目标地址内存状态,避开MEM_FREE或PAGE_NOACCESS区域,避免触发异常
如何定位游戏里某个变量的真实地址(比如血量、金币)
没有“自动找地址”的银弹,本质是靠内存扫描 + 行为观察缩小范围。工具(如 Cheat Engine)只是把这过程图形化了,底层逻辑一样:改值 → 扫描变化 → 缩小候选集 → 验证指针链。
容易踩的坑:int 类型血量可能被拆成多个字节分散存储,或用浮点数模拟整数;更常见的是“显示值 ≠ 内存值”,比如血量实际存的是百分比乘以 1000 的整数,UI 层再除回去。
立即学习“C++免费学习笔记(深入)”;
- 不要只扫一次数值;先记录初始值(比如 100),受击后扫“减小的值”,回血后扫“增大的值”,反复几次能筛掉大量静态干扰项
- 很多关键数据藏在动态分配的堆内存里,地址每次启动都变;得顺着已知模块导出函数或全局变量,用
GetModuleInformation算出基址,再结合 IDA/ReClass 找到相对偏移和指针层级 - 64 位游戏常用 RIP-relative 寻址,偏移可能是负数;反汇编时注意
lea rax, [rip + 0x123456]这类指令,算地址别漏符号位
C++ 外挂代码里为什么总要调 SetPrivilege 提权
因为默认情况下,普通用户进程只能打开同级进程(相同完整性级别)的句柄。游戏若以“高完整性”运行(比如管理员启动、或开启了 UAC 保护),你的外挂即使以管理员运行,也得显式申请 SeDebugPrivilege 权限才能调 OpenProcess。
不提权的典型表现:OpenProcess 返回 NULL,GetLastError() 是 ERROR_ACCESS_DENIED,但你明明开了管理员。
-
SeDebugPrivilege不是“永久生效”,每次进程启动都要重新启用;必须在OpenProcess前调用AdjustTokenPrivileges - 32 位外挂在 64 位系统上调用
OpenProcess打开 64 位游戏时,即使提权成功,仍可能因 WOW64 限制失败;稳妥做法是保持架构一致 - 部分安全软件会 Hook 或拦截
SeDebugPrivilege启用行为,不是所有提权都能过检测;有些游戏还会主动检查自身 token 是否被篡改
读写内存时怎么绕过基础反调试/内存保护
绕不过。至少不能只靠 ReadProcessMemory 就搞定。现代游戏普遍用以下一种或多种防护:
- 内存页设为
PAGE_GUARD或PAGE_NOACCESS,读写会触发异常;你得先VirtualProtectEx改权限,操作完再恢复——但频繁改权限本身就很可疑 - 关键数据加密存储,每次读取前解密,写入后加密;你读到的可能是密文,直接改会崩逻辑
- 用硬件断点监控特定地址,或用
SetThreadContext注入线程执行校验代码;你一动内存,它立刻发现并退出 - 驱动级保护(如 Easy Anti-Cheat、BattlEye)会过滤
ReadProcessMemory调用,甚至让 API 直接返回假数据;用户态代码对此无解
真正难的从来不是“怎么读”,而是“读到的是否可信”、“改了之后程序会不会当场崩溃或封号”。地址漂移、数据混淆、多层指针、运行时校验——这些才是卡住绝大多数人的地方。











