吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 9294|回复: 169
上一主题 下一主题

[原创] 『原创』植物大战僵尸分析及Python辅助实现

    [复制链接]
跳转到指定楼层
楼主
syncking 发表于 2020-12-26 23:58 回帖奖励
本帖最后由 syncking 于 2020-12-27 15:11 编辑

植物大战僵尸分析及Python辅助实现

起因

网上已经有很多帖子分析植物大战僵尸冷却的。有的看不出是个什么逻辑,一会搜索1,一会搜索0的,脑子笨想不出来是什么门道。

没办法只能自己操刀按自己的想法分析看看了,就当学习。

准备工具

  • x32dbg
  • 植物大战僵尸
  • Cheat Engine 7.1

过程

先把阳光数量变成可控的,阳光基址就不说怎么找了。其实不找也行只要把阳光变的多点就行,目的就是能随时用阳光。

按照网上的思路反复搜索1,搜索0的确是能做到无CD,但是看不出门道。换一个思路,冷却时间是最为直观的。就是种上植物之后,卡片会变成冷却状态,有一个冷却进度,如下图的豌豆射手。

所以目标就是先搜索出来记录这个冷却时间的地址。

这个冷却时间有两种可能,

  1. 种上植物后,程序设置一个冷却时间,之后慢慢的往下减,减到0冷却就没了。
  2. 种上植物后,程序将变量置0,开始计时,慢慢的增加,增加到某个阈值,就是无冷却了。(其实是这个)

搜索方法为了统一,不管它是增加计时,还是减数计时,搜索方法就一个。

搜索记录冷却时间的地址

搜索方法

  1. 搜索未知的初始值
  2. 冷却阴影变动,就再搜索变动了的数值
  3. 未发现第一格冷却计时地址,接着重复第2步

先用CE附加植物大战僵尸进程。

接着种上植物,CE搜索未知的初始值。

首次扫描

冷却阴影变动后按下图操作

再次扫描

一直重复再次扫描的步骤,慢慢的筛选,当一个冷却结束后,可以再种一个植物(必须是同一格)。

其实中间可以穿插一些未变动的数值搜索,这样可以更快的检索出结果来。

搜索结果

看动图可以种植的时候是0,有冷却时间的时候随时间增长。

很明显就是第一格的冷却时间,把他拉下来,右击后选择「找出是什么改写了这个地址」

记录下改写指令的汇编地址004B2FEA

实现无冷却

CE先使用一阶段,关掉CE,打开X32dbg附加植物大战僵尸

按下Alt+A附加上植物大战僵尸进程

Ctrl + g到跳转窗口,跳转到刚刚记录下来的004B2FEA地址。

跳转到地址004B2FEA指令处的分析。

// 伪代码大概就是这个意思
// ...
coolDownTime++;
if ( coolDownTime > 当前植物的冷却需要的总时长) {
    // 取消冷却 
    cancelCooling(当前植物);
}
// ...

实现无冷却有一下两种方法。

方法一

nop掉004B2FF3跳转指令

// 改成这个样子
// ...
coolDownTime++;
// 取消冷却 
cancelCooling(当前植物);
// ...

方法二

把比较换成与0比较

// 改成这个样子
// ...
coolDownTime++;
if ( coolDownTime > 0) {
    // 取消冷却 
    cancelCooling(当前植物);
}
// ...

这样改过之后打上补丁玩个游戏就没意思了,可以用CE代码注入,实现动态修改。

这里只演示第二种方法,第二种会了第一种方法就是大同小异。

x32dbg剥离植物大战僵尸进程

CE附加上植物大战僵尸进程,点击查看内存。

ctrl + g跳转到刚记录的004B2FEA指令地址(就是+1指令的地址)

实现的是第二种方法,所以我们选中下面这条指令

PlantsVsZombies.exe+B2FF0 - 3B 47 28              - cmp eax,[edi+28]

安装下面图片一步一步来

下面是生成出来的代码,没有任何改动

修改后的代码

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

originalcode:
// cmp eax,[edi+28]
cmp eax, 0
jle PlantsVsZombies.exe+B3007

exit:
jmp returnhere

"PlantsVsZombies.exe"+B2FF0:
jmp newmem
returnhere:

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"PlantsVsZombies.exe"+B2FF0:
cmp eax,[edi+28]
jle PlantsVsZombies.exe+B3007
//Alt: db 3B 47 28 7E 12

接着就是分配到当前的CT表,保存完这个页面就可以关了。

在主界面就能看到刚刚保存的脚本

这样可以动态修改指令。勾上就是无冷却,取消就是正常代码。

第一种方法和第二种方法都可以实现,第一种方法留下自己实现吧。

看看效果

游戏,索然无味。

到这里还没有结束,不是为了实现冷却,而是尽量的多分析一下看看。

继续深入一点分析-挖掘基址

把刚刚汇编的地方还原,跳出当前函数看看上一层的逻辑。

断在004B2FEA之处后,先点击运行到返回 =>  在单步步过一下 ( 或者双击右下角堆栈窗口的0019F9EC地址数据,也可以跳转到上一层逻辑)

上一层函数的逻辑

形成伪代码就是

// ...
cardList = [豌豆射手, 向日葵, 樱桃炸弹 ....]
cardCount = [eax + 24] // 当前可使用的植物卡片数量
count = 0              // xor ebx, ebx
if (cardCount > 0) {
    do {
            card = cardList[count];
            handlerCard(card);  // 最开始分析的call, 里面执行+1 重置冷却时间
            count++;            
    } while(count < cardCount);
}
// ...

逻辑大致是清晰了,现在找基址一下基址。现在关注一些上下文信息

# 汇编语句
00428E40            | 8B87 5C010000        | mov eax,dword ptr ds:[edi+15C]        |
00428E46(断点处EIP)  | 33F6                 | xor esi,esi                           | esi = 0
00428E48            | 3958 24              | cmp dword ptr ds:[eax+24],ebx         | [eax + 24] 是格子数量   最上面(xor ebx, ebx)
00428E4B            | 7E 1B                | jle plantsvszombies.428E68            | if
00428E4D            | 8D49 00              | lea ecx,dword ptr ds:[ecx]            |
00428E50            | 8D4403 28            | lea eax,dword ptr ds:[ebx+eax+28]     | 这是数组
00428E54            | E8 57A10800          | call plantsvszombies.4B2FB0           | 刚刚分析的就是这个call
00428E59            | 8B87 5C010000        | mov eax,dword ptr ds:[edi+15C]        |
00428E5F            | 46                   | inc esi                               | i++
00428E60            | 83C3 50              | add ebx,50                            |
00428E63            | 3B70 24              | cmp esi,dword ptr ds:[eax+24]         | esi < [eax + 24]
00428E66            | 7C E8                | jl plantsvszombies.428E50             |
# 寄存器信息
EAX : 19B9EC90
EBX : 00000000
ECX : 0000019E
EDX : 00000163
EBP : 0019FA5C
ESP : 0019F9F0
ESI : 1FF12C18
EDI : 200DB408
EIP : 00428E46

call plantsvszombies.4B2FB0需要传入植物卡片的地址([ebx+eax+28] ),eax是上下文提供的,ebx是偏移相当于高级语言中i++的作用。

现在eax的值不确定,有两种方法,

  1. 一个是向上看eax是谁给的,慢慢向上一层一层的找
  2. 使用CE搜索eax寄存器的值19B9EC90。(eax = [edi+15C], 搜索edi(200DB408)就行)

我选择第二种,因为第一种我试过了,不好使不方便。

第二种方式:x32dbg剥离植物大战僵尸进程。

换成CE加载,搜索edi寄存器的值200DB408(注意先勾上十六进制

拉下来右键=>『找出是什么访问了这个地址』。

搜索ESI值0295B120

基址都记录下来吧,以后可能都会用到。(其实随便选一个就行)

<Address>PlantsVsZombies.exe+3794F8</Address>
<Address>PlantsVsZombies.exe+37959C</Address>
<Address>PlantsVsZombies.exe+379670</Address>
<Address>PlantsVsZombies.exe+379618</Address>

组合分析使用基址

// 猜测
CARDS {
    // ....
    int count;     // +0x24
    Card list[X];  // +0x28  每个Card大小为0x50  
    // 后面分析这个数组好像是固定长度  控制 [CARDS + 0x24] 可以扩容和减少格数
    // 设置超过数组的 size 就会程序异常
    // .....
}

//植物卡片对象 地址
CARDS = [[[PlantsVsZombies.exe+379618] + 0x868] + 0x15C]
//植物卡片个数  可以实现扩容和减少格数
[CARDS + 0x24]
// 第N格植物卡片地址 N > 0
[0x50 * N + CARDS + 0x28]
// 第N格植物卡片地址 N > 0 冷却记录
[0x50 * N + CARDS + 0x28 + 0x24]
// 第N格植物卡片地址 N > 0 冷却时间
[0x50 * N + CARDS + 0x28 + 0x28]
// 模块起始地址
00400000 - PlantsVsZombies.exe

有了这些分析就可以写代码了。

Python 实现辅助

下面放一部分,具体的全部代码可以看附录里面的代码,大多读写内存的操作都是封装的Win32Api(还不如用C++写)

# 省略 .......
pid = get_pid("PlantsVsZombies.exe")
print("PlantsVsZombies.exe 进程id: " + str(pid))
processHandle = open_process(pid)

def showCard(processHandle):
    count = plant_cards_count(processHandle)
    os.system("cls")
    x = PrettyTable(["格子", "当前冷却时间", "总时间"])
    for n in range(count):
        plant_info = get_plant_n(processHandle, n)
        x.add_row([n+1, plant_info["cooling"], plant_info["cool_time"]])
    title = "阳光:{}".format(getSunCount(processHandle))
    print(x.get_string(title=title))

def drawTable():
    while True:
        showCard(processHandle)
        time.sleep(1)
# 滚动滚轮
def on_scroll(x, y, dx, dy):
    # dy == -1 下滑
    # dy ==  1 上滑
    sunCount = getSunCount(processHandle)
    setSunCount(processHandle, sunCount + (5 * dy))
# 省略 .......

效果:向上滚动滚轮增加阳光,向下滚动滚轮减少阳光(注意动态中阳光的变化)。可以看到有几个格子,冷却时间,总时间。

修改的功能就只有一个阳光,其他的就不写了,写多了也没意义,现在不会还有人玩这游戏的吧哈哈👀。有兴趣的可以下载附件中的CT(里面包含无冷却,格子数量的控制功能)。写这个Python辅助脚本的目的就是验证上面分析出来的基址和信息对不对,别无目的。

总结

整个过程的分析是完成了,就像开篇说的搜索1/0的方法还是没有探索出来是怎么影响的,知道『原理』的可以撩一撩,是从什么角度分析的,学习一下。

文中提到的方式都可以实现无冷却,分析过程中也随便扒拉出了其他信息,比如当前格子的冷却,当前植物冷却时间的总时间,还有格子数量[CARDS + 0x24]。分析该到一段落了,大多分析结果都是通过少量已知的上下文条件,和我的经验推断出来的(不一定准确),如有异议可以回帖交流啦。

推荐下载相同版本的植物大战僵尸,不同版本CT文件可能不通用

链接:https://pan.baidu.com/s/13XiuPfzr0PStDCpJE5OYYg  提取码:kmgq (里面包含CT文件)

py-script.zip (2.91 KB, 下载次数: 90)

免费评分

参与人数 71威望 +2 吾爱币 +164 热心值 +60 收起 理由
terryyann + 1 + 1 谢谢@Thanks!
KSTG_茶飘香 + 1 + 1 热心回复!
hxtlcc + 1 我很赞同!
LGHLGH + 1 + 1 我很赞同!
silvester + 1 谢谢@Thanks!
a261201 + 1 + 1 我很赞同!
meridian + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
舞墨者 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
HongDi-Joies + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
L12982 + 1 用心讨论,共获提升!
小小青年刘德华 + 1 热心回复!
anliou + 1 + 1 谢谢@Thanks!
冬羽 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
小龙人LL + 1 + 1 用心讨论,共获提升!
cloud_hb + 1 + 1 高手啊!
Trwqnml + 1 + 1 谢谢@Thanks!
jiangjj + 1 + 1 谢谢@Thanks!
bianchaojie + 1 + 1 我很赞同!
冈本003 + 1 谢谢@Thanks!
wzc13935617933 + 1 + 1 谢谢@Thanks!
coolduck + 1 + 1 热心回复!
Hmily + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Polo衫 + 1 + 1 谢谢@Thanks!
julydate + 1 + 1 谢谢@Thanks!
zhuzhuxia111 + 1 + 1 我很赞同!
白皇吾猫 + 1 + 1 我很赞同!
zthonline + 1 + 1 我家小朋友特别爱玩这个
江南第一帅 + 1 + 1 热心回复!
mysxl2008 + 1 + 1 我很赞同!
晓晓晓JH + 1 我很赞同!
Cookiesfly + 1 + 1 用心讨论,共获提升!
涂秋 + 1 热心回复!
谷幽兰 + 1 + 1 谢谢@Thanks!
Web_ + 1 我很赞同!
Cheremace + 1 + 1 我很赞同!
xmztz + 1 + 1 谢谢@Thanks!
今晚酒肆不打烊 + 1 + 1 用心讨论,共获提升!
loveexword + 1 + 1 用心讨论,共获提升!
AccFun + 1 + 1 我很赞同!
funtouch2 + 1 + 1 我很赞同!
sgjf2010 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lxwlxwlxw + 1 + 1 谢谢@Thanks!
南冥大人 + 1 + 1 我很赞同!
Fs-me + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
17315044449 + 1 + 1 热心回复!
csa + 1 + 1 用心讨论,共获提升!
抱薪风雪雾 + 1 + 1 谢谢@Thanks!
amdint123123123 + 1 + 1 我很赞同!
hxdfree + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
内切圆半径除二 + 1 用心讨论,共获提升!
huangxw + 1 + 1 谢谢@Thanks!
zanaa007 + 1 + 1 用心讨论,共获提升!
我是一个外星人 + 1 谢谢@Thanks!
kez + 1 我很赞同!
片面晨光 + 1 我很赞同!
shuaibi_chen + 1 + 1 我很赞同!
Mr_Guan + 1 + 1 我很赞同!
wangyftr + 1 + 1 我很赞同!
kid2man + 1 + 1 用心讨论,共获提升!
huixiaochuna + 1 + 1 我很赞同!
okgjkk + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ff5500 + 1 热心回复!
sdaza + 1 我很赞同!
WIFI4451 + 1 我很赞同!
chinawolf2000 + 1 + 1 热心回复!
start100 + 1 谢谢@Thanks!
o824 + 1 + 1 谢谢@Thanks!
鹤舞九月天 + 1 我很赞同!
churen52 + 1 + 1 谢谢@Thanks!
zecore + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
推荐
wsx710904 发表于 2020-12-27 00:14
提示: 该帖被管理员或版主屏蔽
头像被屏蔽
推荐
天天54123 发表于 2020-12-27 13:47
头像被屏蔽
推荐
qinguoliang1994 发表于 2021-1-6 17:16
5#
zecore 发表于 2020-12-27 00:02
讲的很清楚,感谢分享
6#
曲断情 发表于 2020-12-27 00:02
点个赞 满满的回忆啊
7#
 楼主| syncking 发表于 2020-12-27 00:05 |楼主
曲断情 发表于 2020-12-27 00:02
点个赞 满满的回忆啊

可以说是回忆了,以前打两天也没打通关
8#
churen52 发表于 2020-12-27 00:08
技术流啊,我最近还在玩呢
9#
0kokokgb 发表于 2020-12-27 00:15
非常感谢分享!
10#
呆若木鸡 发表于 2020-12-27 00:23
谢谢分享,感谢感谢
11#
PrincessSnow 发表于 2020-12-27 00:27
谢谢大佬的分享!
12#
Kashimalove 发表于 2020-12-27 01:26
技术才是王道啊!老哥真是666
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2021-1-20 20:15

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表