Android ART流程与脱壳分析
简介
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返回的就是它
双亲委派模式的工作原理为:首先检查这个类是不是已经被加载过了,如果加载过了直接返回,否则委派给父加载器加载,这是一个递归调用,一层一层向上委派,最顶层的类加载器(启动类加载器)无法加载该类时,再一层一层向下委派给子类加载器加载。通俗来讲,即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法完成,这就是双亲委派。
意义:
- 避免重复加载,如果已经加载过一次Class,可以直接读取
- 更加安全,无法自定义类来替换系统类,防止核心API被篡改
类加载
类加载的时机:
- 隐式加载:创建类的实例;访问类的静态变量,或者为静态变量赋值;调用类的静态方法;初始化子类;使用反射强制创建某个类或接口对应的 java.lang.Class 对象
- 显示加载:使用LoadClass() 加载;使用 forName() 加载;
Android 中的类加载器
BootClassLoader:预加载常用类,单例模式,Java实现
BaseDexClassLoader: PathClassLoader,DexClassLoader,InMemoryDexClassLoader父类
PathClassLoader:Android默认类加载器,例如未加壳App的Activity就是由PathClassLoader加载