加固和脱壳介绍

之前的简单加固,就是字符串加密,这里的加固是对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
2
3
4
反编译查看类的数量,一般加固之后app反编译之后类比较少
类中的方法特征,看类名
反编译查看类名特征、so特征 比如qihoo.util libjiagu.so
查壳工具

没有加固的,也可以脱壳

加固的分类

1
2
3
dex加固:整体加固、抽取加固、VMP、dex2c等

so加固:对so结构进行处理、对so里的段数据进行加密、自定义linker,一般处理就是dump so文件,然后修复so

app加固的分类

app加固的几种方式

整体加固,一代加固,分为落盘加载和不落盘加载,也就是解密之后dex会不会落盘还是只是存储到内存里

抽取加固,二代加固,实际上就是把函数体的代码抽空,把函数体的代码放到另外的地方,有些情况下,被抽取掉函数体的函数会被定义为native方法,抽取类的壳也分为两种,一种是函数体被还原之后,就不管了,另一种是函数在被调用的时候还原函数体,用完了继续抽空。还有一种情况,会在类里面加上一些无效的类,这些无效的类一旦被运行就会导致程序崩溃退出(因为正常app在执行的情况下这些类根本不会运行,当脱壳的时候,针对后一种情况(也就是运行函数体之后又把函数给抽空了),就不能用dexdump,必须要主动调用,而脱壳在主动调用的时候就会调用到无效的类导致程序崩溃)

VMP加固

整体加固

介绍

1
2
3
4
5
6
可分为落地加载、内存加载,现在已经没有落地加载了,落地加载就是解密之后的dex文件会落盘
本质上都是将app自身的dex整体加密,app运行过程中解密后加载
有些壳还会抹掉dex文件头,dex的文件大小filesize等信息
一般会有字符串加密、资源加密、反调试、签名验证

整体加固,dex文件是壳的dex,现在的加固有的是在so层去解密dex,壳的dex会根据系统不同去调用不同的so,然后在so中去解密dex文件

解决方案

1
2
3
4
5
6
7
8
9
10
11
脱壳工具fdex2
通过class类的getDex方法得到DexFile,再通过DexFile的getBytes方法得到dex文件,适用于7.0以下系统

脱壳工具blackdex
通过mCookie来脱壳

脱壳工具frida-dump
从内存中搜索dex文件然后保存

脱壳系统FART、youpk
在dex加载、解析过程中,找到一个合适的时机,得到DexFile内存地址和大小,将解密状态的dex保存下来,还可以通过artMethod来得到DexFile,但是现在这两个系统被检测,需要二次开发

抽取加固

运行方法后回填,运行完后不再抽取,只需要把app的方法都运行一遍,然后延时dump

运行方法后回头,运行完成之后又抽取,需要FART、youpk主动调用

抽取加固中函数的goto问题,壳代码中会有大量的goto语句,跳来跳去

解决思路其实就是被抽取的函数肯定要回填运行,抓住运行的时机进行dump

VMP与dex2c

1
2
3
4
5
6
7
VMP:定位解释器是关键,找到映射关系就能恢复
VMP通常共用一个解释器,因此被VMP保护的函数,会被注册到同一个地址上,或者函数逻辑相似,VMP其实也是Java函数native化
会把Java指令放到so中去执行,而so中的代码就类似于解释器,解释器可以理解成把某句Java代码给解释成另一种字节码,可以理解成映射关系

dex2c:基础是编译原理,通过词法分析、语法分析等,进行Java到C的等价转换,彻底还原难度大,也就是Java代码全部变成了C,逻辑代码也都成了C代码,会有大量的JNI相关的API调用,也就是Java函数native化

dex2c通常注册在不同的地址上,并且函数逻辑不相似,开源的dex2c使用的静态注册

多种方式混合加固

先部分类VMP加固,再抽取加固,再整体加固

frida-dexdump暴力脱壳

下载dexdump https://github.com/hluwa/frida-dexdump/releases

objection运行,脱壳之前最好把app上的功能都运行一遍

下述方法一般是针对一代壳

1
2
3
4
5
6
objection -g 包名 explore 进入app进程
plugin load C:\\Users\\FRIDA-DEXDump\\fridadexdump
路径注意双\,要指定到包含init.py的目录
plugin dexdump dump 导出所有内存中的dex文件
然后把导出的所有dex文件全部打包成一个zip文件,不要用winrar打包,把zip文件丢到jadx里
最好打包之前要确保每个dex文件都是dex格式,有些情况下dex的header信息会被抹掉导致jadx无法识别,可以用010editor确定

BlackDex脱壳

开源,运行在手机上

https://github.com/hluwa/frida-dexdump/releases

丢手机上直接运行就行了