区块链技术博客
www.b2bchain.cn

【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

这篇文章主要介绍了【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )的讲解,通过具体代码实例进行16755 讲解,并且分析了【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )的详细步骤与相关技巧,需要的朋友可以参考下https://www.b2bchain.cn/?p=16755

本文实例讲述了2、树莓派设置连接WiFi,开启VNC等等的讲解。分享给大家供大家参考文章查询地址https://www.b2bchain.cn/7039.html。具体如下:

文章目录

  • 一、65535 方法数限制和 MultiDex 配置
  • 二、多 DEX 加载引入
  • 三、PathClassLoader 类加载源码分析
  • 四、BaseDexClassLoader 类加载源码分析
  • 五、DexPathList 相关载源码分析
  • 六、多 DEX 存放位置

一、65535 方法数限制和 MultiDex 配置


在 Android 开发中 , 尤其是项目比较大时 , 或引入的依赖库过多 , 一般的项目后期都会遇到 如下问题 , 整个工程的方法数超过了 65535 65535 65535 个 , 编译时报如下错误 :

trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.  Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536 

Google 官方给出了解决方案 : https://developer.android.google.cn/studio/build/multidex.html

5.0 5.0 5.0 之前的版本 , 应用中只能使用单个 classes.dex , 5.0 5.0 5.0 及以后的版本 原生支持多个 classes.dex 文件 ;

如果最低版本号大于等于 21 21 21 , 就可以不用配置 MultiDex ;

反之版本号小于 21 21 21 , 则 必须进行 MultiDex 配置 ;

Google 提供的 com.android.support:multidex 库 , 就是为了兼容 5.0 5.0 5.0 之前的版本 ;

二、多 DEX 加载引入


MultiDexApplication 中就使用 Android 中的类加载机制 , ClassLoader 加载机制 ;

ClassLoader 相关源码在 libcore/dalvik/src/main/java/dalvik/system Android 源码目录下 ,

【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

参考 : libcore/dalvik/src/main/java/dalvik/system

常用的 ClassLoader 是 PathClassLoaderDexClassLoader ;

PathClassLoader 只能加载 已安装 apk 的 dex ;

DexClassLoader 可以加载 已安装文件系统 中的 APK , DEX , JAR ;

源码参考 :

  • PathClassLoader : libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
  • DexClassLoader : libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java

三、PathClassLoader 类加载源码分析


在 Android 中使用的是 PathClassLoader , 该类很简单 , 只是单纯的继承 BaseDexClassLoader ,

package dalvik.system;  public class PathClassLoader extends BaseDexClassLoader {     public PathClassLoader(String dexPath, ClassLoader parent) {         super(dexPath, null, null, parent);     }     public PathClassLoader(String dexPath, String libraryPath,             ClassLoader parent) {         super(dexPath, null, libraryPath, parent);     } } 

参考源码地址 : libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java

四、BaseDexClassLoader 类加载源码分析


BaseDexClassLoader 是通过 Class<?> findClass(String name) 方法查找类的 , 给定一个全类名字符串 , 返回字节码 ,

查找类通过调用 pathList 的 findClass 方法 , 获取字节码文件 ,

pathList 对应的成员变量定义是 DexPathList pathList , 它是 DexPathList 类型的 ,

public class BaseDexClassLoader extends ClassLoader {     private final DexPathList pathList;     @Override     protected Class<?> findClass(String name) throws ClassNotFoundException {         List<Throwable> suppressedExceptions = new ArrayList<Throwable>();         Class c = pathList.findClass(name, suppressedExceptions);         if (c == null) {             ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class "" + name + "" on path: " + pathList);             for (Throwable t : suppressedExceptions) {                 cnfe.addSuppressed(t);             }             throw cnfe;         }         return c;     } } 

参考源码地址 : libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java

五、DexPathList 相关载源码分析


DexPathList 的 findClass 方法 , 主要是遍历 Element[] dexElements 成员 ,

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

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

调用 DexFile 的 loadClassBinaryName 加载对应的类 ,

/*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

六、多 DEX 存放位置


上述 DexPathList 中的 Element[] dexElements 成员就保存了当前应用中的 DEX 文件 ,

再次回到 classes.dex 分割的问题上 , 如果我们设置一个主 DEX , 其中只存在代理 Application , 用于解密其它被加密的 DEX , 其它的 DEX 都是被加密的 ;

这些 DEX 文件 都需要被存放到上述 DexPathList 的 Element[] dexElements 数组中 ;

本文转自互联网,侵权联系删除【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们