首页
社区
课程
招聘
[原创]通过DLL注入魔改植物大战僵尸(2)——僵尸篇
发表于: 2020-12-19 13:11 6038

[原创]通过DLL注入魔改植物大战僵尸(2)——僵尸篇

2020-12-19 13:11
6038

上一篇文章为我们的魔改打下了基本框架,接下来我们就在这个框架上对功能进行扩展。这篇文章研究如何魔改僵尸,不要忘了我们的最终目标是仿制PVZ95版的功能噢,所以在僵尸篇我们主要打算实现下面几个功能:

通过DLL注入魔改植物大战僵尸(1)——准备工作
GitHub仓库

根据吾爱破解上一些帖子提供的思路,我通过扫描存活僵尸数量得到了两处关键指令,一处是减少存活僵尸数量,另一处是增加存活僵尸数量。显然我们要研究生成僵尸的过程,得从增加存活僵尸数量的指令着手。

IDA查看0x0041DE07处的汇编,eax看来是这一波生成僵尸的数量,然而我们发现上方的 mov eax, 1 指令已经把eax的值设为1了,动调调试也发现修改eax的值并没有什么作用。

retn 处下断点,动态调试查看这个函数的返回地址,意外发现PVZ在加载关卡时就触发了断点,返回地址是0x0040DE0B,猜测是预先设置好本关卡要生成的僵尸。但我们先不管这个,因为我们现在要研究的是如何在关卡中生成僵尸。

继续动调,进入关卡等待第一波僵尸生成,发现还是同一个返回地址(因为我在写文章的时候已经测试过了,函数名称是我自己改的)。

F8步过返回到上一层函数,找到了 call sub_41DDA0 指令。然而根据常识判断生成僵尸的函数总得传点比如僵尸的种类,生成的位置这样的参数吧,但是这个 sub_41DD10 函数没有传任何参数,所以猜测并不是真正的生成僵尸的函数。

所以我们继续动调找到上一层函数,发现 0x00413059 处的call指令就很符合我们的要求。push eaxpush esi 传入了两个参数,edi估计是PVZ游戏状态对象之类的,暂时还没有深究。经过反复调试我发现第一个 push esi 传入的是生成僵尸的行数(0~4),第二个 push eax 传入的是生成僵尸的种类,。

以下是部分僵尸种类的宏定义,通过动调得到的,完整的宏定义可以去我的GitHub仓库上看:

于是我们得到了 CallZombie 函数的原型,edi 理论上也是一个参数,不过是通过eax传入的,很奇怪,不过我也没深究了:

现在我们来劫持 CallZombie 函数,改成我们自己写的函数。这一块总共有9个字节,我们传入三个参数(包括edi)总共需要3个字节,call指令需要5个字节,还是够用的。

在patch函数中写上:

注入以后原来那一块的汇编代码就变成了:

其中CallZombie是我们导出函数的地址,注意调用协定一定得是 __stdcall ,因为已经没有多余的字节给我们去还原esp了,所以栈清理工作只能交给被调用函数完成。在这个函数中我们稍微修改了一下生成僵尸函数的功能——在每一行上生成了不同种类(0~4)的僵尸,调用PVZ函数的过程中注意保持调用形式不变,其具体实现如下:

顺便附上几种不同函数调用协定的区别:

测试一下劫持效果:

真不戳!

 
 
 
 
 
 
#define ZOMBIE 0 //僵尸
#define FLAG_ZOMBIE 1 //摇旗僵尸
#define CONEHEAD_ZOMBIE 2 //路障僵尸
#define BUCKETHEAD_ZOMBIE 3 //铁桶僵尸
#define POLE_VAULTING_ZOMBIE 4 //撑杆僵尸
#define NEWSPAPER_ZOMBIE 5 //读报僵尸
#define SCREEN_DOOR_ZOMBIE 6 //铁栅门僵尸
#define FOOTBALL_ZOMBIE 7 //橄榄球僵尸
#define DANCING_ZOMBIE 8 //舞王僵尸
#define BACKUP_DANCER 9 //伴舞僵尸
#define DUCKY_TUBE_ZOMBIE 10 //鸭子救生圈僵尸
...
#define ZOMBIE 0 //僵尸
#define FLAG_ZOMBIE 1 //摇旗僵尸
#define CONEHEAD_ZOMBIE 2 //路障僵尸
#define BUCKETHEAD_ZOMBIE 3 //铁桶僵尸
#define POLE_VAULTING_ZOMBIE 4 //撑杆僵尸
#define NEWSPAPER_ZOMBIE 5 //读报僵尸
#define SCREEN_DOOR_ZOMBIE 6 //铁栅门僵尸
#define FOOTBALL_ZOMBIE 7 //橄榄球僵尸
#define DANCING_ZOMBIE 8 //舞王僵尸
#define BACKUP_DANCER 9 //伴舞僵尸
#define DUCKY_TUBE_ZOMBIE 10 //鸭子救生圈僵尸
...
void CallZombie(DWORD ztype,DWORD row);
最后于 2021-2-9 23:36 被34r7hm4n编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (4)
雪    币: 8053
活跃值: (3986)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
拜读佳作,收货颇多,谢谢!
2020-12-19 19:34
0
雪    币: 14303
活跃值: (10769)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
3
十年后 拜读佳作,收货颇多,谢谢!
感谢
2020-12-19 22:03
0
雪    币: 224
活跃值: (237)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
太好了,只喜欢研究植物了
2020-12-29 09:34
0
雪    币: 224
活跃值: (237)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
ida调试发现雪人僵尸和海豚僵尸的生成不太一样
2020-12-29 09:35
0
游客
登录 | 注册 方可回帖
返回
//