bug漂流记
手机系统报错引发的惨案
app的开发中,发现app会出现崩溃,进一步发现只有特定的某个机型的某个版本出现这种情况,其他都是正常的,所有我们怀疑手机对系统framework.jar做了什么手脚。通过日志一看,果然如此.......
目录
日志确认问题所在
反编译手机系统,查看代码
hook有问题的部分,解决崩溃问题
- 日志确认问题所在
如:
我们发现是framework层的AbsListView方法发生了空指针异常。现在需要反编译系统看看这部分逻辑是怎么写的
- 反编译开始了
1. 去官网下载地址
http://www.vivo.com/download/97.html
下载好之后,解压zip包,可以看见里面的内容
我们需要找一个工具把这些system.new.dat.*合成一个System.img文件
我墙裂推荐的是:https://github.com/wangkunlin/sdat2img
直接用https://github.com/wangkunlin/sdat2img里面的release中的 sdatimg.jar
命令: java -jar sdat2img.jar 系统的解压包路径/system.transfer.list 系统的解压包路径/system.new.dat system.img
(撒花撒花,我们得到system.img了)
2、使用linux挂载system.img
像我们用mac的小伙伴就需要下载Linux虚拟机了,好吧,mac如何安装linux虚拟机简单的提一句吧:virtualbox + ubuntu-16.04.5-desktop-amd64.iso
使用Linux挂载system.img的方法,我墙裂推荐: https://www.jianshu.com/p/db70835d41c8
挂载好之后,可以看见framework文件夹。把 framework.jar 以及 arm64文件夹下面的boot.oat,直接粘贴出来。
天啊,我们现在有oat文件了
3、 oat转成 dex 我们这里使用 oat2dex文件
4. 我们现在有了dex文件了,这里我墙裂推荐jadx-gui, 可以直接打开dex文件,jadx-gui也能支持apk,jar,zip,class,aar之类的。
现在我们终于看见了系统的代码。 离成功只有一步之遥了。
- 分析问题,找到解决办法
我们发现一是isSuperFloatViewServiceRunning中语句
List<RunningServiceInfo> serviceList = ((ActivityManager) AbsListView.this.getContext().getSystemService(Context.ACTIVITY_SERVICE)).getRunningServices(Integer.MAX_VALUE);
返回的 serviceList是个null。
getRunningServices代码:return ActivityManagerNative.getDefault().getServices(maxNum, 0);
我们知道了一个比较好的hook点,就是代理getServices方法。如果返回的是null ,我们就new一个list返回。
想法是好的,现在是又奔溃了,这次崩溃的日志变了。变成TransactionTooLargeException
我们invoke返回的异常不在是TransactionTooLargeException 所以 getRunningServices就catch不到了,真实的异常就暴露出来了。
所以我们在动态代理的时候,try{} catch(Excepton ex) {}这样,就不会崩溃了。
最终的解决方案的代码
解决,全剧终。