“人的一生可能根本没有分明的四季 一直在光影斑驳的林子下走走停停”
安卓加固技术发展历程:
传统App加固技术,前后经历了四代技术变更,保护级别每一代都有所提升,但其固有的安全缺陷和兼容性问题始终未能得到解决。而下一代加固技术—虚机源码保护,适用代码类型更广泛,App保护级别更高,兼容性更强,堪称未来级别的保护方案。
第一代加固技术——动态加载
第一代Android加固技术用于保护应用的逻辑不被逆向与分析,最早普遍在恶意软件中使用,其主要基于Java虚拟机(java层)提供的动态加载技术。
第二代加固技术——不落地加载
相对第一代加固技术,第二代加固技术在APK修改方面已经完善,能做到对开发的零干扰。开发过程中不需要对应用做特殊处理,只需要在最终发布前进行保护即可。而为了实现这个零干扰的流程,Loader需要处理好Android的组件的生命周期。
另一方面,不落地加载技术是在第一代加固技术的基础上改进,
主要解决第一代技术中 Payload必须释放到文件系统(俗称落地)的缺陷,
其主要的技术方案有两种:
A.拦截系统IO相关的函数(如read、write),在这些函数中提供透明加解密。具体的流程是:
1)关键逻辑(Payload)以加密的方式存储在APK中。
2)运行时加载部分(Loader〉将关键逻辑释(Payload)放到文件系统,此时关键逻辑(Payload)还处于加密状态。
3)加载部分拦截对应的系统lO函数( read,write等)。
4)加载部分(Loader)正常调用Java动态加载机制。由于虚拟机的IO部分被拦截,所以虚拟机读取到已经解密的关键逻辑(Payload) 。
B.直接调用虚拟机提供的函数进行不落地的加载,具体流程是:
1)关键逻辑(Payload)以加密的方式存储在APK中。
2)运行时加载部分(Loader)将关键逻辑释(Payload)放到内存。
3)加载部分调用虚拟机内部接口进行加载。
兼容性 方案A透明加密方案由于其需要拦截系统的IIO函数,这部分会使用inlinehook或者got hook 等技术,其会带来一定的兼容性问题 方案B的不落地加载方案由于其调需要调用系统内部的接口,而这个接口并不导出,各个厂商在实现时又有各自的自定义修改,导致该方案存在兼容性问题。 |
优缺点
和第一代加固技术的对抗方法一样,
不落地加载也无法对抗自定义虚拟机只需对上述的关键函数进行拦截
然后将对应的内存段写出去,即可恢复Payload。
注意,由于IO相关的函数被拦截,所以无法直接调用read/write 等函数进行直接的读写,
需要使用syscall.函数进行绕过。
虽然厂商会自己实现可能上述函数,从而绕过上述函数的拦截。
但是Android的类加载器必须能找到对于的结构体才能正常执行,
攻击者可以以类加载器做为起点,找到对应的Payload在内存中的位置。
第三代加固技术——指令抽离
由于第二代加固技术仅仅对文件级别进行加密,其带来的问题是内存中的Payload是连续的,可以被攻击者轻易获取。第三代加固技术对这部分进行了改进,将保护级别降到了函数级别。
发布阶段将原始DEX内的函数内容(Codeltem)清除,单独移除到一个文件中。
运行阶段将函数内容重新恢复到对应的函数体。恢复的时间点有几个方式
加载之后将函数内容恢复到虚拟机内部的结构体上:
虚拟机读取DEX文件后内部对每一个函数有一个结构体,这个结构体上有一个指针指向函数内容(Codeltem),可以通过修改这个指针修改对应的函数内容。
拦截虚拟机内与查找执行代码相关的函数,返回函数内容。
第四代加固技术
第三代加固技术在函数级别的保护,使用Android虚拟机内的解释器执行代码,带来可能被记录的缺陷,第四代加固技术使用自己的解释器来避免第三代的缺陷。而自定义的解释器无法对Android系统内的其他函数进行直接调用,必须使用JAVA的JNI接口进行调用。
不论使用指令转换/VMP加固的A方案或者B方案,其必须通过虚拟机提供的JNI接口与虚拟机进行交互,攻击者可以直接将指令转换/VMP加固方案当作黑盒,通过自定义的JNI接口对象,对黑盒内部进行探测、记录和分析,进而得到完整DEX程序。
虚机源码保护为用户提供一套完整的工具链,首先把用户待保护的核心代码编译成中间的二进制文件,随后生成独特的虚机源码保护执行环境和只能在该环境下执行的运行程序。
虚机源码保护会在App内部隔离出独立的执行环境,该核心代码的运行程序在此独立的执行环境里运行。即便App本身被破解,这部分核心代码仍然不可见。
生成的虚机源码保护拥有独特的可变指令集,极大的提高了指令跟踪、逆向分析的难度。同时,虚机源码保护还提供了反调试能力和监控能力。虚机源码保护可以通过自身的探针感知到环境的变化,实时探测到外界对本环境的调试、注入等非正常执行流程变化,将调试动作引入程序陷阱,并发出警报,进而进行实时更新,提高安全强度。
脱壳
安卓6-8:dexdump适用,2个xposed插件脱壳
安卓10:dexdump不太适用,使用frida-dexdump
https://github.coom/hluwa/frida-dexdump
DumpDex脱壳
https://github.com/WrBug/dumpDex
FDex2脱壳,在Xposed中安装FDex2
https://github.com/AndnixSH/FDex2
frida-dexdump脱壳
pip3 install frida-dexdump
然后开启frider server
frida-dexdump -FU
frida-ps -Ua 查看安装的包
frida-dexdump -U -f cc.rs.yjzh脱壳完成后会显示保存的位置
然后可以将脱出来的内容使用jadx打开查看
原文始发于微信公众号(0x00实验室):移动安全 | Android加壳和脱壳技术浅析