【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 后续分析 | Application 替换位置 )
文章目錄
- 一、ActivityThread 后續分析
- 二、ActivityThread 相關源碼
- 三、Application 替換位置
dex 解密時 , 需要將 代理 Application 替換為 真實 Application ; 替換 Application 首先要理解系統如何注冊應用的 Application 的 ;
一、ActivityThread 后續分析
在 【Android 安全】DEX 加密 ( Application 替換 | Android 應用啟動原理 | ActivityThread 源碼分析 ) 基礎上 , 繼續分析 ActivityThread 的 handleBindApplication 方法 ;
在 Application app = data.info.makeApplication(data.restrictedBackupMode, null) 代碼中 , 創建了 Application , 并且調用了 Application 的 attachBaseContext 方法 ;
創建完畢之后 , 將創建的 Application 賦值給了 ActivityThread 的 mInitialApplication 成員 , mInitialApplication = app ;
④ ActivityThread 的 mInitialApplication 成員是 Application
在后面調用了 mInstrumentation.callApplicationOnCreate(app) 方法 , 執行了 Application 中的 onCreate 方法 , 此時
try {mInstrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!mInstrumentation.onException(app, e)) {throw new RuntimeException("Unable to create application " + app.getClass().getName()+ ": " + e.toString(), e);}}二、ActivityThread 相關源碼
public final class ActivityThread {Application mInitialApplication;final ArrayList<Application> mAllApplications= new ArrayList<Application>();final ApplicationThread mAppThread = new ApplicationThread();final Looper mLooper = Looper.myLooper();final H mH = new H();private class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");AppBindData data = (AppBindData)msg.obj;handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;}}private void handleBindApplication(AppBindData data) {try {// If the app is being launched for full backup or restore, bring it up in// a restricted environment with the base application class.Application app = data.info.makeApplication(data.restrictedBackupMode, null);mInitialApplication = app;// don't bring up providers in restricted mode; they may depend on the// app's custom Application classif (!data.restrictedBackupMode) {List<ProviderInfo> providers = data.providers;if (providers != null) {installContentProviders(app, providers);// For process that contains content providers, we want to// ensure that the JIT is enabled "at some point".mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);}}// Do this after providers, since instrumentation tests generally start their// test thread at this point, and we don't want that racing.try {mInstrumentation.onCreate(data.instrumentationArgs);}catch (Exception e) {throw new RuntimeException("Exception thrown in onCreate() of "+ data.instrumentationName + ": " + e.toString(), e);}try {// 此處調用了 Application 的 onCreate 函數 mInstrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!mInstrumentation.onException(app, e)) {throw new RuntimeException("Unable to create application " + app.getClass().getName()+ ": " + e.toString(), e);}}} finally {StrictMode.setThreadPolicy(savedPolicy);}}public final void bindApplication(String processName, ApplicationInfo appInfo,List<ProviderInfo> providers, ComponentName instrumentationName,ProfilerInfo profilerInfo, Bundle instrumentationArgs,IInstrumentationWatcher instrumentationWatcher,IUiAutomationConnection instrumentationUiConnection, int debugMode,boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,Bundle coreSettings) {sendMessage(H.BIND_APPLICATION, data);} private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {// Ignore}// Watch for getting close to heap limit.} else {// Don't set application object here -- if the system crashes,// we can't display an alert, we just want to die die die.}}public static void main(String[] args) {Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);Looper.loop();} }
完整源碼參考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/ActivityThread.java
三、Application 替換位置
當應用啟動后 , 在 AndroidManifest.xml 中配置的 代理 Application 為 kim.hsl.multipledex.ProxyApplication ;
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.dex"><applicationandroid:name="kim.hsl.multipledex.ProxyApplication"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><!-- app_name 值是該應用的 Application 的真實全類名 --><meta-data android:name="app_name" android:value="kim.hsl.multipledex.ProxyApplication"/><!-- DEX 解密之后的目錄名稱 --><meta-data android:name="app_version" android:value="1.0"/><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>因此在應用程序開始運行時 , 以下幾個位置運行的 Application 是 kim.hsl.multipledex.ProxyApplication , 需要將其替換為實際開發的 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 對象 ;
替換 Application 就是需要替換上述對象的對應 Application 成員 ;
總結
以上是生活随笔為你收集整理的【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 后续分析 | Application 替换位置 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 安全】DEX 加密 (
- 下一篇: 【Android 安全】DEX 加密 (