阶段 名称 开发过程 核心逻辑 不足 优势 破解状况 实例
一代 动态加载 程序切分成加载(Loader)与关键逻辑(Payload)两部分,并分别打包 运行时加载部分(Loader)会先运行,释放出关键逻辑(Payload),然后用java的动态加载技术进行加载,并转交控制权 1. Payload部分必须解压及释放到文件系统(直接获取) 2. 通过自定义虚拟机,截取关键函数,在加载Payload时把解密后的内容复制 加密Payload保存 目前基本上已经被破解,部分反编译工具已经集成修复功能 早期版本爱加密
二代 内存不落地加载 加载Loader,初始化StubApplication,解密和加载Payload,初始化原始Application,用原始Application代替StubApplication,最后正常加载其他组件. 1. 拦截系统IO相关函数(read,write),在这些函数中提供透明加解密. 2. 直接调用虚拟机提供的函数进行落地加载 1. 在启动过程中需要处理大量的解密操作,容易造成黑屏或假死 2.Payload被加载后,在内存中是连续的,内存dump即可直接获取.(针对关键函数进行拦截即可把内存dump) 当前市面上最为常见,通常作为一项基础性的免费服务向用户提供. 已经出现专业人士自行研究的手工脱壳方法,但尚未出现自动脱壳工具,破解难度依然比较大 市场上流行的大多数在线加固服务,如腾讯加固,360加固,百度加固,阿里聚安全,网易易盾等等
三代 指令抽取 首先,将保护级别降到函数级别,然后将原始DEX内的函数内容(Code Item)清除.单独移除到一个文件中,运行阶段将函数内容重新恢复到对应的函数体. 1. 加载之后恢复函数内容到DEX壳所在的内存区域 2. 加载之后将函数内容恢复到虚拟机内部的结构体上,虚拟机读取DEX文件后内部对每一个函数有一个结构体,这个结构体有一个指针指向函数内容(CodeItem).可以通过修改这个指针修改对应的函数内容 3. 拦截虚拟机内与查找执行代码相关的函数,返回函数内容 1. 指令抽取方案跟虚拟机的JIT性能优化冲突,达不到性能最佳的性能 2. 依然使用Java虚拟机进行函数内容执行,无法对抗自定义虚拟机. 3. 指令抽离技术使用了大量的虚拟内部结构与未文档化的特性,再加上Android复杂的厂商定制,带来大量的兼容问题. 在对自定义虚拟机记录函数执行时函数的内容,遍历触发所有的函数,从而获取全部抽离的内容,最终组装成完整的dex文件.科通过自动化完成整个过程. 部分被破解,已经出现专业人士自行研究手工破解方法,但是至今为止未出现自动脱壳工具 1. 现在免费版的 “爱加密” 2 .棒棒安全免费版
四代 指令转换 A. DEX文件内的函数被标记为native,内容被抽离并转换成一个符合JNI要求的动态库,动态库通过JNI和Android系统进行调用. B. DEX文件内的函数被标记为native,内容被抽离并转换成自定义的指令格式,该格式使用自定义接收器执行,和A一样需要使用JNI和Android系统进行交互. 1. 不论使用指令转换/VMP加固的A方案或B方案,其必须通过虚拟机提供的JNI接口与虚拟机进行交互.攻击者可以直接将指令转换/VMP加固当作黑盒,通过自定义的JNI接口对象,对黑盒内部进行探测.记录和分析,进而得到完整DEX程序 2.第四代VMP加固一般配合第三代加固技术使用,所以第三代的所有兼容问题,指令转换/VMP加固也存在 部分被破解,已经出现专业人士自行研究手工破解方法,但是至今为止未出现自动脱壳工具 大部分需要定制收费的加密服务(如爱加密,邦邦安全,中国移动加固,以及手机银行自研加固等).
五代 虚拟机保护 基于第四代方案的A方式(Java或Kotin -> C/C++),基于LLVM编译工具链(同时支持C/C++,Swift,Object-C),通过对IR执行指令转换,生成自定义指令集(IR-VM).APP内部抽离出独立的执行环境,该核心代码运行程序在此独立的执行环境里. 1. 无法摆脱对JNI的依赖,因此依然存在第四代加固技术的缺陷,存在被记录修复的可能性. 2.由Java转换成等价的C/C++,会导致体积展线性增大,性能有所下降. 1. 由Java转C/C++后的代码,由于虚拟机的保护,逆向难度会上升一个数量级. 2.对于C/C++部分逻辑,智能投入时间去破译虚拟机的指令集含义. 大多数未被破解 极为少数,需要特殊定制的加固服务,通常用于银行金融机构等关乎国家安全的重点领域.