app加固及脱壳
加固和脱壳介绍
之前的简单加固,就是字符串加密,这里的加固是对dex文件或者dex文件中的某些代码或者so文件进行加固
app启动的时候,先加载壳的dex文件,在壳dex文件中有某个方法,去判断平台、加载对应的so、通过so文件解密并释放真正的dex文件并运行
重点就是把解密之后的dex文件拿到并反编译
怎么去分辨加固是厂商加固还是自写的加固,这个时候需要记一些特征,厂商加固的壳dex反编译之后的类名一般是厂商名,或者在assets里面找so文件的文件名,等等
app加固介绍
jadx反编译的都是apk里面的dex,如果dex是加密的,就只能看到壳代码
有些壳代码,在看smali代码中会看到一堆nop,也就是代码抽空,只有在app运行时才被填充,也就是抽取加固
加固,其实就是app真实的dex文件加密,在app运行过程中再加密,此时反编译看到的就是壳的代码
脱壳,就是将加固之后的app在运行过程中,解密之后的dex文件保存,与加密算法差不多,一个加密的是字符串,一个加密的是文件
360加固,整体加固以及被vmp化的onCreate;ijiami企业版,函数体指令被抽取,用nop填充原有数据,或者干脆变成空函数
分析加固的app是不是必须脱壳?不是,能直接逆向出算法的不需要,比如自吐去hook或者能快速定位到关键代码所在so文件的
怎么判断app是否加固?
1 | 反编译查看类的数量,一般加固之后app反编译之后类比较少 |
没有加固的,也可以脱壳
加固的分类
1 | dex加固:整体加固、抽取加固、VMP、dex2c等 |
app加固的分类
app加固的几种方式
整体加固,一代加固,分为落盘加载和不落盘加载,也就是解密之后dex会不会落盘还是只是存储到内存里
抽取加固,二代加固,实际上就是把函数体的代码抽空,把函数体的代码放到另外的地方,有些情况下,被抽取掉函数体的函数会被定义为native方法,抽取类的壳也分为两种,一种是函数体被还原之后,就不管了,另一种是函数在被调用的时候还原函数体,用完了继续抽空。还有一种情况,会在类里面加上一些无效的类,这些无效的类一旦被运行就会导致程序崩溃退出(因为正常app在执行的情况下这些类根本不会运行,当脱壳的时候,针对后一种情况(也就是运行函数体之后又把函数给抽空了),就不能用dexdump,必须要主动调用,而脱壳在主动调用的时候就会调用到无效的类导致程序崩溃)
VMP加固
整体加固
介绍
1 | 可分为落地加载、内存加载,现在已经没有落地加载了,落地加载就是解密之后的dex文件会落盘 |
解决方案
1 | 脱壳工具fdex2 |
抽取加固
运行方法后回填,运行完后不再抽取,只需要把app的方法都运行一遍,然后延时dump
运行方法后回头,运行完成之后又抽取,需要FART、youpk主动调用
抽取加固中函数的goto问题,壳代码中会有大量的goto语句,跳来跳去
解决思路其实就是被抽取的函数肯定要回填运行,抓住运行的时机进行dump
VMP与dex2c
1 | VMP:定位解释器是关键,找到映射关系就能恢复 |
多种方式混合加固
先部分类VMP加固,再抽取加固,再整体加固
frida-dexdump暴力脱壳
下载dexdump https://github.com/hluwa/frida-dexdump/releases
objection运行,脱壳之前最好把app上的功能都运行一遍
下述方法一般是针对一代壳
1 | objection -g 包名 explore 进入app进程 |
BlackDex脱壳
开源,运行在手机上
https://github.com/hluwa/frida-dexdump/releases
丢手机上直接运行就行了