|
|
Day 5 -- 谁动了我的血条:代码查找器的侦探之路
Cheat Engine 从入门到住院 · Day 5
前几天我们一直在找"数据"——血量存在哪个地址。今天换个角度:不找数据,找代码。
打个比方。你发现冰箱里的蛋糕少了一块,之前我们的做法是盯着蛋糕看它什么时候变小。但更聪明的做法是——在冰箱上装个摄像头,看看是谁来偷吃的。
CE 的"代码查找器"功能就是这个摄像头。它能告诉你:是哪一行代码在修改你的血量。
━━━━━━━━━━━━━━━━━━━━
本文你将学到
"Find out what writes to this address" 功能的使用
"Find out what accesses this address" 功能的使用
两者的区别和适用场景
如何用 NOP 指令让扣血代码失效
第一次看懂汇编指令
阅读时间:12 分钟 | 实操时间:25 分钟 | 难度:进阶
━━━━━━━━━━━━━━━━━━━━
CE Tutorial Step 5:找到改写血量的代码
进入 Step 5。和之前一样,有血量和 Hit me 按钮。
但这一步的任务不是改数值,而是:找到修改血量的代码,然后让它失效。
━━━━━━━━━━━━━━━━━━━━
第一步:先找到血量地址
这一步用之前学过的方法,快速找到血量的内存地址。应该已经轻车熟路了。
找到地址后,添加到下方的地址列表。
第二步:找到是谁在改这个地址
在地址列表中,右键点击血量地址,选择 "Find out what writes to this address"(找出什么代码写入了这个地址)。
CE 会弹出一个小窗口,标题类似"The following opcodes write to XXXXXXXX",目前是空的。
第三步:触发写入
回到 Tutorial,点击 Hit me。
回到 CE 的小窗口,你会看到列表里出现了一条记录,类似:
这就是游戏里"扣血"的那一行汇编指令。翻译成人话就是:
:移动(赋值)
:内存中 rbx 寄存器指向的地址加上偏移量 EC 的位置(就是血量的地址)
:一个寄存器,里面存着计算后的新血量值
整条指令的意思是:"把新计算出来的血量值,写入到血量的内存地址"。
第四步:替换为 NOP
选中这条指令,点击 "Replace" 按钮。
CE 会把这条指令替换成 NOP(No Operation,空操作)。NOP 的意思是"什么都不做"。
原来游戏每次执行到这里,会把新血量写入内存。现在变成了"什么都不做",血量就永远不会被修改了。
回到 Tutorial,点 Hit me。血量不动了。点 Next,Step 5 通关。
━━━━━━━━━━━━━━━━━━━━
两个侦探工具的区别
CE 提供了两个"监控"功能:
Find out what writes to this address
监控"谁在写入这个地址"——也就是谁在修改这个值。
用途:找到扣血、扣金币、减弹药的代码。
Find out what accesses this address
监控"谁在访问这个地址"——包括读取和写入。
用途:当你不确定是读还是写时使用。结果会更多(因为读取操作比写入频繁得多),但信息也更全面。
什么时候用哪个?
想让某个值不被修改 → 用 writes
想了解某个值被哪些代码使用 → 用 accesses
不确定时 → 先用 writes,如果没结果再用 accesses
━━━━━━━━━━━━━━━━━━━━
汇编指令速成
你不需要系统学汇编语言,但了解几个常见指令会帮助你理解 CE 显示的内容:
| 指令 | 含义 | 例子 |
|------|------|------|
| MOV | 赋值(移动数据) |把 eax 的值写入地址 |
| ADD | 加法 |给地址的值加 10 |
| SUB | 减法 |给地址的值减 5 |
| NOP | 空操作 | 什么都不做 |
| CMP | 比较 |比较 eax 和 0 |
| JE/JNE | 条件跳转 |如果相等就跳转 |
| PUSH/POP | 压栈/弹栈 | 保存/恢复寄存器的值 |
以及几个常见寄存器:
| 寄存器 | 用途 |
|--------|------|
| EAX/RAX | 通用寄存器,常用于返回值和计算 |
| EBX/RBX | 通用寄存器,常用作基地址指针 |
| ECX/RCX | 通用寄存器,常用于计数 |
| EDX/RDX | 通用寄存器 |
| ESP/RSP | 栈指针 |
| EBP/RBP | 基址指针 |
E 前缀是 32 位,R 前缀是 64 位。现代游戏大多是 64 位。
━━━━━━━━━━━━━━━━━━━━
NOP 的威力与风险
把代码替换成 NOP 是最简单粗暴的修改方式,但要注意:
NOP 的好处:
简单直接,一键搞定
效果立竿见影
不需要理解代码逻辑
NOP 的风险:
同一段代码可能被多个对象共用。比如扣血的代码不仅扣你的血,也扣敌人的血。你 NOP 掉之后,敌人也不掉血了。
可能破坏游戏逻辑。比如扣血代码里可能还有其他副作用(播放音效、触发事件),NOP 掉之后这些都没了。
第一个问题(共享代码)是 CE Tutorial Step 9 的主题,我们在 Day 9 会详细讲怎么解决。
━━━━━━━━━━━━━━━━━━━━
实战技巧:Replace vs 手动 NOP
CE 的 Replace 按钮会自动把指令替换成等长的 NOP 指令。但你也可以手动操作:
在代码查找器窗口中,选中指令,点击 "Show disassembler"
进入内存视图的反汇编界面
双击目标指令
把指令内容改成
手动操作更灵活,比如你可以只 NOP 掉部分指令,或者替换成其他指令(我们后面会学到)。
━━━━━━━━━━━━━━━━━━━━
常见问题
Q:NOP 之后游戏崩溃了怎么办?
A:关掉游戏重开就行。NOP 只修改了内存中的代码,不会改动游戏文件。重启游戏后一切恢复原状。如果你想持久化修改,需要其他方式(后面会讲)。
Q:代码查找器窗口里出现了多条指令,选哪个?
A:每条指令旁边会显示被执行的次数(Count)。次数多的通常是主要的写入操作。你也可以看指令本身:开头的是减法(扣血),开头的是赋值。
Q:NOP 和冻结数值有什么区别?
A:冻结是 CE 在后台不断把你设定的值写回去——游戏扣你的血,CE 再加回来,双方在拉锯。NOP 是直接让扣血代码失效,游戏根本不会执行扣血操作,从根源上解决问题。NOP 更优雅,但也更危险(因为改的是代码而不是数据)。
━━━━━━━━━━━━━━━━━━━━
小结
今天我们从"改数据"升级到了"改代码":
用代码查找器监控谁在修改某个地址
第一次看到游戏的汇编指令
用 NOP 让扣血代码失效
了解了 writes 和 accesses 两种监控方式的区别
这是一个质的飞跃。之前我们是被动地修改数值(改了还会被游戏覆盖),现在我们可以直接修改游戏的行为逻辑。
但还有一个问题没解决:地址每次重启游戏都会变。今天你辛辛苦苦找到的血量地址,关掉游戏再开,血量可能跑到去了。
明天 Day 6,我们要解决这个问题——通过指针找到数据的"永久住址"。 |
|