8、寻找游戏基址:什么是基址、为什么需要基址、使用 Cheat Engine 的“找出是什么改写了这个地址”功能、动态地址与静态地址
好,咱们进入第八章。这一章可以说是整个逆向工程的基石——基址。
你可能已经遇到过这种情况:用 Cheat Engine 搜到了血量地址,改得很爽。但游戏一重启,地址变了,血量的值也找不到了。是不是很崩溃?
嗯,这就是动态地址在搞鬼。而基址,就是解决这个问题的钥匙。
什么是基址?
说白了,基址就是一个不会变的地址。它由程序加载时由操作系统分配,但一旦分配好,在整个游戏运行期间都保持不变。
我习惯把基址比作「房子的地基」。你装修房子(修改数据),墙可以拆、门可以换,但地基不动。基址就是那个地基。
举个例子:
静态地址(基址):0x004A1F2C → 每次启动都不变
动态地址:0x0A3F4B20 → 每次启动都可能变
在 Cheat Engine 里,基址通常显示为绿色。绿色的地址,就是静态地址。
为什么需要基址?
我刚开始做逆向时,觉得动态地址也能用啊,改完就完事了。直到有一次,我写了一个自动修改脚本,结果游戏更新后所有地址全废了。那叫一个惨。
基址的核心价值在于:
- 持久性:游戏重启后,基址依然有效
- 通用性:同一版本的游戏,基址在不同电脑上相同
- 稳定性:基址不会因为游戏场景切换而改变
- 可移植性:写 CT 文件或修改器时,只需要基址+偏移量
核心原则:所有动态地址,最终都能通过「基址 + 偏移量」的方式找到。这是逆向工程的黄金法则。
动态地址与静态地址
这两个概念必须分清楚。我见过不少新手在这上面栽跟头。
| 特性 | 静态地址(基址) | 动态地址 |
|---|---|---|
| 稳定性 | 每次启动不变 | 每次启动可能变 |
| 颜色(CE中) | 绿色 | 黑色 |
| 存储位置 | 代码段(.text)或数据段(.data) | 堆(heap)或栈(stack) |
| 修改方式 | 直接修改 | 需通过指针访问 |
| 适用场景 | 全局变量、常量 | 临时变量、动态分配的对象 |
为什么会这样?因为游戏引擎为了管理内存,会把大部分数据动态分配。比如你的血量,每次进游戏可能分配在不同的堆地址上。但指向这个堆地址的指针,往往存储在静态区。
说白了,我们要找的基址,就是那个「指向动态地址的静态指针」。
使用 Cheat Engine 的“找出是什么改写了这个地址”功能
这是 CE 最强大的功能之一。我个人觉得,学会这个功能,逆向水平直接上一个台阶。
操作步骤:
- 先找到你要修改的数据的动态地址(比如血量)
- 右键该地址 → 选择「找出是什么改写了这个地址」
- CE 会开始监控这个地址的写入操作
- 回到游戏,让血量发生变化(比如挨打、吃药)
- CE 会捕获到一条汇编指令,例如:
mov [eax+0C], edx - 这条指令就是修改血量的代码
小技巧:捕获到的指令中,[eax+0C] 这种形式就是「基址+偏移量」的雏形。eax 里存的就是基址,0C 就是偏移量。
我曾经遇到过一个坑:游戏用了多线程,血量被多个线程同时修改。CE 捕获到的指令有十几条。这时候不要慌,一条一条看,找到真正写入数值的那条。通常带有 mov 或 add 指令的就是。
从动态地址到基址的完整流程
咱们用一张图来理清整个逻辑:
这张图展示了完整的逆向流程。你想想看,从动态地址出发,一步步向上追踪,最终找到那个绿色的基址。这个过程就像剥洋葱,一层一层剥开。
实战:用 CE 追踪基址
咱们用一个经典例子来演示。假设你要找「玩家血量」的基址。
第一步:找到动态地址
扫描血量数值,找到当前地址。假设是 0x0A3F4B20。
第二步:找出改写
右键 → 「找出是什么改写了这个地址」。挨打一下,CE 捕获到:
mov [eax+0C], edx
第三步:查看 eax 的值
在 CE 的寄存器面板里,看到 eax = 0x0A3F4B14。注意,这个值也是动态的。
第四步:找出 eax 的来源
右键 eax 的地址 → 「找出是什么改写了这个地址」。重复这个过程。
最终,你会找到一个绿色的地址,比如 0x004A1F2C。这就是基址。
注意:指针链可能很长,有的游戏有 5-6 层甚至更多。我曾经追踪过一个网游的坐标,指针链长达 8 层。耐心是关键。
指针扫描:批量找基址
手动追踪太慢?CE 提供了「指针扫描」功能。我个人习惯先用指针扫描扫一遍,再手动验证。
操作步骤:
- 找到动态地址后,右键 → 「指针扫描」
- 设置扫描参数(偏移量、层级深度等)
- 重启游戏,重新找到动态地址
- 再次指针扫描,对比两次结果
- 两次都出现的地址,就是基址
避坑指南:指针扫描结果中,绿色地址不一定都是基址。有些是模块基址(如 game.exe+0x1234),这种也是有效的。我一般优先选择带模块名的地址,因为它们更稳定。
基址的表示方式
在 CE 中,基址通常有两种表示方式:
方式一:绝对地址
0x004A1F2C
方式二:模块名+偏移
game.exe+0x1F2C
我个人更推荐第二种。因为如果游戏更新,模块基址可能会变,但偏移量通常不变。你只需要更新模块基址即可。
举个例子:
// 旧版本
game.exe+0x1F2C → 实际地址 0x004A1F2C
// 新版本(模块基址变了)
game.exe+0x1F2C → 实际地址 0x005B3F2C
看到了吗?偏移量 0x1F2C 没变,变的只是模块基址。这就是为什么 CT 文件里通常用「模块名+偏移」来保存地址。
总结
基址是逆向工程的基石。没有基址,你写的修改器就是一次性用品。有了基址,你才能做出真正可用的工具。
记住几个关键点:
- 绿色地址 = 静态地址 = 基址
- 黑色地址 = 动态地址 = 需要通过指针访问
- 「找出是什么改写了这个地址」是找基址的核心功能
- 指针扫描可以批量找基址,但需要手动验证
- 模块名+偏移 的表示方式更稳定
嗯,这一章的内容就到这。基址的概念不难,但需要多练。找个游戏,自己动手走一遍流程,比看十遍教程都管用。