这个壳子经常听人说,好像是frida检测特别厉害,据说国内许多银行类app都在用。逆向了一下发现非常简单,好在实现了第三代dex加固——代码抽取,刚好论坛里缺这方面的逆向帖子,这里简单补充一下。
ida打开后发现有一个init_proc,这个函数是最早执行的,早于init_array里的函数,一般包含代码解密之类的逻辑:

第一个函数没什么用,mmap了一块空间,第二个函数点进去:

ida无法正常F5,是因为在代码里插入了数据:

不过无所谓,这部分主要是做了一下完整性检测,看看这部分代码有没有被篡改。核心是进入了sub_1095EC。
sub_1095EC主要做了以下几件事:
打开/proc/self/maps,定位到内存中的so的位置。
将so中加密的数据先解压缩,再异或解密。
将解密的数据回填到so内存。
所以这个加固的so壳非常简单,只需要在sub_1095EC执行完后,从内存中dump出so的rx段,回填即可:

回填后可以发现这个加固很多符号名都没有去除,可以说做的相当简单。没有自定义linker,就是一个最简单的内存解密+原地回填。

so脱壳后查看一下Init_array,发现只是解密了一些字符串。
查看JNI_OnLoad,没有混淆,除了注册一些native函数外,最主要的流程在key_func里:

这个加固没有ollvm混淆,脱壳后就和读源码一样容易。
比较核心的流程如下:
主要是通过openat访问/data/data/top.niunaijun.blackdexa32/.a和/data/data/top.niunaijun.blackdexa64/.a

如果存在就造crash退出:

根据配置决定是否开启检测,一般是开启,开启后会将检测函数包装在一个函数指针数组里,然后依次pthread_create:

检测函数都没有混淆,我们以其经常被讨论的frida检测为例:

主要有两种方式:
1.首先在/proc/self/maps里检查匿名内存:

如果匿名内存是elf文件,在其内存区域全量扫描以下字符串:
如果同时存在,则判定为frida。
这是在检查frida的java-bridge特征,对于frida 16以下的版本有效,frida 17以上已经移除该特征。
2.检查frida的DBUS协议:
从20000端口检查到30000端口,如果有符合frida使用的DBUS协议的端口,则检查到。
所以绕过方式只要避开20000-30000端口就行。
3.退出函数n_event:

该加固检测到异常后会走统一的退出函数,第一个参数代表异常id,第二个参数是一个随机数,用于制造随机crash退出:

每一个id都对应一个异常,id表如下:

其他的检测就不再分析了,感兴趣可以自己分析,没有混淆,字符串是inline加密的,仅此而已。可以通过查看退出函数的交叉引用,快速定位到各个监测点:

至于绕过检测,只需要让这个退出函数不走crash分支即可。
dex壳的知识点比较多,最核心的是dex文件相关的处理流程。
简单来说,andorid会将dex文件整体加载进内存,直到程序需要使用一个类的时候,才会去解析其在dex文件中具体的实现。
其中最核心的是一个类的代码,在dex文件中用code_item表示。
在dex文件的class_defines里,包含每个class对应的method,每个method指向data区的CodeItem,codeitem包含了一个函数的所有dex字节码。
如何在内存中获取到dex文件并进行修改?主要有两种方式:
1.通过Class类的dexCache获取,这种方式可以获取指定类所在的dex文件:
Java的CLass类包含了元素DexCache,DexCache包含了元素dexFile,通常为long,其值为dex文件在内存中的起始地址。
任意给一个类比如com.example.bb,通过FindClass可以获取其对应的Class类。然后依次访问上述元素,可以拿到com.example.bb类所在的dex文件:

2.通过ClassLoader → DexPathList→ dexElements[] → DexFile → mCookie,获取所有已加载的dex文件。
也可以主动构造dexfile,添加到dexElements元素列表里,这样就实现了主动加载一个dex文件。
由于不同版本andorid的实现方式不同,所以要兼容各个版本的实现。主要是mCookie的类型在变。
以上是关于dex加固加载的基础知识,接下来看看这个加固是如何加载dex的:
首先通过dexcache的方式获取当前加载到内存的dex文件:

这个文件包含了壳的代码,和加密的原app的dex文件。
通过dexdata0字符串,定位到内存中的加密数据:

例如0x44A0为加密数据的起始


接下来读取第0xc,0x10,0x14偏移处的3个4字节数,这些数是大端法表示的。
[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于 5小时前
被乐子人编辑
,原因: