【Android 逆向】加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程
文章目錄
- 一、加殼的 Android 應(yīng)用啟動流程
- 二、使用反射替換 LoadedApk 中的類加載器流程
一、加殼的 Android 應(yīng)用啟動流程
加殼的 Android 應(yīng)用啟動流程 : 加殼的 Android 應(yīng)用執(zhí)行時 , 殼代碼獲取應(yīng)用的執(zhí)行權(quán)限 , 然后將加殼的應(yīng)用修正后 , 獲得真正的字節(jié)碼文件 , 由類加載器加載真正的字節(jié)碼文件 , 然后執(zhí)行應(yīng)用的業(yè)務(wù)邏輯 ;
- ① BootClassLoader 加載 Android 核心庫
- ② PathClassLoader 加載應(yīng)用自身的 DEX 字節(jié)碼
- ③ 開始 執(zhí)行 Android 應(yīng)用的自身組件 ( 如 Activity 等 )
- ④ 執(zhí)行 Application 的 attachBaseContext 方法
- ⑤ 執(zhí)行 Application 的 onCreate 方法
注意 , 其中的 ② 步驟 , 針對與應(yīng)用是否加殼 , 有以下 222 種不同的情況 ;
- 加殼應(yīng)用 : 如果應(yīng)用沒有加殼 , 加載 DEX 代碼就是完整的應(yīng)用字節(jié)碼文件 ;
- 不加殼應(yīng)用 : 如果應(yīng)用有加殼 , 加載的 DEX 字節(jié)碼就是殼應(yīng)用的 DEX 字節(jié)碼文件 ;
在之前的 Android 安全 專欄中 , 已經(jīng)進行過加殼功能的開發(fā) , 是在 Application 的 attachBaseContext 方法中 , 對殼進行的處理 , 將加密后的 DEX 還原成正常的 DEX 字節(jié)碼文件 ;
在 Application 的 attachBaseContext 方法中 需要 解密 加殼的 DEX 文件 , 反射設(shè)置 LoadedApk 中的類加載器 ;
在 Application 的 onCreate 方法中 , 需要獲取程序的 Application 名稱 , 然后通過反射創(chuàng)建 真實的 Application 對象 , 通過反射設(shè)置 ActivityThread 中的真實的 Application 對象 ;
二、使用反射替換 LoadedApk 中的類加載器流程
ActivityThread 是 Android 應(yīng)用 主線程 起點 , ActivityThread 類是全局單例的 , 其全局唯一的 ActivityThread 實例對象是 , ActivityThread 有一個 sCurrentActivityThread 成員變量 , 該成員就是 ActivityThread 的單例對象 ;
public final class ActivityThread {/** Reference to singleton {@link ActivityThread} */private static volatile ActivityThread sCurrentActivityThread;public static ActivityThread currentActivityThread() {return sCurrentActivityThread;} }源碼路徑 : /frameworks/base/core/java/android/app/ActivityThread.java
因此 , 通過反射 , 很容易獲取到 ActivityThread 的實例對象 ;
然后 , 獲取 ActivityThread 實例對象中的 mPackages , 目的是獲取其中的 LoadedApk 實例對象 ;
public final class ActivityThread {// 這些可以被多個線程訪問;mResourcesManager是鎖。// XXX目前,我們保留有關(guān)所有軟件包的信息// 已看到,但未從此映射中刪除條目。// 注意:活動和窗口管理器需要調(diào)用// ActivityThread執(zhí)行更新資源配置等操作,// 這意味著當活動和窗口管理器// 他們有自己的鎖。因此,您決不能回撥活動管理器// 或窗口管理器或任何依賴于它們的東西。// 這些LoadedApk僅對我們正在運行的用戶ID有效。@GuardedBy("mResourcesManager")final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>(); }源碼路徑 : /frameworks/base/core/java/android/app/ActivityThread.java
獲取到 LoadedApk 實例對象后 , 就可以獲取該實例對象的 ClassLoader 類加載器 對象 ;
public final class LoadedApk {private ClassLoader mClassLoader; }源碼路徑 : /frameworks/base/core/java/android/app/LoadedApk.java
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【Android 逆向】加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】类加载器 Cla
- 下一篇: 【Android 逆向】启动 DEX 字