找出植物大战僵尸生产阳光call。
二、思路
以在《植物大战僵尸更改阳光产出速度》一文中找到的产出阳光计时数据为基础,猜测存在判断跳转语句如下:当产出阳光计时据为0时,跳转到生产阳光call。
三、实现
(一)CE找到产出阳光计时数据
步骤见
《植物大战僵尸更改阳光产出速度》,此处略 ,地址如下:
(二)OD分析
根据在CE中找到的地址,在OD命令行中输入“dd 1728FD00”,数据窗口中对此地址数据下硬件访问断点,运行游戏。断下:
00463418 FF4F 58 dec dword ptr [edi+58] ; 阳光间隔减法
0046341B 8B77 58 mov esi, dword ptr [edi+58]
0046341E 83FE 64 cmp esi, 64 ; 阳光间隔与64比较
00463421 7F 27 jg short 0046344A
上面代码将产出阳光计时数据减1,并与0x64进行比较,大于则跳至
0046344A。将
jg short 0046344A改为如下语句:
00463421 /EB 27 jmp short 0046344A
则向日葵产生阳光时由暗变亮的动画消失,但阳光正常产出,此处不是关键跳转。到
0046344A处看看:
0046344A 85F6 test esi, esi
0046344C 0F8F E5000000 jg 00463537
00463452 |8B47 5C mov eax, dword ptr [edi+5C]
00463455 |8DB0 6AFFFFFF lea esi, dword ptr [eax-96]
上面这段代码测试产出阳光计时数据是否为0,大于则跳转,将
0046344C处的跳转语句NOP掉,回到游戏,观察如下(自动拾取物品功能已开):
由此可知
0046344C 0F8F E5000000 jg 00463537
为关键跳转,当esi大于0时跳走,当esi等于0时顺序执行下面的语句产出阳光
,在此关键跳转的下一语句下断,当esi为0时会断在如下语句处:
00463452 |8B47 5C mov eax, dword ptr [edi+5C]
此时F8跟踪一下程序执行流程,整理出执行的跳转和call如下:
- 0046345F E8 3CBE1900 call 005FF2A0
- 00463473 E8 8836FFFF call 00456B00
- 0046347E /75 14 jnz short 00463494
- 0046349D /EB 46 jmp short 004634E5
- 004634F0 E8 0BBFFAFF call 0040F400
- 004634FE /75 37 jnz short 00463537
- 00463537 5E pop esi ; 0018FA08
- 00463538 C3 retn
分析生成阳光call,应该至少有地面横纵坐标两个参数,以此分析,很容易分辨出上面第5行的call是生成阳光call,具体如下:
004634E5 8B47 0C mov eax, dword ptr [edi+C]
004634E8 8B4F 08 mov ecx, dword ptr [edi+8]
004634EB 50 push eax ; 方格纵坐标
004634EC 51 push ecx ; 方格横坐标
004634ED 8B4F 04 mov ecx, dword ptr [edi+4]
004634F0 E8 0BBFFAFF call 0040F400 ; 生成阳光call
下面进行测试,上面跟踪程序流程中,可以发现在调用生产阳光call之前有许多参数入栈,经过分析,当部分入栈参数如下:
00463499 6A 02 push 2
0046349B 6A 04 push 4
时,将产出阳光,当部分入栈参数如下:
00463499 6A 01 push 1
0046349B 6A 03 push 3
时,将产出钻石,那么,种一棵向日葵,修改入栈参数:
00463499 6A 01 push 1
0046349B 6A 03 push 3
开启更改阳光产出速度,开启自动拾取物品,效果如下:
四、小结
大胆假设,小心求证。感谢各位支持,祝论坛越办越好。
ggsuper
2018.02.19