文章目录

  • 一、 PathClassLoader 加载 Dex 机制
  • 二、 PathDexList 查找 Class 机制
  • 三、 类查找的顺序机制

一、 PathClassLoader 加载 Dex 机制


Android 中 Class 加载机制 :

Java 代码运行时 , 使用 ClassLoader 加载 Class 字节码文件 , Class 字节码文件 , Jar 文件 , Dex 文件 , 都必须加载到内存中 ;

在 Android 平台中 , Android 应用运行时 , 使用 PathClassLoader 加载 Dex 文件 , 在应用启动时 , 首先将若干 Dex 文件加载到内存中 ;

一个 Android 应用中可以存在多个 Dex 文件 , 参考 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList ) 博客 ,

二、 PathDexList 查找 Class 机制


当应用运行时调用到某类 A.class 时 , 会通过 PathClassLoader 加载该类 , PathClassLoader 是一个包装类 , 其中封装了 PathDexList 类 , 该类中的 Element[] dexElements 成员存放着多个 Dex 文件 ;

每个 Dex 文件中封装了多个 Class 字节码文件 ; 查找某个具体的 A.class 时 , 主要是通过 DexPathList 的 findClass 方法 , 遍历 Element[] dexElements 成员 ,

Element[] dexElements 数组中保存的就是内存中的 DEX 文件 , 如果 APP 中有 333 个 DEX 文件 , 那么该数组就有 333 个元素 ;

然后逐个遍历 获取该 element 中的 dexFile , 这是 DexFile 类型文件 ,

调用 DexFile 的 loadClassBinaryName 加载对应的 A.class 类 , 如果找到了 A.class 类 , 直接返回 ; 如果没有找到 , 则继续遍历下一个 Element[] dexElements 元素 ;

/*package*/ final class DexPathList {/*** dex/resource (class path) 元素集合.* 应该调用 pathElements , 但是 Facebook 应用通过反射修改 dexElements .*/private final Element[] dexElements;public Class findClass(String name, List<Throwable> suppressed) {for (Element element : dexElements) {DexFile dex = element.dexFile;if (dex != null) {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

三、 类查找的顺序机制


在 PathDexList 查找 Class 中 , DexPathList 的 findClass 方法遍历 Element[] dexElements 数组永远都是从 000 索引开始 , 向后遍历 , 其中就隐含着 Dex 文件搜索的顺序机制 ;

顺序机制 : 如果在第 222 个 Dex 文件 和 第 333 个 Dex 文件中都包含该 A.class 字节码文件 , 则只会返回第 222 个 Dex 文件中的类 , 遍历到此处就返回了 , 不会去遍历到低 333 个 Dex 文件 ;

利用上述顺序加载的机制 , 将修复包的 dex 文件放在前面 , 就可以屏蔽后面出现问题的类 ;

示例 :

在已经发布的应用中 , 有 333 个 Dex 文件 , 其中第 222 个 Dex 文件中的 A.class 字节码类中出现了崩溃问题 , 这里我们将修复好的 A.class 文件打包成 Dex 文件 , 将其插入到原来第 111 个和第 222 个 Dex 文件之间 , 这样在类加载器加载 A.class 类时 , 按照顺序先把修复的 Dex 文件加载到内存中 , 不再向后查找第 333 个 Dex 文件中出现崩溃的 A.class 类了 ;

热修复只是在前面插入一个修复好的 Dex 文件 , 不会删除出现问题的 Dex 文件 ;

第 111 个 Dex 文件一定不能出现问题 , 如果出现问题 , 就无法在该 Dex 文件之气前插入 Dex 文件 , 这个主 Dex 文件中有 Application , MainActivity 等相关重要组件 , 无法进行替换 ;

如果第 111 个 Dex 文件出现问题 , 只能发布新版本 ;

实际上热修复机制属于一种利用漏洞的机制 , Google 没有正面支持该功能 , iOS 中就关闭了热修复功能 ;

【Android 热修复】热修复原理 ( 类加载机制 | PathClassLoader 加载 Dex 机制 | PathDexList 查找 Class 机制 | 类查找的顺序机制 )相关推荐

  1. 【Android 热修复】热修复原理 ( 合并两个 Element[] dexElements | 自定义 Application 加载 Dex 设置 | 源码资源 )

    文章目录 一.合并两个 Element[] dexElements 二. 完整修复包加载工具类 三. 源码资源 一.合并两个 Element[] dexElements 在 [Android 热修复] ...

  2. Android 框架学习5:微信热修复框架 Tinker 从使用到 patch 加载、生成、合成原理分析

    这篇文章是基于内部分享的逐字稿内容整理的,现在比较喜欢写逐字稿,方便整理成文章. 文章目录 目录 Tinker 介绍 使用 TinkerApplicaition ``SampleApplicaitio ...

  3. Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)

    一.前言 时隔半年,困扰的问题始终是需要解决的,之前也算是没时间弄,今天因为有人在此提起这个问题,那么就不能不解决了,这里写一篇文章记录一下吧.那么是什么问题呢? 就是关于之前的一个话题:Androi ...

  4. JVM 类加载机制与加载过程

    JVM的类加载机制:在代码编译后,就会生成JVM(Java虚拟机)能够识别的二进制字节流文件(*.class).而JVM把Class文件中的类描述数据从文件加载到内存,并对数据进行校验.转换解析.初始 ...

  5. 29.类加载机制、类加载过程、加载、验证、准备、解析、初始化、总结

    29.类加载机制 29.1.类加载过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 其中类加载 ...

  6. JVM类加载、加载机制、加载器

    一.类加载过程 类的7个生命周期:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 1.加载 加载阶段主要做三件事: 1)加载指的是将 ...

  7. 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 类加载器构造函数分析 | DexPathList 引入 )

    文章目录 一.DexClassLoader 类加载器构造函数分析 二.DexPathList 引入 一.DexClassLoader 类加载器构造函数分析 DexClassLoader 是加载 dex ...

  8. 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )

    文章目录 前言 一.DexFile.loadDexFile 函数分析 二.DexFile 构造函数分析 三.DexFile.openDexFile 函数分析 前言 上一篇博客 [Android 逆向] ...

  9. 【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 将系统的 dexElements 与 应用的 dexElements 合并 | 替换操作 )

    文章目录 一.将系统的 dexElements 与 应用的 dexElements 合并 二.Element[] dexElements 替换操作 三.完整 dex 加载源码 参考博客 : [Andr ...

最新文章

  1. QWidget子窗口中setStyleSheet无效,解决方法
  2. jQuery_2_常规选择器-进阶选择器
  3. 如何设置Windows版Go —快速简便的指南
  4. 敲了几年代码,是时候考虑以后的发展了
  5. elif else if oracle_shell中if做比较
  6. GitHub For Beginners: Don’t Get Scared, Get Started
  7. MYSQL锁表的用法,防止并发情况下的重复数据
  8. Web of science(WOS)引文跟踪
  9. JavaScript引入的三种方式(附实例)
  10. iOS性能优化-列表卡顿
  11. 三角函数π/2转化_浅谈三角函数导数综合题(1)
  12. Word中插入分隔线
  13. Hyperledger Fabric定制联盟链网络工程实践
  14. Web安全之常见面试题总结
  15. 2016面试总结,面试宝典有木有
  16. 柱状图python_化学领域里「过柱子」是什么意思?柱子干了为什么可怕?
  17. elang 字符处理
  18. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——3.2 动态数据流...
  19. Windows 10家庭中文版中启用WSL 2
  20. 【学习笔记】:Multi-mode Transformer Transducer with Stochastic Future Context

热门文章

  1. gsoap中的数据结构中不允许有野指针
  2. 【BZOJ5461】 【PKUWC2018】—Minimax(线段树合并优化dp)
  3. 漫画算法:什么是一致性哈希?
  4. jexus防止产生 *.core文件
  5. 不能解决,复选框在request对象获取的信息后显示在用户信息里面为中文的选项名...
  6. AngularJS之禅
  7. [NOI2007]货币兑换Cash(DP+动态凸包)
  8. php 对接中国天气网 城市 id json串
  9. Spring使用支付宝扫码支付
  10. 移动端以刻度或尺度滑动方式选择年龄收入等