Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段相关的知识,希望对你有一定的参考价值。
文章目录
一、ClassLoader 源码简介
ClassLoader
抽象类中的 private final ClassLoader parent
成员 , 用于实现双亲委派机制 , 所有的 ClassLoader
子类 , 如 PathClassLoader
, DexClassLoader
等类加载器 , 都会存在一个 ClassLoader parent
成员 , 用于表示该 类加载器 的父节点 是哪个 类加载器 ;
BootClassLoader
的 ClassLoader parent
成员是空的 , 是最顶层的类加载器 ;
注意该 ClassLoader parent
成员是 final
修饰的 , 只能进行一次赋值 ;
ClassLoader 源码参考 :
public abstract class ClassLoader
// 委托的父类加载器
// 注意:VM硬编码此字段的偏移量,因此所有新字段
// 必须在*之后添加*。
private final ClassLoader parent;
源码路径 : /libcore/ojluni/src/main/java/java/lang/ClassLoader.java
二、BaseDexClassLoader 源码简介
BaseDexClassLoader
中实现了类加载的核心业务逻辑 , 这个类很大 , 很复杂 ;
BaseDexClassLoader 源码 :
/**
* 用于各种基于dex的数据库之间的通用功能的基类
* @link ClassLoader 实现.
*/
public class BaseDexClassLoader extends ClassLoader
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
三、DexClassLoader 源码简介
DexClassLoader
继承了 BaseDexClassLoader
类 , 类中没有实现任何业务逻辑 , 只是提供了一个构造函数 ;
DexClassLoader 源码 :
/**
* 从@code.jar和@code.apk文件加载类的类加载器
* 包含@code classes.dex项。这可用于执行未作为应用程序一部分安装的代码。
*
* <p>这个类加载器需要一个应用程序私有的可写目录来缓存优化的类。
* 使用@code Context.getCodeCacheDir()创建
* 这样一个目录:<pre>@code
* File dexOutputDir = context.getCodeCacheDir();
* </pre>
*
* <p><strong>不要在外部存储上缓存优化的类。</strong>
* 外部存储不提供保护您的计算机所需的访问控制
* 防止代码注入攻击的应用程序。
*/
public class DexClassLoader extends BaseDexClassLoader
/**
* 创建一个@code-DexClassLoader来查找解释的和本机的
* 密码解释类可以在包含的一组DEX文件中找到
* 在Jar或APK文件中。
*
* <p>使用指定的字符分隔路径列表
* @code path.separator系统属性,默认为@code:。
*
* @param dexPath 包含类和
* 资源,由@code File.pathSeparator分隔,其中
* android上的默认值为@code”:“
* @param optimizedDirectory 目录,其中包含优化的dex文件
* 应该是书面的;不能为@code null
* @param librarySearchPath 包含本机
* 库,由@code File.pathSeparator分隔;可能是
* @code null
* @param parent 父类加载器
*/
public DexClassLoader(String dexPath, String optimizedDirectory,
String librarySearchPath, ClassLoader parent)
super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java
四、PathClassLoader 源码简介
PathClassLoader
继承了 BaseDexClassLoader
类 , 类中没有实现任何业务逻辑 , 只是提供了一个构造函数 ;
PathClassLoader 源码 :
/**
* 提供对列表进行操作的简单@link ClassLoader实现
* 本地文件系统中的文件和目录,但不尝试
* 从网络加载类。Android将该类用作其系统类
* 加载器及其应用程序类加载器。
*/
public class PathClassLoader extends BaseDexClassLoader
/**
* 创建一个@code PathClassLoader,它在给定的文件列表上运行
* 和目录。此方法相当于调用
* @link#PathClassLoader(String,String,ClassLoader)与
* 第二个参数的@code null值(请参见此处的说明)。
*
* @param dexPath 包含类和
* 资源,由@code File.pathSeparator分隔,其中
* Android上的默认值为@code”:“
* @param parent 父类加载器
*/
public PathClassLoader(String dexPath, ClassLoader parent)
super(dexPath, null, null, parent);
/**
* 创建一个@code PathClassLoader,它在两个给定的
* 文件和目录的列表。第一个列表的条目
* 应为以下内容之一:
*
* <ul>
* <li>JAR/ZIP/APK文件,可能包含“classes.dex”文件
* 以及任意资源。
* <li>原始“.dex”文件(不在zip文件中)。
* </ul>
*
* 第二个列表的条目应该是包含
* 本机库文件。
*
* @param dexPath 包含类和
* 资源,由@code File.pathSeparator分隔,其中
* Android上的默认值为@code”:“
* @param librarySearchPath 包含本机
* 库,由@code File.pathSeparator分隔;可能是
* @code null
* @param parent 父类加载器
*/
public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent)
super(dexPath, null, librarySearchPath, parent);
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
五、InMemoryDexClassLoader 源码简介
InMemoryDexClassLoader
类加载器 继承了 BaseDexClassLoader
类 , 与 PathClassLoader
, DexClassLoader
类似 , 只提供了构造函数 , 没有实现业务逻辑 ;
InMemoryDexClassLoader
主要用于加载内存中的 Dex 字节码文件 , 在 Android
8.0
8.0
8.0 中加入到系统中 ;
InMemoryDexClassLoader 源码 :
/**
* 一个@link ClassLoader实现,从
* 包含DEX文件的缓冲区。这可用于执行以下代码:
* 尚未写入本地文件系统。
*/
public final class InMemoryDexClassLoader extends BaseDexClassLoader
/**
* 使用给定的DEX缓冲区创建内存中的DEX类装入器。
*
* @param dexBuffers 包含之间的DEX文件的缓冲区数组
* <tt>buffer.position()</tt>和<tt>buffer.limit()</tt>。
* @param parent 委托的父类加载器。
* @隐藏
*/
public InMemoryDexClassLoader(ByteBuffer[] dexBuffers, ClassLoader parent)
super(dexBuffers, parent);
/**
* 创建一个新的内存中DEX类装入器。
*
* @param dexBuffer 缓冲区,包含之间的DEX文件内容
* <tt>buffer.position()</tt>和<tt>buffer.limit()</tt>。
* @param parent 委托的父类加载器。
*/
public InMemoryDexClassLoader(ByteBuffer dexBuffer, ClassLoader parent)
this(new ByteBuffer[] dexBuffer , parent);
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/InMemoryDexClassLoader.java
以上是关于Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向类加载器 ClassLoader ( 启动类加载器 | 扩展类加载器 | 应用类加载器 | 类加载的双亲委托机制 )
Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段
Android 逆向加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程
Android 逆向加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程
Android 逆向整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 类加载器构造函数分析 | DexPathList 引入 )
Android 逆向类加载器 ClassLoader ( 类加载时机 | 隐式加载 | 显示加载 | 类加载步骤 | 装载 | 链接 | 初始化 )