yycmd 发表于 2021-2-14 15:47

植物大战僵尸CE实现阳光越用越多分析

论坛里面有很多分析教程写的相当好,这个帖子仅仅作为我个人的学习记录,有写错的地方希望大家指正,谢谢!

图文关系:图片在上,文字在下,先图后文字!





我用的是 1.2.0.1.73 版本。


我们正常打开游戏,到主界面或者进入游戏中都可以,我是在游戏选择模式界面。


打开CE(版本无所谓,我是CE6.7,这个大家都有吧,没有的话就去下载一个!),附加游戏!


我们回到游戏,我选择“冒险模式”,关卡2-7,大家自由选择。


游戏开始之后,我们要暂停游戏,可以看到系统送了我们50个阳光。


我们回到CE,扫描类型:精确数值,数值类型:4字节,输入阳光50,点击“首次扫描”。


扫描之后有很多结果,我们现在不知道到一个才是我们需要的地址,所以我们回到游戏让阳光增加或者减少。
显然因为是夜晚,不会产生阳光,所以我们不能增加,我们就尝试让它减少,也就是种一个植物,让阳光减少。
阳光从原来的50变成25,因为我种了一个小蘑菇,消耗了25个阳光,剩下25。


我们回到CE,输入游戏里面剩下的阳光 25,点击 再次扫描


此时我们经过再次扫描,剩下的这个就是我们想要的数据。


我们将搜索的数据拉到地下的列表中。


这样我们就将地址拉到我们的列表中了。


点击刚才拉到 列表中的数据,对着数据进行右键,找到右键的 “找出是什么改写了这个地址”,也可以用快捷键F6



选择“找出是什么改写了这个地址” 会弹出提示框,选择 YES ,就会出现一个空白的弹框。
我们使用 “找出是什么改写了这个地址” 目的是看看谁在游戏里面改了 258D3A70 地址的数据,
也就是说我们现在要回到游戏里面,增加或者减少阳光,看看到底是谁改变了 258D3A70 地址的数据。
由于之前我们调试的时候,游戏是暂停的,所以我们现在继续游戏,让阳光发生变化。


我们种了一个消耗0个阳光的小蘑菇,所以阳光还剩下25,也就是说,阳光没发生变化。
但是我们刚才 CE 的窗口却出现了一条记录,猜想程序里面剩余阳光应该是这样计算的:

公式:剩余阳光 = 总阳光 - 消耗阳光

总阳光:25
消耗阳光:0

代入公式:剩余阳光 = 25 - 0
即,剩余阳光 = 25 ,得出阳光不发生变化。


按图中所示,选中CE补货的记录,点击 显示反汇编程序。


我们得到了这样一个 反汇编程序窗口。

PlantsVsZombies.exe.text+32F86 - 89 B7 78550000      - mov ,esi

在 PlantsVsZombies.exe.text+32F86 这个地址,我们可以看到汇编指令 mov ,esi
通过百度我们得知 汇编指令 mov 是将右边的 值 赋值给左边,也就是将 esi 的值赋值给 edi + 5578 这个地址。
为什么我们肯定 edi + 5578 是地址呢?

[*]因为汇编中,中括号内数据指向的是地址。
[*]mov指令是将右边的数据赋值给左边,而执行这个指令就会 增加/减少我们的阳光,所以 edi + 5578 一定指向的是地址。

我们现在去验证一下,edi + 5578 到底是不是阳光的地址,而esi又是不是 剩余阳光。



我们按图中所示,打开当前这个指令的详细信息,我们这个时候关注两个蓝色的方框中的内容。

[*]第一个方框就是我们上面说的 mov指令 mov ,esi
[*]我们可以知道,EDI = 258CE4F8,ESI = 00000019
[*]由于我们说 EDI + 5578 是地址,所以我们要回到游戏中,看看 258CE4F8 + 5578 到底能不能得到 25



我们将 EDI + 5578 手动添加到 CE中,可以看到CE已经计算出来了,数据为25,我们现在已经验证了 EDI +5578 就是地址



已知 ESI = 00000019 ,我们打开计算器输入十六进制的19,刚好得到十进制的25,看来ESI也就是我们剩余阳光

回到最初的问题,我们想要阳光越勇越多,现在我们已经知道了edi + 5578 是阳光的地址,esi是剩余阳光,
那么问题来了,esi是怎么计算出来的呢?
现在回到反汇编程序窗口,鼠标滚轮向上滚动,我们看看在这之前 esi 发生了什么变化?


向上滚动一小段窗口之后,蓝色背景就是我们程序改变的阳光的位置,现在我们要看看这段程序到底发生了什么。

PlantsVsZombies.exe.text+32F70 - 56                  - push esi
PlantsVsZombies.exe.text+32F71 - 8B B7 78550000      - mov esi,
PlantsVsZombies.exe.text+32F77 - 8B D7               - mov edx,edi
PlantsVsZombies.exe.text+32F79 - E8 12FFFFFF         - call PlantsVsZombies.exe.text+32E90
PlantsVsZombies.exe.text+32F7E - 03 C6               - add eax,esi
PlantsVsZombies.exe.text+32F80 - 3B D8               - cmp ebx,eax
PlantsVsZombies.exe.text+32F82 - 7F 0C               - jg PlantsVsZombies.exe.text+32F90
PlantsVsZombies.exe.text+32F84 - 2B F3               - sub esi,ebx
PlantsVsZombies.exe.text+32F86 - 89 B7 78550000      - mov ,esi


这段代码翻译一下大概如下:

第一句:
PlantsVsZombies.exe.text+32F70 - 56 - push esi
再次百度,push 是压栈操作,将 esi 压栈,压得什么鬼,我们不知道,暂时不用管,等用的时候再分析 esi是什么

第二句:
PlantsVsZombies.exe.text+32F71 - 8B B7 78550000 - mov esi,
再次百度,我们知道 mov 是赋值命令,将 地址的数据赋值给 esi,也就是说 esi 的数据 = edi +5578 的数据,
刚才我们知道了,edi + 5578 的数据是 25 ,也就是 esi = 25 ,等于 将阳光的总数据 25 存放到了 esi 中

第三句:
PlantsVsZombies.exe.text+32F77 - 8B D7 - mov edx,edi
再次百度, mov 是赋值指令,edx = edi ,这个时候我们知道 edi 是个地址,所以 edx 也是地址
edi = 258CE4F8 ,也就是 edx = edi = 258CE4F8

第四句:
PlantsVsZombies.exe.text+32F79 - E8 12FFFFFF - call PlantsVsZombies.exe.text+32E90
再次百度,call 是函数调用指令,也就是说,通过 call 可以调用指定地址的 函数
CPU:我现在要进入 PlantsVsZombies.exe.text+32E90 地址的函数
我们因为没有分析 PlantsVsZombies.exe.text+32E90 地址的函数,所以也不知道里面发生了什么,所以也不用管它。

第五句:
PlantsVsZombies.exe.text+32F7E - 03 C6 - add eax,esi
再次百度,add 是加法指令,add eax,esi ,也就是 eax = eax + esi,这里我们知道 esi = 25 ,但是 eax 是多少呢?
我也不知道 eax 是多少,暂时也不用管它。

第六句和第七句:
PlantsVsZombies.exe.text+32F80 - 3B D8 - cmp ebx,eax
PlantsVsZombies.exe.text+32F82 - 7F 0C - jg PlantsVsZombies.exe.text+32F90
再次百度,我们把 cmp 和 jg查询,发现这两可以配合一起用。

cmp比较一下两个寄存器,jg判断寄存器比较结果。

也就是CPU:

[*]我先用 cmp 比较一下 ebx 和 eax 这两个东西,看看你们两个谁大谁小
[*]jg :如果 ebx 你比 eax 大,那么我就要让CPU这个大兄弟到 PlantsVsZombies.exe.text+32F90 地址去玩了,ebx 小于 eax 就让他继续执行 sub esi,ebx 以及之后的代码

很显然,我们的程序执行到了 PlantsVsZombies.exe.text+32F86 - 89 B7 78550000 - mov ,esi 这个位置,所以 ebx小于eax

第八句:
PlantsVsZombies.exe.text+32F84 - 2B F3 - sub esi,ebx
再次百度,sub 是减法指令,sub esi,ebx 等于 esi = esi - ebx

第九句:
PlantsVsZombies.exe.text+32F86 - 89 B7 78550000 - mov ,esi
再次百度,mov 是赋值指令,mov ,esi
等于将 esi 的数据 赋值到 edi + 5578 这个地址中。

第八句的 sub esi,ebx 不就是为了得到 esi 的最终数据吗?
换句话来说,我们把 sub 的减法指令换成加法指令,是不是就可以增加阳光呢?



于是我们再次百度,汇编加法指令,百度说 add是加法指令,用法是 add A,B
换成实际操作是 A = A +B

我们百度知道的 sub 是减法指令,用法师 sub A,B
换成实际操作是 A = A - B

也就是说,我们只要把PlantsVsZombies.exe.text+32F84 - 2B F3 - sub esi,ebx 位置的 sub 换成 add 好像就可以实现 阳光越用越多了。



说干就干,搞起来!! sub 改成 add ,点击确定。


改好之后,原来的 sub 变成了 add。现在我们去试试游戏里面阳光会不会越用越多。


我去游戏里面测试了一下,依次种了两个阳光菇一个土豆。
两个阳光姑 = 25 * 2 = 50
一个大喷菇 = 50 * 1 = 50
种植之前有 25 点阳光
即 25 + 50 + 50 = 125,也就是我们现在总共的阳光 125 ,到这里我们阳光越用越多效果就实现了。

教程讲的很长,希望你不要觉得我啰嗦,这里把自己逆向分析的过程完全还原出来。

希望和我一样的萌新玩家能够看懂,不明白的地方,我尽量再讲细一点。

如果那里讲的不对,希望大佬能够给出指正。

有需要游戏的我后面再想办法分享出来。

yycmd 发表于 2021-2-14 16:48

喵卡表鸽 发表于 2021-2-14 16:32
哦!原来如此!前面大部分我是否可以理解为,是在分析《植物大战僵尸》是如何实现种植物减阳光的;而最后则 ...

一样可以,不过换成 乘法可能会出现游戏崩溃的问题吧!
实际情况我也没测试,我猜应该会

yycmd 发表于 2021-2-16 00:58

cqnowind 发表于 2021-2-15 21:51
感觉和98呀xp上的GAMEMASTER 或者FPE是一个思路,我一般是锁定钱或者血槽,懒得改了。

锁定什么的就没意思了,咱们主要是学一下这个实现的思路,以及汇编层面又是如何修改的

皇乐 发表于 2021-2-14 16:11

666我一个小白竟然基本看懂了

7758520ph 发表于 2021-2-14 16:22

牛逼普拉斯!!

喵卡表鸽 发表于 2021-2-14 16:32

哦!原来如此!前面大部分我是否可以理解为,是在分析《植物大战僵尸》是如何实现种植物减阳光的;而最后则是把一个减法变成一个加法。那如果,我是说如果,有没有可能换成乘法呢?{:1_921:}
谢谢了,我竟然懂了!

王雪峰 发表于 2021-2-14 16:36

学习了,谢谢大神

seasonkaka 发表于 2021-2-14 16:40

这也行~~~~~~~~~~{:1_905:}

yycmd 发表于 2021-2-14 16:47

皇乐 发表于 2021-2-14 16:11
666我一个小白竟然基本看懂了

看懂了就好

yycmd 发表于 2021-2-14 16:49

seasonkaka 发表于 2021-2-14 16:40
这也行~~~~~~~~~~

学习到新技巧没有{:301_997:}

lyl610abc 发表于 2021-2-14 16:52

{:17_1068:}植物大战僵尸劳模实锤了,楼主写得很详细,支持一下
页: [1] 2 3 4 5 6 7 8
查看完整版本: 植物大战僵尸CE实现阳光越用越多分析