日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )

發(fā)布時(shí)間:2025/6/17 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 ) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android 插件化系列文章目錄

【Android 插件化】插件化簡(jiǎn)介 ( 組件化與插件化 )
【Android 插件化】插件化原理 ( JVM 內(nèi)存數(shù)據(jù) | 類加載流程 )
【Android 插件化】插件化原理 ( 類加載器 )

【Android 插件化】“ 插樁式 “ 插件化框架 ( 原理與實(shí)現(xiàn)思路 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 類加載器創(chuàng)建 | 資源加載 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 注入上下文的使用 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 獲取插件入口 Activity 組件 | 加載插件 Resources 資源 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 運(yùn)行應(yīng)用 | 代碼整理 )

【Android 插件化】Hook 插件化框架 ( Hook 技術(shù) | 代理模式 | 靜態(tài)代理 | 動(dòng)態(tài)代理 )
【Android 插件化】Hook 插件化框架 ( Hook 實(shí)現(xiàn)思路 | Hook 按鈕點(diǎn)擊事件 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動(dòng)過(guò)程 | 靜態(tài)代理 )

【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動(dòng)流程 一 | Activity 進(jìn)程相關(guān)源碼 )
【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動(dòng)流程 二 | AMS 進(jìn)程相關(guān)源碼 | 主進(jìn)程相關(guān)源碼 )

【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )
【Android 插件化】Hook 插件化框架 ( 通過(guò)反射獲取 “插件包“ 中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 通過(guò)反射獲取 “宿主“ 應(yīng)用中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 合并 “插件包“ 與 “宿主“ 中的 Element[] dexElements | 設(shè)置合并后的 Element[] 數(shù)組 )
【Android 插件化】Hook 插件化框架 ( 創(chuàng)建插件應(yīng)用 | 拷貝插件 APK | 初始化插件包 | 測(cè)試插件 DEX 字節(jié)碼 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動(dòng)流程 | Hook 點(diǎn)分析 )


文章目錄

  • Android 插件化系列文章目錄
  • 前言
  • 一、Hook 點(diǎn)分析
  • 二、查看 Instrumentation 源碼
  • 三、分析 Instrumentation.execStartActivity 方法
  • 四、分析 ActivityManager 中的源碼
  • 五、博客資源


前言

在 【Android 插件化】Hook 插件化框架 ( 通過(guò)反射獲取 “插件包“ 中的 Element[] dexElements ) 博客中介紹了從 " 插件包 " APK 文件中獲取 Element[] dexElements 流程 ;

在博客 【Android 插件化】Hook 插件化框架 ( 通過(guò)反射獲取 “宿主“ 應(yīng)用中的 Element[] dexElements ) 介紹了從 " 宿主 " 應(yīng)用中獲取 Element[] dexElements 流程 ;

在博客 【Android 插件化】Hook 插件化框架 ( 合并 “插件包“ 與 “宿主“ 中的 Element[] dexElements | 設(shè)置合并后的 Element[] 數(shù)組 ) 中 , 將上述從 " 插件包 " APK 文件中獲取 Element[] dexElements 和 從 " 宿主 " 應(yīng)用中獲取 Element[] dexElements 獲取的兩個(gè)數(shù)組進(jìn)行了合并 ;

在博客 【Android 插件化】Hook 插件化框架 ( 創(chuàng)建插件應(yīng)用 | 拷貝插件 APK | 初始化插件包 | 測(cè)試插件 DEX 字節(jié)碼 ) 中驗(yàn)證了上述加載的插件包 Dex 字節(jié)碼是否加載成功 , 并通過(guò)反射調(diào)用了插件包中的方法 ;


上面一組博客將插件包數(shù)據(jù)加載到了內(nèi)存中 , 下面開始進(jìn)行 Hook Activity 的操作 ,






一、Hook 點(diǎn)分析



【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動(dòng)流程 一 | Activity 進(jìn)程相關(guān)源碼 )
【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動(dòng)流程 二 | AMS 進(jìn)程相關(guān)源碼 | 主進(jìn)程相關(guān)源碼 )

兩篇博客中 , 分析了 Activity 的啟動(dòng)流程 ,

在當(dāng)前應(yīng)用主進(jìn)程中 , 在 Activity 中執(zhí)行 startActivity 方法 , 然后調(diào)用 Instrumentation 中的 execStartActivity 方法 ;

然后在 ActivityManagerService 進(jìn)程中 , 執(zhí)行后續(xù)操作 ; ( 具體細(xì)節(jié)看上面的兩篇博客 )


這里只需要研究 Activity 中執(zhí)行 startActivity 方法的情況 , 因?yàn)椴寮簧婕霸?" 宿主 " 應(yīng)用中 , 啟動(dòng) " 插件 " 包中的 Activity 類 , 只需要考慮這一種情況即可 ;


Activity 的所有的生命周期函數(shù) , 都與 Instrumentation 相關(guān) , Instrumentation 會(huì)處理 Activity 實(shí)例化等操作 ;





二、查看 Instrumentation 源碼



查看 Instrumentation 相關(guān)代碼 , 雙 Shift 搜索界面中 , 選中 " Include non-project items " 選項(xiàng) , 當(dāng)前的編譯版本是 28 , 因此這里選擇 API 28 中的 Instrumentation.java 源碼 ;





三、分析 Instrumentation.execStartActivity 方法



啟動(dòng) Activity 時(shí) , 調(diào)用的是下面的 Instrumentation.execStartActivity 方法 ;

public class Instrumentation {/*** Execute a startActivity call made by the application. The default * implementation takes care of updating any active {@link ActivityMonitor}* objects and dispatches this call to the system activity manager; you can* override this to watch for the application to start an activity, and * modify what happens when it does. ** <p>This method returns an {@link ActivityResult} object, which you can * use when intercepting application calls to avoid performing the start * activity action but still return the result the application is * expecting. To do this, override this method to catch the call to start * activity so that it returns a new ActivityResult containing the results * you would like the application to see, and don't call up to the super * class. Note that an application is only expecting a result if * <var>requestCode</var> is &gt;= 0.** <p>This method throws {@link android.content.ActivityNotFoundException}* if there was no Activity found to run the given Intent.** @param who The Context from which the activity is being started.* @param contextThread The main thread of the Context from which the activity* is being started.* @param token Internal token identifying to the system who is starting * the activity; may be null.* @param target Which activity is performing the start (and thus receiving * any result); may be null if this call is not being made* from an activity.* @param intent The actual Intent to start.* @param requestCode Identifier for this request's result; less than zero * if the caller is not expecting a result.* @param options Addition options.** @return To force the return of a particular result, return an * ActivityResult object containing the desired data; otherwise* return null. The default implementation always returns null.** @throws android.content.ActivityNotFoundException** @see Activity#startActivity(Intent)* @see Activity#startActivityForResult(Intent, int)* @see Activity#startActivityFromChild** {@hide}*/public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;Uri referrer = target != null ? target.onProvideReferrer() : null;if (referrer != null) {intent.putExtra(Intent.EXTRA_REFERRER, referrer);}if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);ActivityResult result = null;if (am.ignoreMatchingSpecificIntents()) {result = am.onStartActivity(intent);}if (result != null) {am.mHits++;return result;} else if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;} }

在上述方法最后 , 調(diào)用了 AMS 的 startActivity 方法 , ActivityManager.getService().startActivity() 方法最終是 ActivityManagerService 執(zhí)行的 ;
由于當(dāng)前主線程與 ActivityManagerService 不再同一個(gè)進(jìn)程中 , 因此需要使用 Binder 進(jìn)行調(diào)用 ;

int result = ActivityManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);



四、分析 ActivityManager 中的源碼



在 ActivityManager 中的 getService 方法 , 獲取的

/*** @hide*/public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};

IActivityManager 是 Binder 的 Proxy , Binder 下存在 Stub 和 Proxy 兩個(gè)內(nèi)部類 , Binder 生成的 Java 類時(shí)內(nèi)部生成上述 Stub 和 Proxy 兩個(gè)內(nèi)部類 ;

反射的時(shí)候 , 反射

final IActivityManager am = IActivityManager.Stub.asInterface(b);

對(duì)象 , 最終調(diào)用 startActivity 的是 IActivityManager , 使用占坑的 Activity 隱瞞 IActivityManager , 實(shí)際上啟動(dòng)我們從插件包中加載的 Activity ;

Hook 點(diǎn)就是 android.app.ActivityManager 的 private static final Singleton<IActivityManager> IActivityManagerSingleton成員 ;





五、博客資源



博客資源 :

  • GitHub : https://github.com/han1202012/Plugin_Hook

總結(jié)

以上是生活随笔為你收集整理的【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。