继续分析植物大战僵尸,第四篇,这次的目标是植物无CD效果。
准备
- 系统:Windows 10 x64 专业版
- 软件:植物大战僵尸中文版
- 工具:CheatEngine v6.8.2、吾爱破解专用版OllyDbg
- 目标:植物无CD
分析
整理思路。
在游戏中多次实验可以发现,当点击植物卡片时,会触发两种情况,一种是装填完毕,一种是未装填完毕。
猜测游戏中对植物装填状态有一个判断,而且是发生在点击植物卡片之后,所以,目标可以分为两个部分:
进行分析。
1. 寻找植物卡片点击事件
第一个目标,可以将第三篇的植物种植函数来作为切入点。
搜索当前阳光存储地址,找出减少阳光值指令。
单步执行出种植函数。
004121FE |. 8B4D 0C mov ecx,[arg.2] ; kernel32.772887DD
00412201 |. 8B55 08 mov edx,[arg.1]
00412204 |. 51 push ecx
00412205 |. 52 push edx
00412206 |. 57 push edi
00412207 |. 8BCB mov ecx,ebx
00412209 |. E8 22DBFFFF call Plants_v.0040FD30 ; 0x0040FD30-种植植物函数
0041220E |. E8 0DC3FFFF call Plants_v.0040E520
00412213 |. 5F pop edi ; 0019FD00
00412214 |. 5E pop esi ; 0019FD00
00412215 |. 5B pop ebx ; 0019FD00
00412216 |. 8BE5 mov esp,ebp
00412218 |. 5D pop ebp ; 0019FD00
00412219 |. C2 0C00 retn 0xC
向上找到函数头部,下断,就可以发现该函数就是植物卡片点击事件处理函数。
2. 寻找植物装填状态判断
点击植物分为可种植和不可种植两种状态,所以从种植函数开始逆向分析点击事件处理函数。
种植函数上方就是一个判断跳转,简单分析可以猜测其功能是判断本次点击是否为放下植物。
004121F3 |. 8BC7 mov eax,edi
004121F5 |. E8 E6AAFFFF call Plants_v.0040CCE0 ; 猜测-判断本次鼠标点击是否为放下植物
004121FA |. 84C0 test al,al
004121FC |. 74 1E je short Plants_v.0041221C
而且可以发现,无论植物是否装填完毕,都会运行到该函数位置。
对该函数的参数与返回结果进行比较分析。
确定无论是否装填完毕,同一植物情况下参数与返回结果都相同。
所以装填状态判断还在后面,继续单步分析。
跳转后出现两个函数,
0041221C |> \83FA 04 cmp edx,0x4 ; Switch (cases 1..F)
0041221F |. 75 28 jnz short Plants_v.00412249
00412221 |. 8B4424 10 mov eax,dword ptr ss:[esp+0x10] ; Case 4 of switch 0041221C
00412225 |. 8B48 04 mov ecx,dword ptr ds:[eax+0x4]
00412228 |. 80B9 64010000>cmp byte ptr ds:[ecx+0x164],0x0
0041222F |. 0F85 EB000000 jnz Plants_v.00412320
00412235 |. 50 push eax
00412236 |. E8 55630700 call Plants_v.00488590 ; 冷却判断函数
0041223B |. E8 E0C2FFFF call Plants_v.0040E520
00412240 |. 5F pop edi ; 0019FD00
00412241 |. 5E pop esi ; 0019FD00
00412242 |. 5B pop ebx ; 0019FD00
00412243 |. 8BE5 mov esp,ebp
00412245 |. 5D pop ebp ; 0019FD00
00412246 |. C2 0C00 retn 0xC
同样对齐进行参数比较后,发现 0x00488590 函数的参数与返回结果出现了变化。
以向日葵为对象(左为装填完毕,右为装填中)。
参数比较:
返回结果比较:
修改执行后的eax返回值,发现在装填状态下可以种植植物,确定该函数就是装填状态判断函数。
F7进入分析,确定关键跳转位置。
00488684 |. 807D 48 00 cmp byte ptr ss:[ebp+0x48],0x0 ; 冷却判断
00488688 |. 0F85 79010000 jnz Plants_v.00488807 ; 成功跳转
猜测 [ebp+0x48] 指向的内存地址为装填状态标志,0x00为装填中,0x01为装填完毕。
在标志上下内存写入断点,运行游戏,确定标志设置指令。
设置为装填中。
00488E71 |> \33C0 xor eax,eax ; Default case of switch 00488E3B
00488E73 |. C645 48 00 mov byte ptr ss:[ebp+0x48],0x0 ; 修改装填标志为装填中
00488E77 |. 8945 24 mov [arg.8],eax
00488E7A |. 8945 28 mov [arg.9],eax
设置为装填完毕。
00487298 |. C747 24 00000>mov dword ptr ds:[edi+0x24],0x0
0048729F |. C647 49 00 mov byte ptr ds:[edi+0x49],0x0
004872A3 |. C647 48 01 mov byte ptr ds:[edi+0x48],0x1 ; 设置装填标志为装填完毕
004872A7 |. E8 E4FEFFFF call Plants_v.00487190
004872AC |> 8B47 3C mov eax,dword ptr ds:[edi+0x3C]
分析完毕,只需要将设置为装填中的指令,修改为设置为装填完毕,即可实现植物无CD的目标。
效果如图: