android 加壳思路
对java及dex代码保护的技术发展:
第一代
dex文件加密,打包。在运作时通过一个自定义的类加载器进行解密。
第二代
类级别的dex保护。把需要保护的核心函数抽离出来生成另外一个文件。利用虚拟机类加载机制,在运行时调用修复函数进行修复。
第三代
将dex的核心函数抽离出来,翻译为自定义指令,运行时通过自写的解释器解释指令。
第四代
java2c,通过将核心函数转为c代码,编译为so文件。
dex文件加壳
类PE壳
dex作为android程序运行的主要文件,加壳尤为重要。从dex文件结构来看,它和windows的pe文件有许多相似之处,而且更为简单,所需数据的索引很方便。
类比PE文件,将原始数据加密后存放在文件内部,可以是尾部,也可以是头部(header结构之下)。
使程序能够正常执行,首先是用壳来解密原始数据,恢复原始程序。
放于文件尾部:
加壳程序工作流程:
1.加密源程序APK文件得到加密的数据
2.把解加密的数据写在解壳程序Dex文件末尾,并在文件尾部添加解壳数据的大小。
3.修改解壳程序DEX头中checksum.signature 和file_size头信息。
4.修改源程序AndroidMainfest.xml文件并覆盖解壳程序AndroidMainfest.xml文件。
解壳DEX程序工作流程:
1.读取DEX文件末尾数据获取加密数据长度。
2.从DEX文件读取加密数据,将数据解密。以文件形式保存解密数据到a.APK文件
3.通过DexClassLoader动态加载a.apk。
放于文件头部:
加壳程序工作流程:
1.加密源程序APK文件为解壳数据
2.计算解壳数据长度,并添加该长度到解壳DEX文件头末尾,并继续解壳数据到文件头末尾。(插入数据的位置为0x70处)
3.修改解壳程序DEX头中checksum\signature\file_size\header_size\string_ids_off\type_ids_off\proto_ids_off\field_ids_off\method_ids_off\class_defs_off和data_off相关项。 分析map_off 数据,修改相关的数据偏移量。
4.修改源程序AndroidMainfest.xml文件并覆盖解壳程序AndroidMainfest.xml文件。
解壳DEX程序工作流程:
1.从0x70处读取解壳数据长度。
2.从DEX文件读取解壳数据,解密解壳数据。以文件形式保存解密数据到a.APK
3.通过DexClassLoader动态加载a.APK。
动态加载
主要方式:
1.将核心代码编译成dex文件的Jar包
2.对jar包进行加密处理
3.在程序主入口利用NDK进行解密
4.再利用ClassLoader将jar包进行动态加载
5.利用反射技术将ClassLoader 设置成系统的ClassLoader