1 背景
插桩技术又称代码注入法,能够在程序特定的位置插入代码段,从而收集程序运行时的动态上下文信息。
栈追踪也称堆栈回溯,是对程序运行过程中的某个时间点上活跃栈帧信息的描述。
Android的Method Profiling功能,是可以在一段时间内记录所有运行过的函数,最后生成一个xxx.trace文件。
2 插桩
Smali强大之处就是可以随心所欲的进行插桩操作。何为插桩,引用一下wiki的解释:
程序插桩,最早是由J.C. Huang教授提出的,它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。
【注意】插桩时不要影响程序上下文,即插入的代码不能影响下面代码中使用的寄存器或者变量。
首先使用查壳工具检测下APP有没有加壳,如图1所示
可以看到好搜小说大全的APK没有加壳,没加壳好办,直接使用AndroidKiller打开APK,找到对应smali代码(如果加壳,需要先脱壳,然后再反编译分析,这里不涉及脱壳。)在工程信息栏的入口界面处,打开入口activity,并插入Log和Toast函数,其中的字符串使用Unicode编码形式,如图2所示。
最后,编译、打包、签名,重新安装到真机中,就会在打开APP的情况下弹出信息,如图3所示。
在Android Device Monitor的Logcat中,根据进程进行过滤查看Log插桩成功,如图4所示。
3 栈跟踪
在AndroidKiller的入口界面的loadData()函数中,右击->插入代码->stack trace,插入栈跟踪代码,如图5所示。
然后,编译、打包、签名,重新安装到真机中,接着在Android Device Monitor的Logcat中,根据进程进行过滤查看栈跟踪成功,如图6所示。
同样,我们也可以通过栈跟踪查看到程序执行的顺序!
4 方法剖析
有两种方法实现方法剖析,一种是使用Android Device Monitor工具自动生成trace文件,另一种是通过调用android.os.Debug类提供的方法生成trace文件。
4.1 Android Device Monitor
在Android SDK中有一个工具Device Monitor,可以用来运行一些动态分析工具,其中就包括Method Profiling。在Android Studio安装时的SDK/tools文件夹下有monitor.bat的文件,双击后即可打开Android Device Monitor。
首先点击“Device”窗口上方工具栏中的“Start Method Profiling”按钮,开启Method Profiling。与此同时,“Start Method Profiling”按钮上的文字会变成“Stop Method Profiling”。单击添加新书按钮,待跳转到榜单界面后单击“Stop Method Profiling”停止,稍等片刻便会自动弹出TraceView窗口。
每个表项都是有Parents和Children两个子项,图7中显示Parents表示com.reader.activity.TopListActivityV2.initTabAndFragments()被com.reader.activity.TopListActivityV2.onCreate()调用,Children表示com.reader.activity.TopListActivityV2.initTabAndFragments()调用了com.reader.widget.TabIndicator.setTitle()。所有方法调用都以链表形式依次显示,显示的顺序与栈跟踪的输出信息相反。
4.2 android.os.Debug
如果我们想要执行的Method Profiling代码在程序一开始就执行了,要想对其进行Method Profiling,需要先查找开始点与结束点,再手动注入代码。Method Profiling的调试支持本来就是由Android SDK提供的,android.os.Debug类提供了startMethodTracing()与stopMethodTracing()来开启Method Profiling,示例Java代码如下所示。
1 | android.os.Debug.startMethodTracing("iHui"); |
如果手动注入Method Profiling时代码的起始点与结束点不容易确定,可以将代码的范围设置得大一些。
首先,在Activity的OnCreate()方法中注入startMethodTracing()的代码,反汇编成smali代码后如下所示。
1 | const-string v1,"123" |
然后,在Activity的OnDestroy()方法中注入stopMethodTracing()的代码,反汇编成smali代码后如下所示。
1 | invoke-static {},Landroid/os/Debug;->stopMethodTracing()V |
字符串123为trace文件名,上面的代码执行后,会在SD卡的根目录中生成123.trace文件。这个文件包含了方法执行过程中的所有方法调用与CPU占用时间等信息,可以使用Android Device Monitor工具打开,注意从Android Studio3.2以后traceview工具被弃用,最终的方法剖析结果如图8所示。
同时,通过Jadx也能查看方法之间的调用关系,如图9所示。
5 参考文献
[1]丰生强. Android软件安全权威指南[M]. 电子工业出版社, 2019.
[2]https://blog.csdn.net/freeking101/article/details/105829304
[3]https://blog.csdn.net/freeking101/article/details/105897144
[4]https://blog.csdn.net/freeking101/article/details/105910086
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。