Android DEX加固方案与原理

Android 反编译的威胁

逆向分析: 漏洞挖掘、协议分析
二次打包: 盗版、破解、广告

保护方案

代码混淆:Java代码、C\C++带马甲、JS\HTML代码
应用加固:DEX文件、SO文件、资源文件

APP构建过程中用到的工具

Android DEX加固方案与原理_第1张图片

编译流程

  • java源码编译:通过javac将源码编译为.class文件
  • 多dex分包:脚本将类根据一定规则划分到主dex和从dex中,生成配置文件
  • proguard优化/混淆:对.class文件进行压缩、优化、混淆处理
  • 转化为dex文件:dx\d8将.class文件转换为dex文件

DEX加固方案的演进

Android DEX加固方案与原理_第2张图片

  • 动态加载:从服务器动态加载业务的DEX
  • DEX内存加载:模拟App启动的时候,将我们的壳、将业务DEX文件加载到内存中,然后通过一些处理方式,让DEX文件把Application启动起来,让应用认为和普通的启动方式是一样的 (缺点:DEX会暴露在内存中)
  • DEX指令抽取:把DEX文件中的一些方法的指令抽取出来,然后在内存中开辟一段区域,然后将我们内存加载的DEX解析到相应的方法指令偏移的地方,方法指令的偏移指向我们开辟的一段内存里面。(缺点:不彻底)
  • 虚拟机加固:我们通过自己实现一套虚拟机,将DEX方法的指令抽取出来,在运行的时候,我们的虚拟机里面就运行被抽取的一段指令。这样攻击者想要破解,首先必须要找到我们虚拟机的入口,将虚拟机整个逻辑还原出来,这样攻击成本相对比较高 (缺点:本身Android应用就运行在虚拟机里面,不论是Dalvik还是ART,增加个虚拟机,就会增加一层对应用运行时代码的解释执行操作,那么解释执行的效率会大大下降)
  • JAVA2C:提升应用运行时的效率,我们的方法会转换为一层在Native(JNI)上实现的逻辑,最终通过JNI编译成so,这样的话在本地执行,而不是在虚拟机执行,执行效率会大大提升。

DEX内存加载实现原理

框架原理

Android加壳框架原理为Proxy/Delegate Application,即使用自定义的代理Application类作为程序入口(修改AndroidManifest.xml),在代理Application中完成壳的解密操作,最后启动原来的Application

ProxyApplication:框架会提供一个ProxyApplication抽象基类(abstract class),使用者需要继承这个类,并重载initProxyApplication()方法,在其中改变surrounding,如替换ClassLoader等
DelegateApplication:即应用原有的Application,应用从getApplicationContext()等方法中取到的都是DelegateApplication

修改入口

将Manifest中application改为ProxyApplication

代理Application

在ProxyApplication中实现如下内容

  • 内存加载DEX:加载原Application
  • ClassLoader设置
  • Application引用替换

壳启动流程

  • 内存加载DEX文件:通过Dalvik、ART虚拟机JNI接口内存加载被加密隐藏的DEX文件
  • 设置ClassLoader:将DEX文件内存加载产生的mCookie放入ClassLoader中(MutiDex)
  • 加载原Application:基于替换后的ClassLoader查找原始Application类并生成实例
  • Application还原:将API层的所有Application引用替换为原始Application

你可能感兴趣的:(Android深度)