【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )
文章目錄
- 前言
- 一、DexFile.loadDexFile 函數分析
- 二、DexFile 構造函數分析
- 三、DexFile.openDexFile 函數分析
前言
上一篇博客 【Android 逆向】整體加固脫殼 ( DexClassLoader 加載 dex 流程分析 | DexPathList 中根據 File 加載 DexFile | loadDexFile 分析 ) 中 , 介紹了 DexPathList 中通過 File 生成 DexFile 的源碼 , 在 makeDexElements 中調用了 loadDexFile 方法 , 在 loadDexFile 又有調用了 DexFile.loadDexFile 函數 , 用于生成 DexFile 實例對象 ;
本博客中介紹 DexFile 相關源碼 ;
一、DexFile.loadDexFile 函數分析
在 DexPathList.loadDexFile 方法中 , 調用 DexFile 構造函數創建了 DexFile 實例對象 ;
下面的代碼中 , 列出了 loadDexFile 方法 ;
傳入的參數分別是 Dex 文件的路徑 , 優化后的 Dex 文件路徑 , 標志位 , 一般是 0 ;
/*** 操縱DEX文件。這門課在原則上與我們的課相似* {@link java.util.zip.ZipFile}。它主要由類裝入器使用。* <p>* 注意,我們不直接打開并讀取這里的DEX文件。它們是內存映射的* 由VM只讀。*/ public final class DexFile {/*** 打開一個DEX文件,指定優化的DEX所在的文件* 數據應該是書面的。如果優化表單存在并出現* 要成為最新版本,將使用它;如果沒有,VM將嘗試* 再生它。** 這是供希望下載的應用程序使用的* 并在通常的應用程序安裝之外執行DEX文件* 機制。此函數不應由* 應用;相反,使用類加載器,例如* 達爾維克。系統DexClassLoader。** @param sourcePathName* 帶有“classes.dex”的Jar或APK文件。(可將此擴展為包括* 未來的“原始索引”。)* @param outputPathName* 保存優化形式的DEX數據的文件。* @param標志* 啟用可選功能。(當前未定義任何內容。)* @返回* 新的或以前打開的文件。* @拋出異常* 如果無法打開源文件或輸出文件。*/static public DexFile loadDex(String sourcePathName, String outputPathName,int flags) throws IOException {/** TODO:我們可能希望緩存以前打開的DexFile對象。* 緩存將與close()同步。這會有幫助的* 我們避免在應用程序運行時多次映射同一個索引* 決定多次打開它。實際上,這可能不是* 這是一個真正的問題。*/return new DexFile(sourcePathName, outputPathName, flags);} }源碼路徑 : /libcore/dalvik/src/main/java/dalvik/system/DexFile.java
二、DexFile 構造函數分析
在 loadDexFile 方法 , 調用到 DexFile 構造方法 ;
在 DexFile 構造方法中 , 調用了 mCookie = openDexFile(sourceName, outputName, flags); 方法打開 Dex 文件 ;
/*** 操縱DEX文件。這門課在原則上與我們的課相似* {@link java.util.zip.ZipFile}。它主要由類裝入器使用。* <p>* 注意,我們不直接打開并讀取這里的DEX文件。它們是內存映射的* 由VM只讀。*/ public final class DexFile {/*** 使用指定文件從給定文件名打開DEX文件* 保存優化的數據。** @param sourceName* 帶有“classes.dex”的Jar或APK文件。* @param outputName* 保存優化形式的DEX數據的文件。* @param標志* 啟用可選功能。*/private DexFile(String sourceName, String outputName, int flags) throws IOException {if (outputName != null) {try {String parent = new File(outputName).getParent();if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) {throw new IllegalArgumentException("Optimized data directory " + parent+ " is not owned by the current user. Shared storage cannot protect"+ " your application from code injection attacks.");}} catch (ErrnoException ignored) {// assume we'll fail with a more contextual error later}}mCookie = openDexFile(sourceName, outputName, flags);mFileName = sourceName;guard.open("close");//System.out.println("DEX FILE cookie is " + mCookie);} }源碼路徑 : /libcore/dalvik/src/main/java/dalvik/system/DexFile.java
三、DexFile.openDexFile 函數分析
在 DexFile 的 openDexFile 函數中 , 調用了 native 函數 openDexFileNative , 打開 Dex 文件 , 該函數是使用 C 代碼生成的 ;
/*** 操縱DEX文件。這門課在原則上與我們的課相似* {@link java.util.zip.ZipFile}。它主要由類裝入器使用。* <p>* 注意,我們不直接打開并讀取這里的DEX文件。它們是內存映射的* 由VM只讀。*/ public final class DexFile {/** 打開一個DEX文件。返回的值是一個神奇的VM cookie。在…上* 失敗時,將引發IOException。*/private static int openDexFile(String sourceName, String outputName,int flags) throws IOException {return openDexFileNative(new File(sourceName).getCanonicalPath(),(outputName == null) ? null : new File(outputName).getCanonicalPath(),flags);}native private static int openDexFileNative(String sourceName, String outputName,int flags) throws IOException; }源碼路徑 : /libcore/dalvik/src/main/java/dalvik/system/DexFile.java
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】整体加固脱壳 (
- 下一篇: 【Android 逆向】整体加固脱壳 (