【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )
文章目錄
- 一、不同 Android 系統創建 dex 數組源碼對比
- 二、不同 Android 系統創建 dex 數組源碼對比
- 三、 Android 5.1 及以下系統反射方法并創建 Element[] dexElements
- 四、 Android 6.0 及以下系統反射方法并創建 Element[] dexElements
- 五、 完整代碼示例
參考博客 :
- 【Android 安全】DEX 加密 ( 常用 Android 反編譯工具 | apktool | dex2jar | enjarify | jd-gui | jadx )
- 【Android 安全】DEX 加密 ( Proguard 簡介 | Proguard 相關網址 | Proguard 混淆配置 )
- 【Android 安全】DEX 加密 ( Proguard 簡介 | 默認 ProGuard 分析 )
- 【Android 安全】DEX 加密 ( Proguard keep 用法 | Proguard 默認混淆結果 | 保留類及成員混淆結果 | 保留注解以及被注解修飾的類/成員/方法 )
- 【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的報錯信息 | Proguard 混淆映射文件 mapping.txt )
- 【Android 安全】DEX 加密 ( Proguard 混淆 | 將混淆后的報錯信息轉為原始報錯信息 | retrace.bat 命令執行目錄 | 暴露更少信息 )
- 【Android 安全】DEX 加密 ( DEX 加密原理 | DEX 加密簡介 | APK 文件分析 | DEX 分割 )
- 【Android 安全】DEX 加密 ( 多 DEX 加載 | 65535 方法數限制和 MultiDex 配置 | PathClassLoader 類加載源碼分析 | DexPathList )
- 【Android 安全】DEX 加密 ( 不同 Android 版本的 DEX 加載 | Android 8.0 版本 DEX 加載分析 | Android 5.0 版本 DEX 加載分析 )
- 【Android 安全】DEX 加密 ( DEX 加密使用到的相關工具 | dx 工具 | zipalign 對齊工具 | apksigner 簽名工具 )
- 【Android 安全】DEX 加密 ( 支持多 DEX 的 Android 工程結構 )
- 【Android 安全】DEX 加密 ( 代理 Application 開發 | multiple-dex-core 依賴庫開發 | 配置元數據 | 獲取 apk 文件并準備相關目錄 )
- 【Android 安全】DEX 加密 ( 代理 Application 開發 | 解壓 apk 文件 | 判定是否是第一次啟動 | 遞歸刪除文件操作 | 解壓 Zip 文件操作 )
- 【Android 安全】DEX 加密 ( 代理 Application 開發 | 加載 dex 文件 | 反射獲取系統的 Element[] dexElements )
- 【Android 安全】DEX 加密 ( 代理 Application 開發 | 加載 dex 文件 | 使用反射獲取方法創建本應用的 dexElements | 各版本創建 dex 數組源碼對比 )
在 【Android 安全】DEX 加密 ( 支持多 DEX 的 Android 工程結構 ) 博客中介紹了 DEX 加密工程的基本結構 ,
app 是主應用 , 其 Module 類型是 “Phone & Tablet Module” ,
multiple-dex-core 是 Android 依賴庫 , 其作用是解密并加載多 DEX 文件 , 其 Module 類型是 “Android Library” ,
multiple-dex-tools 是 Java 依賴庫 , 其類型是 “Java or Kotlin Library” , 其作用是用于生成主 DEX ( 主 DEX 的作用就是用于解密與加載多 DEX ) , 并且還要為修改后的 APK 進行簽名 ;
在 【Android 安全】DEX 加密 ( 代理 Application 開發 | multiple-dex-core 依賴庫開發 | 配置元數據 | 獲取 apk 文件并準備相關目錄 ) 博客中講解了 multiple-dex-core 依賴庫開發 , 每次啟動都要解密與加載 dex 文件 , 在該博客中講解到了 獲取 apk 文件 , 并準備解壓目錄 ;
在 【Android 安全】DEX 加密 ( 代理 Application 開發 | 解壓 apk 文件 | 判定是否是第一次啟動 | 遞歸刪除文件操作 | 解壓 Zip 文件操作 ) 博客中講解了 apk 文件解壓操作 ;
在 【Android 安全】DEX 加密 ( 代理 Application 開發 | 加載 dex 文件 | 反射獲取系統的 Element[] dexElements )博客中講解了 dex 文件加載第一階段 , 獲取系統中的 Element[] dexElements ;
本博客中主要講解 dex 文件加載操作 第二階段 , 創建本應用的 dex 文件數組 Element[] dexElements ;
一、不同 Android 系統創建 dex 數組源碼對比
Android4.4(KitKatAPI19)\rm Android \ 4.4 \ ( KitKat \ API \ 19 )Android?4.4?(KitKat?API?19) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String libraryPath, File optimizedDirectory) {this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);}/*** 創建一個數組 , 每個數組元素都是 dex 路徑名稱 .*/private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,ArrayList<IOException> suppressedExceptions) {} }參考 : 4.4.4_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android4.4W(KitKatWatchAPI20)\rm Android \ 4.4W \ ( KitKat Watch \ API \ 20 )Android?4.4W?(KitKatWatch?API?20) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String libraryPath, File optimizedDirectory) {this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);}/*** 創建一個數組 , 每個數組元素都是 dex 路徑名稱 .*/private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,ArrayList<IOException> suppressedExceptions){} }參考 : 4.4w_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android5.0(LollipopAPI21)\rm Android \ 5.0 \ ( Lollipop \ API \ 21 )Android?5.0?(Lollipop?API?21) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String libraryPath, File optimizedDirectory) {this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);}/*** 創建一個數組 , 每個數組元素都是 dex 路徑名稱 .*/private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,ArrayList<IOException> suppressedExceptions){} }參考 : 5.0.1_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android5.1(LollipopAPI22)\rm Android \ 5.1 \ ( Lollipop \ API \ 22 )Android?5.1?(Lollipop?API?22) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String libraryPath, File optimizedDirectory) {this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);}/*** 創建一個數組 , 每個數組元素都是 dex 路徑名稱 .*/private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,ArrayList<IOException> suppressedExceptions){} }參考 : 5.1.0_r3/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android6.0(MarshmallowAPI23)\rm Android \ 6.0 \ (Marshmallow \ API \ 23 )Android?6.0?(Marshmallow?API?23) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String libraryPath, File optimizedDirectory) {// save dexPath for BaseDexClassLoaderthis.dexElements = makePathElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions);}/*** 創建一個數組 , 每個數組元素都是 dex 路徑名稱 .*/private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {} }參考 : 6.0.1_r16/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android7.0(NougatAPI24)\rm Android \ 7.0 \ ( Nougat \ API \ 24 )Android?7.0?(Nougat?API?24) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String librarySearchPath, File optimizedDirectory) {// save dexPath for BaseDexClassLoaderthis.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions, definingContext);}private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions,ClassLoader loader) {}/*** Makes an array of directory/zip path elements, one per element of the given array.*/private static Element[] makePathElements(List<File> files,List<IOException> suppressedExceptions,ClassLoader loader) {return makeElements(files, null, suppressedExceptions, true, loader);}/** TODO (dimitry): Revert after apps stops relying on the existence of this* method (see http://b/21957414 and http://b/26317852 for details)*/private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeElements(files, optimizedDirectory, suppressedExceptions, false, null);} }參考 : 7.0.0_r31/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android7.1(NougatAPI25)\rm Android \ 7.1 \ ( Nougat \ API \ 25 )Android?7.1?(Nougat?API?25) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String librarySearchPath, File optimizedDirectory) {// save dexPath for BaseDexClassLoaderthis.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions, definingContext);}private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions,ClassLoader loader) {}/*** Makes an array of directory/zip path elements, one per element of the given array.*/private static Element[] makePathElements(List<File> files,List<IOException> suppressedExceptions,ClassLoader loader) {return makeElements(files, null, suppressedExceptions, true, loader);}/** TODO (dimitry): Revert after apps stops relying on the existence of this* method (see http://b/21957414 and http://b/26317852 for details)*/private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeElements(files, optimizedDirectory, suppressedExceptions, false, null);} }參考 : 7.1.1_r28/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android8.0(OreoAPI25)\rm Android \ 8.0 \ ( Oreo \ API \ 25 )Android?8.0?(Oreo?API?25) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String librarySearchPath, File optimizedDirectory) {// save dexPath for BaseDexClassLoaderthis.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions, definingContext);}private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions,ClassLoader loader) {}/** TODO (dimitry): Revert after apps stops relying on the existence of this* method (see http://b/21957414 and http://b/26317852 for details)*/@SuppressWarnings("unused")private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, null);}/*** Makes an array of directory/zip path elements for the native library search path, one per* element of the given array.*/private static NativeLibraryElement[] makePathElements(List<File> files) {} }參考 : 8.0.0_r4/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android9.0(PieAPI28)\rm Android \ 9.0 \ ( Pie \ API \ 28 )Android?9.0?(Pie?API?28) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;public DexPathList(ClassLoader definingContext, String dexPath,String librarySearchPath, File optimizedDirectory) {// save dexPath for BaseDexClassLoaderthis.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions, definingContext, isTrusted);}/*** Makes an array of dex/resource path elements, one per element of* the given array.*/private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions, ClassLoader loader) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, loader, false);}private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) {}/** TODO (dimitry): Revert after apps stops relying on the existence of this* method (see http://b/21957414 and http://b/26317852 for details)*/@SuppressWarnings("unused")private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, null);}/*** Makes an array of directory/zip path elements for the native library search path, one per* element of the given array.*/private static NativeLibraryElement[] makePathElements(List<File> files) {} }參考 : 9.0.0_r8/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
Android10.0(QAPI29)\rm Android \ 10.0 \ ( Q \ API \ 29 )Android?10.0?(Q?API?29) 系統中創建 Element[] dexElements 的方法 :
/*package*/ final class DexPathList {private Element[] dexElements;DexPathList(ClassLoader definingContext, String dexPath,String librarySearchPath, File optimizedDirectory, boolean isTrusted) {// save dexPath for BaseDexClassLoaderthis.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory,suppressedExceptions, definingContext, isTrusted);}/*** Makes an array of dex/resource path elements, one per element of* the given array.*/@UnsupportedAppUsageprivate static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions, ClassLoader loader) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, loader, false);}private static Element[] makeDexElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions, ClassLoader loader, boolean isTrusted) {}/** TODO (dimitry): Revert after apps stops relying on the existence of this* method (see http://b/21957414 and http://b/26317852 for details)*/@UnsupportedAppUsage@SuppressWarnings("unused")private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, null);}/*** Makes an array of directory/zip path elements for the native library search path, one per* element of the given array.*/@UnsupportedAppUsageprivate static NativeLibraryElement[] makePathElements(List<File> files) {} }參考 : 10.0.0_r6/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java
二、不同 Android 系統創建 dex 數組源碼對比
Android5.0、5.1\rm Android \ 5.0 、 5.1Android?5.0、5.1 系統需要反射如下 makeDexElements 方法 ;
private static Element[] makeDexElements(ArrayList<File> files, File optimizedDirectory,ArrayList<IOException> suppressedExceptions){}Android6.0、7.1、7.1、8.0、9.0、10\rm Android \ 6.0 、 7.1、7.1、8.0、9.0、10Android?6.0、7.1、7.1、8.0、9.0、10 系統需要反射如下 makePathElements 方法 ;
@SuppressWarnings("unused")private static Element[] makePathElements(List<File> files, File optimizedDirectory,List<IOException> suppressedExceptions) {return makeDexElements(files, optimizedDirectory, suppressedExceptions, null);}三、 Android 5.1 及以下系統反射方法并創建 Element[] dexElements
Android 5.1 及以下系統反射方法并創建 Element[] dexElements :
if(Build.VERSION.SDK_INT <=Build.VERSION_CODES.LOLLIPOP_MR1){ // 5.0, 5.1 makeDexElements// 反射 5.0, 5.1, 6.0 版本的 DexPathList 中的 makeDexElements 方法makeDexElements = reflexMethod(pathList, "makeDexElements",ArrayList::class.java, File::class.java, ArrayList::class.java)var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>()addElements = makeDexElements.invoke(pathList, dexFiles,optimizedDirectory,suppressedExceptions) as Array<Any>}四、 Android 6.0 及以下系統反射方法并創建 Element[] dexElements
Android 6.0 及以下系統反射方法并創建 Element[] dexElements :
}else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 7.0 以上版本 makePathElements// 反射 7.0 以上版本的 DexPathList 中的 makeDexElements 方法makeDexElements = reflexMethod(pathList, "makePathElements",ArrayList::class.java, File::class.java, ArrayList::class.java)var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>()addElements = makeDexElements.invoke(pathList, dexFiles,optimizedDirectory,suppressedExceptions) as Array<Any>}五、 完整代碼示例
/*2 . 在本應用中創建 Element[] dexElements 數組 , 用于存放解密后的 dex 文件不同的 Android 版本中 , 創建 Element[] dexElements 數組的方法不同 , 這里需要做兼容*/var makeDexElements: Methodvar addElements : Array<Any>if(Build.VERSION.SDK_INT <=Build.VERSION_CODES.LOLLIPOP_MR1){ // 5.0, 5.1 makeDexElements// 反射 5.0, 5.1, 6.0 版本的 DexPathList 中的 makeDexElements 方法makeDexElements = reflexMethod(pathList, "makeDexElements",ArrayList::class.java, File::class.java, ArrayList::class.java)var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>()addElements = makeDexElements.invoke(pathList, dexFiles,optimizedDirectory,suppressedExceptions) as Array<Any>}else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 7.0 以上版本 makePathElements// 反射 7.0 以上版本的 DexPathList 中的 makeDexElements 方法makeDexElements = reflexMethod(pathList, "makePathElements",ArrayList::class.java, File::class.java, ArrayList::class.java)var suppressedExceptions: ArrayList<IOException> = ArrayList<IOException>()addElements = makeDexElements.invoke(pathList, dexFiles,optimizedDirectory,suppressedExceptions) as Array<Any>}
總結
以上是生活随笔為你收集整理的【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 安全】DEX 加密 (
- 下一篇: 【Android 安全】DEX 加密 (