10-3:IDA找敌人数组相关函数调用关系(有符号so)
单机安卓游戏绘制教程10-3:IDA找敌人数组相关函数调用关系(有符号so)
本文接上一篇:单机安卓游戏绘制教程10-2:IDA找敌人数组相关函数思路(有符号so)
目前已知GmSimGetNumOfDeadAiTANKs这个函数的参数就是敌人数组的起始地址,接下来找它的调用栈,通过调用栈上的函数,找到参数的来源。
能对着函数名按X,就按X,如果按X出现的列表没有“BL”指令,就给函数打断点,观察LR寄存器的值,接下来演示操作:
按X找到了两个函数,我们先进去第一个看看:
可以得知,GmSimGetNumOfDeadAiTANKs的参数一,是GmSceneCampaignCallbackSimEventTANKKilled的参数一a1+32得到的地址所指向的数值(注意这个*(_DWORD *)(a1 + 32),把a1+32转为了指针,并读取出了这个指针指向的地址的值)
再对着这个函数按X,发现并没有出现BL指令,只有一个GmSceneCampaignResume函数当中用到了该函数的指针,后续游戏会通过函数指针的形式调用这个函数,这种情况IDA不能静态分析出来,
所以接下来要回到GmSceneCampaignCallbackSimEventTANKKilled,直接如图所示,给这个函数第一条语句打上断点(点击行号左边的蓝色圆圈):
先回到GmSimGetNumOfDeadAiTANKs函数,这次进入xrefs窗口的第二个函数GmScenePreviewCallbackSimEventTANKKilled,可以看到,这两个函数参数关系是*(_DWORD *)(a1 + 4)
对着GmScenePreviewCallbackSimEventTANKKilled函数按X,发现仍然找不到BL指令调用,所以,这里也打个断点
现在按X已经遇到阻碍了,接下来要通过LR寄存器继续找调用关系,需要用到IDA目录的dbgsrv文件夹的android_server,这部分教程网络上已经有很多了,推荐一个帖子作参考:https://www.52pojie.cn/thread-1511844-1-2.html (专栏不能设置站外链接)
android_server和ceserver使用方式一样(关于ceserver,可以参考我这个视频教程05-1:免root使用ceserver桥接真机的准备工作:设置debuggable=true,以及这个视频教程05-2:CE查看安卓手机内存中的数据(ceserver桥接教程)),有ROOT直接用;如果没有ROOT,就需要修改安装包debuggable属性,然后run-as启动android_server。
在手机端启动android_server之后,IDA操作如图所示:
选中游戏进程点OK,然后:
如果出现上图这个弹窗,是在问你当前打开的so和内存中的so是否一样(就是说 解压的apk和安装的apk是否是同一个版本),选择Same就行了,
然后游戏进程就被暂停掉了,等待上面这张图的窗口消失,
刚刚已经打过俩断点了,然后在游戏里面动一动,等待触发断点,然后你会发现,在子弹即将接触到某个角色时,游戏被暂停,此时触发断点,
所以是GmSceneCampaignCallbackSimEventTANKKilled这个函数的断点触发了,并且是GmSimDealDamageToTANK调用了它,参数一是v17[36],
这里先简单记一下这个函数内部和v18的参数一有关的代码:
|
|
然后继续,找这个函数是谁调用:
先点击去第一个看看:
参数一不可能是float,不多解释了,直接改类型:
记一下:
|
|
继续找:
记下来:
|
|
找:
这个时候,前两个函数进去按X找不到调用者,打断点并没有遇到他们的触发条件,然后干脆将剩下四个也打断点,最终触发了GmSimProcessInstantProjectile,所以进这个函数:
该记就记,该找就找,
|
|
|
|
剩下的都是以此类推,看图吧,
到目前为止,已经找到的调用栈:(个人习惯这样记录,仅供参考)
|
|
先到这里吧,写得好累,明天再继续。