This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可证发布
文中的内容是 CE 的简介,和我前面的叙述内容差不多。
你需要做的就是在 CE 中点击那个闪闪发亮的进程选择按钮,选择 ????????-Tutorial-x86_64.exe 或者 ????????-Tutorial-i386.exe , x86_64 或者 i386 取决于你打开的是 32 位的教学程序还是 64 位的教学程序,前面的 8 位可能不一样,因为这个是进程 ID(PID),每次打开程序,系统会重新分配一个新的 PID。
通常,游戏只会有一个进程,某些游戏可能有两个进程,选哪个就要凭感觉了,你可以看看任务管理器,通常选择占用内存大的那一个,实在不行就两个都试一试(反正又玩不坏)。
Tutorial 右下角有一个输入密码的地方,之后每一关都会告诉你一个密码,在这里输入,就可以直接就跳到对应关卡了。
选择完之后可以看到主界面上面显示了当前选择的进程名。
现在点击 Tutorial 中的 Next 就可以了。
Step 2: Exact Value scanning (PW=090453)
第二关:精确值搜索(密码是 090453)。
这关重现了经典的打怪现场,你有 100 滴血,点击 Hit me 你会被怪打一下,然后你的血量就少了。(再然后,打着打着就像白学家一样被打死了←_←,不过 Tutorial 会给你一条新的生命的。实际游戏中通常不会有这种好事,开始一次新的搜索吧)
你需要做的是:把它改成 1000。
很简单,在CE中输入 100,点击 First scan。
然后让怪打自己一下(点击 Hit me),输入新的数值(比如说 96),然后点击 Next scan。
现在基本就剩1个地址了,不行就再打一下,再搜一次。
然后双击地址列表中的值(或者选中然后点击右下箭头),添加到下方 Cheat Table 中。
然后双击 Value 部分,改成 1000。
可以看到原来不可以点击的 Next 现在已经可以点击了,点击 Next 进入下一关。
现在想想,这个是什么原理呢?
首先你需要开始一次新的搜索,点击 New scan。
然后在 Scan Type 中选择 Unknown initial value(未知初始值),点击 First scan。
因为是未知初始值,所以第一次搜索之后列表中什么也不会显示,因为显示什么也没有用,毕竟未知初始值没什么意义。同时左上角的 Found 显示找到的数值非常多,未知初始值就是把内存中所有数值都保存下来,所以非常多,所以最好不要使用未知初始值这个东西。
然后打自己一下,在CE中选择 Decreased value by ...(数值减少了...),将减少的数值输进去,比如 Tutorial 中显示 -9 则输入 9,点击 Next scan。
这时列表可能不止一个数值,我们重复上述操作,再打一次,把减少的血量输入到CE中,再搜索一次。
搜索了几次还是剩这么几个地址,我果断就把其他几个忽略了,把两百左右那个添加到 Cheat Table中,改成 5000,有时候还是需要一些主观因素的。
好了,可以 Next 了。
课外拓展
除了改一下 Value Type 其他和第二关完全一样。
把 Value Type 改成 Float 搜索并修改生命值,改成 Double 搜索并修改弹药。
然后点击 Next。
说明
通常游戏中为了计算速度会选择 Float 类型,至于游戏开发者或游戏框架会选择什么类型谁也不清楚,靠自己瞎猜吧,一个一个试,实在不行就把 Value Type 改成 All 吧。
Step 5: Code finder (PW=888899)
第五关:代码查找器
通常,储存数据的地址不是固定不变的,每一次重启游戏通常都会变动,甚至在你玩游戏的过程中地址都有可能改变。为此,我们有两个方法,这一关讲解使用代码查找的方法。
每一次点击 Change value 数值都会改变。
你需要做的是:让其不再改变。
首先,用第二关的方法,找到这个数值的地址,添加到 Cheat Table 中。
然后,右键点击这个地址,选择 Find out what writes to this address。
这时会弹出一个提示框,“这个操作会将 Cheat Engine 的调试器附加到指定进程中,是否继续?”
选择“是”即可。(你可以试试选“否”会怎样。随便尝试嘛,反正电脑又不是 Samsung Galaxy Note 7,又不会因为这点小事而爆炸。不过试了之后你会发现什么都没发生...因为选“否”就是不继续进行任何操作了。)
这时就会弹出一个新的窗口“下列操作指令写入了xxxxxxxx”
现在,点一下 Change value 就会发现,CE 发现了一条指令改写了当前地址。
选中这条指令,点击 Replace 按钮,想起个名字就给他起个名字,不想起就直接 OK 就行了。
当然,右键这条指令,选择 Replace with code that does nothing (NOP) 也可以。
这时再点 Change value,就会发现 Next 可以点击了。
如果你能以足够快的方式锁定这个数值,也是可以的过关的。
说明
这一关,我们到底做了些什么?
找出改写当前地址的操作
首先,找出改写当前地址的操作,这个是调试器的一个功能,所以必须先把调试附加到指定进程(这个附加操作可能被检测到,网络游戏需要过非法)
找出改写当前地址的操作,其实是设了一个内存断点,每次有指令改写这个内存,都会使目标进程中断在改写指令之后(为什么是之后,这个是CPU所决定的,没办法),然后 CE 会自动记录这条地址,并储存寄存器信息,然后继续运行程序。
可以尝试,右键这个地址选择 Browse this memory region 查看这块内存区域。
可以看到当前地址用深绿色表示,证明有断点存在
这个操作的过程还是很耗资源的,虽然现在的PC已经完全不在话下了,但是还是在用完即使点 Stop 按钮,取消这个断点,结束这一系列操作。
点击 Stop 之后,绿色表示的断点就会消失。
将代码替换为什么也不做
程序运行时的指令与数据都是储存在内存中的,将指令替换为什么都不做(通常称为:NOP 掉这条指令。NOP 就是 No operation 的意思,CPU遇到这条指令就是什么都不做,直接执行下一条指令。NOP对应的机器码为 0x90,16进制的90),就是将指定的内存区域全部改成 90,可以先使用 Show diassembler 查看指定区域的反汇编,然后再点 Replace 看看那条指令的变化。
替换成什么也不做之后,这个地址就不会再改变了,其他指令使用这个地址时就一直是同一个值了。
代码列表
你懂的,先用第二关的方法把血量的地址找到,然后添加到 Cheat Table 中。再用第六关的方法搜索指针,不过这次你发现,搜索到的地址不是绿色的基址了,这就需要我们再继续搜索上一级指针。
将这个地址添加到下方,然后使用 Find out what accesses this address,注意是 accesses 而不是 writes。
然后点击 Change value 会收集到两条指令,cmp 指令跟指针没什么关系,对我们有用的是第二条指令 mov esi,[esi]。
不过问题来了,我们发现,这里提示的地址和上一次提示的地址是一样的,这是为什么呢?
CE 默认使用硬件断点的方式,断点只能停在指令执行之后,而这条指令正好是把 esi 原来指向的地址中的值再赋值给 esi,所以执行之后 esi 的值已经是被覆盖掉的值了,而我们想知道的恰恰是执行这条指令之前的 esi 值,那么怎么办呢。
方法一:秀操作
我们可以手动在当前指令的前一条指令下断点...(陈独秀同志,请你坐下)
方法二:动一动脑子
我们的 Find out what accesses this address 是干什么的?查找访问这个地址的指令,然后我们又发现了 mov esi,[esi] 这条指令访问了这个地址,那么 [esi] 原来是啥?原来的 esi 不就是这个我们监视的地址嘛。
所以直接搜索这个地址即可。
将这个地址添加到下方,然后使用 Find out what accesses this address,再来一遍。
和上一步一样,不在赘述。
不过这次我们搜索到了两个指针,用哪个呢?通常的话选第一个就可以了,不过这个也不一定,大不了再把第二个也试一下嘛。
真不巧,还真是第二个...
现在我们来整理一下
我们可以借用汇编语言的指针表示方法来表示一下我们需要的内存地址
[[[["Tutorial-i386.exe"+1FD660]+0C]+14]+00]+18
把基址(一级指针) "Tutorial-i386.exe"+1FD660 的值取出来,加上一级偏移 0C,当做地址,这是二级指针的地址,再把二级指针的值取出来,加上 14,这是三级指针的地址,依次类推。
然后就来手动添加地址
把刚添加的条目改成5000,然后锁定
点击 Change pointer 然后就可以点击 Next 了。
注意