现在市面上对App的安全合规管控越来越严格了,也就要求了APP在上架之前一定要做合规检测和加固处理。对APP就是加固的好处,可以提高APP的安全性,提高APP被逆向分析破解的门槛,同时通过加固保护可以提高过安全合规的检测。
由于APP加固技术不断被攻破情况,因此加固技术也是不断在快速迭代的过程。现在市面上的加固产品的还是比较多的,并且各个加固技术产品都有其各自优缺点,但是加固产品的所采用技术去有很多共性的地方。下面就对加固和脱壳对抗方案做些梳理总结。
360整体加固classes.dex后的apk程序的特点,以超信1.1.4版本为例。360加固以后,会在apk的assets文件的路径下增加两个文件libjiagu.so和libjiagu_x86.so以及修改原apk的AndroidManifest.xml文件的application标签增加两个元素。
360加固脱壳需要完成两个任务,一个任务是过掉360加固的反调试,另外一个是获取原apk的classes.dex文件。下面写一下具体的脱壳步骤,完成这两个任务。为了脱壳成功,在动态调试加固apk程序前,需要将android_server调试程序的名字修改一下,因为360加固会通过查询/proc/pid/cmdline文件获取程序的名称来对android_server、gdb、ltrace、strace调试器进行反调试。
在动态调试加固apk程序的时候,需要在几个关键点函数 open、strtol、mmap、memcmp处下断点,后面具体的分析。由于android系统是由linux系统修改而来,因此Android系统上很多的属性和Linux系统下的属性。Linux下进程和线程的信息是保存在文件中的,因此要查询进程或者线程的信息必须通过open或者fopen等方式操作文件来完成。
Android的so调试的步骤略过,已经在上面提到的4个函数处下断点,注意下断点的技巧,下断点的时候,要在一个函数的第1条指令和最后一条指令的地方下断点。
F9运行程序,当看到下图的状态,调用open函数打开文件/proc/self/status时,可以确实是加固外壳apk程序通过TracePid的反调试。
过掉通过TracePid方式的反调试的方法是在strtol函数处下断点,在strstol函数的最后一行指令的地方,修改该函数的返回值R0的值为0即可,然后F9运行程序。
360加固的外壳程序apk还会通过文件/proc.NET/tcp的本地套接字进行反调试,一旦检测到程序有23946端口的本地连接的套接字,他就会结束当前程序,其实过这个方式的反调试的方法很多,修改远程调试的端口号就可以过掉反调试。
过掉通过/proc/net/tcp文件的本地套接字的反调试的方法是在open函数处下断点,然后F8单步调试发现strstr函数,加固的外壳apk程序就是通过strstr函数进行判断当前进程是否存在本地连接的套接字,一旦检测到,就结束当前进程。
发现程序循环调用strstr函数进行判断,当strstr函数的返回值不为0为字符串“sl local_address rem_address”时,需要注意,说明当前进程已经检测到了本地连接的套接字,因此需要修改strstsr函数的返回值为0即可。
加固apk程序还会通过"/proc/pid/mdline"对android_server、gdb、strace、ltrace调试器进行反调试,但是只要向前文提到的修改android_server的名称即可过掉该反调试。
过掉反调试的方法已经说明白了,下面只要F9运行,按照前面的方法过掉几次前面提到的反调试即可畅快的调试程序了。当发现当前进程调用open函数打开文件/proc/pid/maps需要注意了,脱壳需要关注的地方开始了。原被加固的dex文件开始解压和解密了。
经过几次F9的调试发现了下面截图的状态,但是不要心急,只是离脱壳进了一步,此时内存dump出来的odex文件不是被加固的原dex文件的而是加固外壳qihu360的dex文件。
继续F9运行程序,经过n次F9运行memcmp函数以后(其实这里可以做一个处理,暂时去掉mmap函数的断点,等到mmap函数断点处再次设置mmap函数的断点),再经过大约2次mmap函数运行以后,再一次调用memcmp函数即到了脱壳的地方,注意此时加固外壳apk程序呈现的堆栈和内存的状态。由于360加固自己制作了dvmDexFileOpenPartial函数,但是该函数需要调用memcmp进行dex文件的魔法字符串”dex“的比较,因此此时是脱壳的最佳时机。
OK,现在的任务就是从内存中dump出原来完整的dex文件,既可以手动的dump出内存中的dex文件,也可以通过IDC的脚本或者dumpdex的插件将原dex文件dump出来。
原apk程序的Dex文件拿到了,只需替换360加固的外壳程序的dex,删除AndroidManifest.xml文件的application标签增加的两个元素,删除assets文件的路径下增加两个文件libjiagu.so和libjiagu_x86.so以及原来的签名,重新签名一下apk程序即可。
在删除的application标签增加的元素中,特别是在删除android:name =””的时候,一定要检查脱壳的classes.Dex文件中否重写过application类,如果脱壳后的classes.Dex文件中重写了application类,需要将application标签中android:name=””修改过来才行。
以上就是有关dex加固的方法了,举例了360加固与脱壳流程。
拓展学习
so加固
so反编译比较困难,比dex的反编译困难。一般做法是抽取Android工程的关键java代码转为c/c++, 然后生成so文件。so加密我只是了解了一下破坏.so部分头文件的方式加固。
加固里面的VMP(虚拟机)是什么?
VMP(虚拟软件保护技术)大概思路就是自定义一套虚拟机指令和对应的解释器,并将标准的指令转换成自己的指令,然后由解释器将自己的指令给对应的解释器。