Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )(代码
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )(代码相关的知识,希望对你有一定的参考价值。
前言
上一篇博客 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | ClassLoader#loadClass 函数分析 | BaseDexClassLoader#findClass 分析 ) 分析到 , 类加载流程中 , 在 BaseDexClassLoader 中的 findClass 方法中 , 主要调用 DexPathList pathList 成员的 findClass 函数查找类 ;
一、DexPathList.java#findClass 类加载函数源码分析
在 DexPathList.java#findClass 方法中 ,
首先 , 遍历 Element[] dexElements 成员 , 每个 Element 元素都封装了一个 DexFile , 即 dex 文件 ;
DexFile dex = element.dexFile;
然后尝试从 dex 文件中加载 Java 类 ;
Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
DexPathList.java#findClass 类加载函数源码 :
/**
* 一对条目列表,与@code ClassLoader关联。
* 其中一个列表是索引/资源路径—通常提及
* 作为“类路径”—列表和其他名称目录
* 包含本机代码库。类路径条目可以是以下任一项:
* 一个@code.jar或@code.zip文件,其中包含一个可选的
* 顶级@code classes.dex文件以及任意资源,
* 或者是一个普通的@code.dex文件(不可能与
* 资源)。
*
* <p>此类还包含使用这些列表进行查找的方法
* 课程和资源</p>
*/
/*package*/ final class DexPathList
/**
* 索引/资源(类路径)元素的列表。
* 应该称为pathElements,但Facebook应用程序使用反射
* 要修改“dexElements”(http://b/7726934).
*/
private final Element[] dexElements;
/**
* 在所指向的某个dex文件中查找命名类
* 这个例子。这将在最早的列表中找到一个
* 路径元素。如果已找到类但尚未找到
* 已定义,则此方法将在定义中定义它
* 构造此实例时使用的上下文。
*
* @param要查找的类的名称
* @param查找类时遇到抑制异常
* @返回已命名的类或@code null(如果该类不是空的)
* 在任何dex文件中找到
*/
public Class findClass(String name, List<Throwable> suppressed)
// 对 DexPathList 中的 Element 数组进行遍历
for (Element element : dexElements)
// 每个 Element 元素都封装了一个 DexFile , 即 dex 文件
DexFile dex = element.dexFile;
if (dex != null)
// 尝试从 dex 文件中加载 Java 类
// ★ 核心跳转
Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
if (clazz != null)
return clazz;
if (dexElementsSuppressedExceptions != null)
suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
return null;
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/DexPathList.java#findClass
二、DexFile.java#loadClassBinaryName 函数源码分析
在 DexFile.java#loadClassBinaryName 函数中 , 调用了 defineClass 方法 , 在 defineClass
方法中 , 调用了 native 函数 defineClassNative ;
在 DexFile.java 的 loadClass 函数中 , 也会调用 DexFile.java#loadClassBinaryName 函数 , 进行类的加载 ;
DexFile.java#loadClassBinaryName 函数源码 :
/**
* 操纵DEX文件。这门课在原则上与我们的课相似
* @link java.util.zip.ZipFile。它主要由类装入器使用。
* <p>
* 注意,我们不直接打开并读取这里的DEX文件。它们是内存映射的
* 由VM只读。
*/
public final class DexFile
/**
* 加载一个类。成功返回类或@code null引用
* 一旦失败。
* <p>
* 如果不是从类加载器调用此函数,则很可能不是
* 去做你想做的事。改用@link Class#forName(String)。
* <p>
* 如果类
* 找不到,因为在每个
* 在我们查看的第一个DEX文件中找不到类的时间。
*
* @param name
* 类名,看起来应该像“java/lang/String”
*
* @param装载机
* 尝试加载类的类加载器(在大多数情况下
* 方法的调用方
*
* @返回表示类的@link Class对象,或@code null
* 如果无法加载该类
*/
public Class loadClass(String name, ClassLoader loader)
String slashName = name.replace('.', '/');
return loadClassBinaryName(slashName, loader, null);
/**
* 请参阅@link#loadClass(String,ClassLoader)。
*
* 这需要一个“二进制”类名来更好地匹配类加载器语义。
*
* @隐藏
*/
public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed)
return defineClass(name, loader, mCookie, suppressed);
private static Class defineClass(String name, ClassLoader loader, int cookie,
List<Throwable> suppressed)
Class result = null;
try
result = defineClassNative(name, loader, cookie);
catch (NoClassDefFoundError e)
if (suppressed != null)
suppressed.add(e);
catch (ClassNotFoundException e)
if (suppressed != null)
suppressed.add(e);
return result;
// ★ 核心跳转
private static native Class defineClassNative(String name, ClassLoader loader, int cookie)
throws ClassNotFoundException, NoClassDefFoundError;
源码路径 : /libcore/dalvik/src/main/java/dalvik/system/DexFile.java#loadClassBinaryName
以上是关于Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )(代码的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative 函数 )(代
Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )(代码
Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | Class.cpp#findClassNoInit 函数 | DexFile.cpp#dexFindClass 函数分析 )(代
Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | ClassLoader#loadClass 函数分析 | BaseDexClassLoader#findClass 分析 )(代
Android 逆向ART 函数抽取加壳 ⑥ ( 函数抽取后续操作 “ 还原被抽取的函数 “ | LoadClass 类加载 | LoadClassMembers 类成员加载 )
Android 逆向加壳技术识别 ( 函数抽取 与 Native 化加壳的区分 | VMP 加壳与 Dex2C 加壳的区分 )