Android ART流程与脱壳分析

系列 - 脱壳
注意
本文最后更新于 2022-08-22,文中内容可能已过时。

简介

Android 平台主流APP代码绝大多数由java(kotlin)代码以及C/C++甚至汇编组成,java代码经过编译器编译生成dex文件,c/c++以及汇编经过编译器生成so文件。要梳理APP的执行逻辑,重点要关注其dex文件。

dex保护技术发展: dex整体加固保护 -> 函数粒度保护 -> smali指令粒度保护

整体型壳的核心原理

针对dex整体加固保护的主要技术可大致分为两类:dex文件加载和dex内存加载,但本质上都是dex动态加载

JVM的类加载器包括3种:

  • Bootstrap ClassLoader(引导类加载器)

​ C/C++ 代码实现的加载器,用于加载指定的 JDK 的核心类库,比如 java.lang.,java.util.等这些系统类。Java虚拟机的启动就是通过Bootstrap,该ClassLoader在java里无法获取,负责加载 /lib 下的类。

  • Extensions ClassLoader(拓展类加载器)

​ Java 中的实现类为 ExtClassLoader,提供除了系统类之外的额外功能,可以在 java 里获取,负责实现 /lib/ext 下的类

  • Application ClassLoader(应用程序类加载器)

​ Java 中的实现类为 AppClassLoader,是与我们接触最多大的类加载器,App代码默认就是由它来加载,使用 ClassLoader.getSystemClassLoader返回的就是它

/images/android_art_protect_1/image-20220810221842434.png

双亲委派模式的工作原理为:首先检查这个类是不是已经被加载过了,如果加载过了直接返回,否则委派给父加载器加载,这是一个递归调用,一层一层向上委派,最顶层的类加载器(启动类加载器)无法加载该类时,再一层一层向下委派给子类加载器加载。通俗来讲,即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法完成,这就是双亲委派。

意义:

  • 避免重复加载,如果已经加载过一次Class,可以直接读取
  • 更加安全,无法自定义类来替换系统类,防止核心API被篡改

类加载的时机:

  1. 隐式加载:创建类的实例;访问类的静态变量,或者为静态变量赋值;调用类的静态方法;初始化子类;使用反射强制创建某个类或接口对应的 java.lang.Class 对象
  2. 显示加载:使用LoadClass() 加载;使用 forName() 加载;

BootClassLoader:预加载常用类,单例模式,Java实现

BaseDexClassLoader: PathClassLoader,DexClassLoader,InMemoryDexClassLoader父类

PathClassLoader:Android默认类加载器,例如未加壳App的Activity就是由PathClassLoader加载