【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 )
文章目錄
- 一、獲取對象類型分析
- 二、獲取 ContextImpl 類型對象
- 三、獲取 ActivityThread、LoadedApk 類型對象
dex 解密時 , 需要將 代理 Application 替換為 真實 Application ; 替換 Application 首先要理解系統如何注冊應用的 Application 的 ;
一、獲取對象類型分析
替換 Application 就是需要替換下面各個類型對象的對應 Application 成員 ;
① ContextImpl 的 private Context mOuterContext 成員是 kim.hsl.multipledex.ProxyApplication 對象 ;
② ActivityThread 中的 ArrayList<Application> mAllApplications 集合中添加了 kim.hsl.multipledex.ProxyApplication 對象 ;
③ LoadedApk 中的 mApplication 成員是 kim.hsl.multipledex.ProxyApplication 對象 ;
④ ActivityThread 中的 Application mInitialApplication 成員是 kim.hsl.multipledex.ProxyApplication 對象 ;
ContextImpl 源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/ContextImpl.java
ActivityThread 源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/ActivityThread.java
LoadedApk 源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/LoadedApk.java
替換上述類型對象中的成員 , 首先要獲取到上述 ContextImpl , ActivityThread , LoadedApk 類型的對象 ;
上述三個對象在每個應用中有且僅有一個 , 只要獲取到了就是本應用中唯一的對象 ;
使用反射獲取上述對象 ;
二、獲取 ContextImpl 類型對象
獲取 ContextImpl 類型對象 : Application 創建完畢之后 , 就會立刻調用 Application 的 void attachBaseContext(Context base) 函數 , 該函數中的 Context base 參數就是 ContextImpl 類型對象 ;
通過 Application 的 void attachBaseContext(Context base) 回調函數 , 可獲取 ContextImpl 對象 ;
public class ContextWrapper extends Context {protected void attachBaseContext(Context base) {mBase = base;} }三、獲取 ActivityThread、LoadedApk 類型對象
獲取 ActivityThread、LoadedApk 類型對象 :
在 LoadedApk 中的 makeApplication 方法中 ,
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this) ,
通過調用 ContextImpl.createAppContext 函數創建 ContextImpl 對象 ,
- 傳入的第一個參數就是 ActivityThread 對象
- 傳入的第二個參數就是 LoadedApk 對象
LoadedApk 完整源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/LoadedApk.java
分析 ContextImpl.createAppContext 方法 , 在該方法中調用了 ContextImpl 的構造方法創建了 ContextImpl 對象 ;
class ContextImpl extends Context {static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {if (packageInfo == null) throw new IllegalArgumentException("packageInfo");// 調用構造函數創建了 ContextImpl 對象 return new ContextImpl(null, mainThread,packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);} }繼續查看 ContextImpl 構造函數 , 該構造函數參數很長 , 其第二個參數是 ActivityThread mainThread , 第三個參數是 LoadedApk packageInfo ;
在構造函數中 , mMainThread = mainThread , 構造函數中 ActivityThread mainThread 參數賦值給了 final ActivityThread mMainThread 成員變量 ;
在構造函數中 , mPackageInfo = packageInfo , 構造函數中 LoadedApk packageInfo 參數賦值給了 final LoadedApk mPackageInfo 成員變量 ;
因此可以通過 ContextImpl 類型對象 , 獲取其中的
- final ActivityThread mMainThread
- final LoadedApk mPackageInfo
兩個成員變量 , 即可獲取到 ActivityThread 和 LoadedApk ;
class ContextImpl extends Context {// 應用的 ActivityThread final ActivityThread mMainThread;// 應用的 LoadedApk final LoadedApk mPackageInfo;// ContextImpl 構造方法 , 只留下分析到的有用代碼 , 其余代碼刪除 private ContextImpl(ContextImpl container, ActivityThread mainThread,LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,Display display, Configuration overrideConfiguration, int createDisplayWithId) {mOuterContext = this;mMainThread = mainThread;mPackageInfo = packageInfo;}static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {if (packageInfo == null) throw new IllegalArgumentException("packageInfo");// 調用構造函數創建了 ContextImpl 對象 return new ContextImpl(null, mainThread,packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);} }ContextImpl 完整源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/ContextImpl.java
總結
以上是生活随笔為你收集整理的【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 安全】DEX 加密 (
- 下一篇: 【错误记录】NDK 报错 java.la