记录第一次逆向过程

一、准备

<1>、工具

  1.         逆向工具:IDA Freeware 8.4
  2.         逆向对象:植物大战僵尸杂交版v2.0.88;(B站作者:潜艇伟伟迷)
  3.         逆向辅助工具:文心一言;(在此之前从未接触过汇编,所以利用AI快速了解汇编代码)

<2>、IDA快捷键   

SHIFT+F12打开Strings视图,包含有所有字符串
SHIFT+F3打开Functions视图
空格view视图下流程视图的切换
CTRL+FStrings视图/Functions视图下搜索
ALT+Tview视图/pseudocode视图下搜索
F5反汇编为C语言
F2添加/删除断点

F7

单步步入
F8单步跳过
F9 运行直到下一断点/结束
F11全屏
G地址跳转
X展示引用当前(光标所在)方法的方法
ESC返回上一个方法
编辑注释
CTRL+Z撤回上一步操作
  1.    IDA顶部菜单 Debugger 下的 Debugger windows 下的 Locals 视图可以在动态分析时实时展示当前断点方法中的变量值内容;
  2.    IDA顶部菜单 Edit 下的 Patch Program 下的  Assemble an instrction 可修改汇编代码(其他两个没用过)。同菜单中 Apply patches to input file 可将修改的代码应用到文件中。

<3>、其他

  1.       植物大战僵尸杂交版  在安装完成后需要运行一次,不然就只有一个启动文件 pvzHE-Launcher.exe(本人就在这个文件上浪费了太多时间)。运行完之后就会生成多个文件,其中就有一个我们的关注对象 PlantsVsZombies.exe。

二、开始

<1>、初次探索

使用IDA打开 PlantsVsZombies.exe 文件(第一次打开文件自行百度需要设置的点)之后不要急于分析代码。先根据对应文件以及自己的目标,大致猜测几个可能得关键词。(例如:Plant(s) 、Zombie(s)、bullet、shell、cannonballd 等)然后SHIFT+F12 打开Strings视图,接着CTRL+F搜索上面猜测的关键词(由于作者开发游戏时对于命名可能采用缩写等方式,所以在初次搜索时尽量不要使用完整的单词,我一般选择截取至少前四位字母的方式,如果搜到的内容较多便可以将搜索搜索词改的更精确些,否则可尝试一下截取前三位字母,再小就不建议了)。
Plant(s)为例,如图所示:

           

此时我们就可以找一些我们感兴趣的字符串。如图中的 plants 。然后变可以双击鼠标左键查看,如图所示:

在这里我们就可以看到游戏开发者关于变量的命名结果(单引号中的)。此时你可以试着向上或者向下查找对你可能有帮助的变量名,亦或者继续使用上面最开始的查找方式。

之后我们便可以对变量进行一个全局的搜索(ALT+T)。下面是zombies(plants搜索结果一样)的搜索:

                     

搜索结果:

这里我们可以发现搜索结果中有两个方法  sub_407B50  和  sub_418C70 (该方法对我们没有用,本人猜测可能是初始化,没有深究)。那么目标就放到了 sub_407B50  这里。双击sub_407B50  。如图所示(代码片段):

无奈看不懂,只能F5查看伪代码:

      

但是这还是不容易看出代码逻辑。于是,我便使用空格键切换到流程视图,在代码开始和结尾处各打了一个断点,想要通过debug看看代码大致执行顺序。但是我发现,当点击关卡时,会被断点拦截,同时,只有结尾处的断点放行后,才会正式进入游戏,于是我简单的向上找(引用该方法的方法)了一下,没有找到where等循环的代码结构,便放弃了继续找下去,将sub_407B50 记录了一下,就跳过了。

<2>、再次探索

        1.经过上面的查找,我觉的我在关键词上的选择范围有点大了,于是我又开始试着以植物的名称(如:豌豆),攻击相关的字眼(如:发射),子弹相关(如:豌豆,刺,尖刺,玉米等)等进行查找。

        2.在查找shoot时,发现了大量关于(anim_shooting)的结果,根据命名不难猜出这是关于触发射击动画的变量。

对Function进行排序后,发现sub_45EF10anim_shooting  的使用最多,于是我猜测该方法可能是植物/僵尸攻击的方法。然后我就无脑的对sub_45EF10里面anim_shooting  行代码进行断点。

继续debug。此时令人兴奋的时刻到了。

种植豌豆后,没有任何事发生。但当僵尸刷新出来后,进程被断点拦截住了。

于是我开始F8一点一点的步进,最终发现,知道代码运行到141行返回结果时,子弹依旧没有出现。

于是我继续F8来到了 sub_45F8A0 的 36行:

这是什么鬼,这行哪里调用了sub_45EF10,但还是硬着头皮F8,于是来到了43行,可这任然没有得到我期望的结果,只能试着继续F8,期望能看到子弹的出现。可没多久,我就在向上走了三个方法到sub_4130D0 时(这之间没进过几个方法,几乎一路return),我看到了循环:

这也就意味着,子弹的发射确确实实和 sub_45EF10有关。(原因:sub_45F8A0下的 sub_45EF10 有字符串 anim_shooting 。并且,只有子弹发射前一刻,该方法会拦截到进程

至于子弹没出现可能是渲染顺序方面的原因吧。为了继续佐证我的猜想,我便在 sub_45EF10的上级sub_45F8A0开始尝试打断点。

           

从这两个断点中我知道了if外在不断地循环中,当只要进入if内,子弹就会发射。也就是说,这里起到了计时器的作用,那么此时我将 0 调节的更大,这样就缩短了发射子弹的时间。

<3>、尝试修改代码

在第八行打上断点,将视图切换到view视图(有汇编代码的视图),然后F9,等待拦截到。

这里(如果看不懂汇编,可以直接将代码复制给 文心一言 )的代码:

cmp     eax, 0 ;和零进行比较
jg      short loc_45F91C ;如果eax中的值大于0,就跳转到loc_45F91C对应的代码块,如果小于等于零就跳过loc_45F91C

也就是说我们只要改变 cmp eax,0 中的0值即可。

点击ok(输入100会被自动改为64h,最好还是直接手动输入16进制数吧),取消断点看结果:

可是我发现该处只对冰豌豆有效,但对普通豌豆只加速了发射子弹的动画,至于发射子弹则是普通豌豆发射不了子弹了,对于其他植物也无正向效果。只不是我期望的,于是恢复修改,继续在此基础上分析。既然上面的操作能影响冰豌豆的攻击速度,那么if中一定有攻击方法,并且断点步进只经过sub_45EF10:

那么接下来就在sub_45EF10 中断点分析,由于之前猜想的关于 anim_shoot 的方法都可能是判定动画,和执行动画方法。与攻击方法应属于并列的关系,所以我们可以暂时将注意力集中到不含有anim_ 的方法上。但注意观察游戏界面的变化(这可能有助于缩下分析范围)。

然后我找到了四个方法,其中有两个和疑似动画相关的方法关联性比较高:

明显sub_473310 的可能性比较大,接下来就是验证哪一个是攻击方法。(想办法阻止其中一个方法不执行)但是ida可以很容易修改代码,但很难新增代码,所以我这里就试着将 v9 改为 !v9:

test    ebx, ebx             ;与自身and运算
jz      loc_45F09E           ;如果等于0则跳转loc_45F09E---修改jz为jnz
;相等与if(v9)

push    offset aAnimShooting ; "anim_shooting" ;设置参数
call    sub_4732C0           ;调用方法
test    al, al               ;与自身and运算
jz      loc_45F09E           ;如果等于0则跳转loc_45F09E
;相等与if(v9)

;--------------------否则执行下面代码-----------------
push    14h
push    ebx
call    sub_473310

修改后:

没有影响子弹发射,继续:

也没有用,那么就恢复修改,对  sub_466E00 重复上面操作,可能问题来了,我在183行和140行打的断点并没有拦截到,而141行的断点却拦截到了(造成的原因可能是返回值对应的汇编代码是被共用的,所以会被拦截到,但当时我没意识到,所以我就开始好奇,难道sub_466E00真的没被执行吗。)。于是我就在sub_466E00 里面打了一个点,结果真让我瞎猫碰上死耗子了(我承认我有赌的成分),于是我就长按F8(也可以找到所有return打点F9)想看看是那个方法调用的:

结果来到了sub_464820  ,同时我发现我在sub_466E00打的第一个点:

这里拦截几次就有几个子弹产生,而且不分植物。之后我就将 sub_464820 中所有调用 sub_466E00 的地方打上断点,结果是仙人掌在312行被拦截:

冰豌豆在321行被拦截(321对应的代码块被其他地方调用,通过步进来确定是哪个植物调的哪一行即可)

然后我对较容易修改的321行进行修改 if(result) 改为if(!result),结果是冰豌豆只有攻击动画没有子弹产生。那么到这里,我们就可以猜测出sub_464820是用来判断哪种植物发射哪种子弹(与参数V2中的值直接相关,可以通过 Locals 视图查看)而sub_466E00则是处理子弹的方法。由于我没有找到V2如何设置值的,所以我就尝试修改判断条件让321行的代码尽可能多的执行(中间有点繁杂无味就跳过了),结果如下:

267-270原本的代码是v2中的下标36对应的值如果等于 1 则直接return出该方法,而我则将其改为了不等于1。这样冰豌豆的sub_466E00触发几率就增大了。修改后应用到文件中的效果如下:

<4>、最后

通过上面的步骤我又找到控制僵尸(包括僵尸输出数量,位置等)和毁灭加农炮的相关的方法:

三、结束

本篇目的是仅为了学习交流!

由于初次逆向,对于逆向过程还有很多不足之处,希望道友们多开金口。

关于文中提到的V2值的设置(或者其他好玩有意思的点),有知道的盆友也可以告诉我一下。

最后呢,我也想诚恳的请教大佬们,我有可以根据地址向内存中写入值的代码,但我不知道如何搞到基地址+偏移量,是否与view视图中的地址有关?还请赐教,谢谢。

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值