|
本次帖子中实现的思路是通过上一次的实现自动收集阳光的关键跳转的地方想到并实现的
上篇地址:植物大战僵尸自动收集阳光&金币
https://www.52pojie.cn/thread-1001645-1-1.html
一.天上无限掉落金币
1.思路
接着上回实现自动收集中,在最初的调试中,以为那个关键跳转前的比较是一个标志的判断,给那个地址赋值0代表点击植物,值1代表点击阳光。但是多数情况点击植物不会下断,调试中发现,当马上要出现一个阳光时,会赋值0。那么我们是不是可以通过这个地址找到产生阳光的地方,并且做些什么呢?
2.天上掉落阳光的寻找
产生阳光有两种情况,第一是天上掉落阳光,第二是太阳花产生阳光。我们先说第一种掉落。找到实现自动收集的那个跳转,在上面的比较处的第一个地址下一个内存写入断点,回到游戏中等待,当马上掉落一个阳光的时候,会给这个地址赋值0。
在天上即将掉落阳光的时候会断下来
执行出去,在刚才出来的call上面,并没有看到任何判断跳转,并且代码也不多。天上掉落阳光应该是有一个计时器,到达时间之后就会掉落一个阳光,这里没有这些特征,所以我们继续执行出去。
执行出来后,往上面翻一翻,看到许多的判断和跳转,同时在上面不多的地方,0041FC53处给一个地址加了-1,也就减一,这里会不会就是掉落阳光的计时器呢?
在这里下断,将这个地址中的值修改为1(下面是JNZ跳转,减一之后刚好为0,不会跳转),回到游戏中发现马上掉落一个阳光。说明此处就是掉落阳光的计时器了。
大致看一下计算的过程,41FC5A处和41FC90处调用的是同一个函数,它是一个计算,会计算并返回一个值,每次计算出的值都不一样。esi+0x5554中存储的是掉落的阳光的总数。
a=阳光掉落总数+阳光掉落总数*4
a=a*2+0x1A9
判断a是否大于0x3B6,如果大的话,最后a只能等于0x3B6,也就是a最大为0x3B6。41FC90处的call返回一个值,这个值加上a就是我们下次掉落计时器的数值。通过查看41FCC1处的掉落阳光call传入的几个参数,发现edi其实是掉落阳光的位置,如果修改为上一次的值,那么阳光会掉落在同一个地方。edi的值是通过第一次的计算返回值加上0x64获得的。
[Asm] 纯文本查看 复制代码0041FC55 |. 68 26020000 push 0x2260041FC5A |. E8 61F01C00 call PlantsVs.005EECC0 ; 返回一个初值参与计算0041FC5F |. FF86 54550000 inc dword ptr ds:[esi+0x5554] ; 阳光的总数量0041FC65 |. 8BF8 mov edi,eax0041FC67 |. 8B86 54550000 mov eax,dword ptr ds:[esi+0x5554]0041FC6D |. 8D0480 lea eax,dword ptr ds:[eax+eax*4]0041FC70 |. 8D8400 A90100>lea eax,dword ptr ds:[eax+eax+0x1A9]0041FC77 |. 83C4 04 add esp,0x40041FC7A |. 83C7 64 add edi,0x640041FC7D |. 3D B6030000 cmp eax,0x3B60041FC82 |. BB B6030000 mov ebx,0x3B60041FC87 |. 7F 02 jg short PlantsVs.0041FC8B0041FC89 |. 8BD8 mov ebx,eax0041FC8B |> 68 13010000 push 0x1130041FC90 |. E8 2BF01C00 call PlantsVs.005EECC00041FC95 |. 8B8E A4000000 mov ecx,dword ptr ds:[esi+0xA4]0041FC9B |. 03C3 add eax,ebx0041FC9D |. 8986 50550000 mov dword ptr ds:[esi+0x5550],eax ; 计算后的数值重写进地址0041FCA3 |. 83C4 04 add esp,0x40041FCA6 |. 83B9 1C090000>cmp dword ptr ds:[ecx+0x91C],0x250041FCAD B8 04000000 mov eax,0x40041FCB2 |. 75 05 jnz short PlantsVs.0041FCB90041FCB4 |. B8 06000000 mov eax,0x60041FCB9 |> 6A 00 push 0x00041FCBB |. 50 push eax ; 标志0041FCBC |. 6A 3C push 0x3C0041FCBE |. 57 push edi ; 下落地点0041FCBF |. 8BCE mov ecx,esi0041FCC1 |. E8 9A8BFFFF call PlantsVs.00418860 ; 掉落阳光函数
3.无限掉落阳光的实现
修改就很容易了,将41FC53处的JNZ nop掉,不管当前计时器什么情况都顺序执行。效果还是挺疯狂的,不配合自动收集的话,一会全屏幕就会铺满阳光。
4.疯狂掉落
上一次的自动收集中在最后增加那里说道,通过判断几个数字来决定增加的金币还是阳光。在调试过程中,看到最后的掉落阳光call传入的几个参数中eax的值是4,这正是之前分析过得代表着大阳光的值,那么这里会不会也是一个标志呢,修改后会不会掉落别的东西?
将当前寄存器中的值修改为1,回到游戏中可以发现掉落一个银币,证明了我们的猜想。
看一下eax的值是哪里给的,之后修改这里,就可以达到我们的目的了。往上41FCAD处给eax赋值,我们修改这里就可以了。
看下修改后的效果,把0x4改为0x3(0x3代表钻石),可以掉落钻石,满屏幕都是钻石。
二.太阳花无限产生阳光&金币
1.思路
第二种产生阳光的途径是太阳花产生。还是之前的那个地址,当天上掉落的阳光的时候会断下来赋值0,太阳花产生阳光的时候也会赋值0,但是在天上掉落阳光的那里并没有找到太阳花产生阳光的函数之类的。也就是应该是不同的函数,那么太阳花是不是也可以实现刚才实现的这些呢?
2.寻找
继续在那个给地址赋值0的地方下断,回到游戏中种植一个太阳花,当太阳花要产生阳光的时候会断下来。
还是像之前一样执行出去,直到这里,可以看到上面有许多的判断跳转,可以在头部下断单步执行看一下,可以在46DE18处看到给一个每次减一,继续走看到46DE4A处有一个test指令,我们知道test一般可以用来检查寄存器是否为空,猜测这里就是太阳花产生阳光的计时器了。再往下是一些计算的过程,用来计算下一次太阳花的计时器。
在游戏中种植一个太阳花,修改这里为1,回到游戏可以看到太阳花马上产生了一个阳光。
3.无限产生阳光
直接修改test下一条的JG,把它nop掉即可。可以看到太阳花变成了一个喷泉,一直往外喷太阳。
4.无限产生金币
有了天上掉落的经验,那么太阳花是不是也有一个标志,也可以实现产生金币这些呢?继续调试,发现在太阳花产生阳光的函数这的几个寄存器的值都不是0x4。进去函数里面看看。
进去后发现,还是用到了0x4的,只是这个值不在寄存器中,而是在栈里,那么就到外面去找,是哪里把这个值压入栈了。
在这个jmp前看到push 0x4,直接修改这里就可以了。
改为0x2(代表金币),可以看到太阳花变成了金币喷泉。
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|