日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

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

Android 插件化系列文章目錄

【Android 插件化】插件化簡介 ( 組件化與插件化 )
【Android 插件化】插件化原理 ( JVM 內存數據 | 類加載流程 )
【Android 插件化】插件化原理 ( 類加載器 )

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

【Android 插件化】Hook 插件化框架 ( Hook 技術 | 代理模式 | 靜態代理 | 動態代理 )
【Android 插件化】Hook 插件化框架 ( Hook 實現思路 | Hook 按鈕點擊事件 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動過程 | 靜態代理 )

【Android 插件化】Hook 插件化框架 ( 從 Hook 應用角度分析 Activity 啟動流程 一 | Activity 進程相關源碼 )
【Android 插件化】Hook 插件化框架 ( 從 Hook 應用角度分析 Activity 啟動流程 二 | AMS 進程相關源碼 | 主進程相關源碼 )

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

【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | Hook 點分析 )


文章目錄

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


前言

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

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

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

在博客 【Android 插件化】Hook 插件化框架 ( 創建插件應用 | 拷貝插件 APK | 初始化插件包 | 測試插件 DEX 字節碼 ) 中驗證了上述加載的插件包 Dex 字節碼是否加載成功 , 并通過反射調用了插件包中的方法 ;


上面一組博客將插件包數據加載到了內存中 , 下面開始進行 Hook Activity 的操作 ,






一、Hook 點分析



【Android 插件化】Hook 插件化框架 ( 從 Hook 應用角度分析 Activity 啟動流程 一 | Activity 進程相關源碼 )
【Android 插件化】Hook 插件化框架 ( 從 Hook 應用角度分析 Activity 啟動流程 二 | AMS 進程相關源碼 | 主進程相關源碼 )

兩篇博客中 , 分析了 Activity 的啟動流程 ,

在當前應用主進程中 , 在 Activity 中執行 startActivity 方法 , 然后調用 Instrumentation 中的 execStartActivity 方法 ;

然后在 ActivityManagerService 進程中 , 執行后續操作 ; ( 具體細節看上面的兩篇博客 )


這里只需要研究 Activity 中執行 startActivity 方法的情況 , 因為插件化只涉及在 " 宿主 " 應用中 , 啟動 " 插件 " 包中的 Activity 類 , 只需要考慮這一種情況即可 ;


Activity 的所有的生命周期函數 , 都與 Instrumentation 相關 , Instrumentation 會處理 Activity 實例化等操作 ;





二、查看 Instrumentation 源碼



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





三、分析 Instrumentation.execStartActivity 方法



啟動 Activity 時 , 調用的是下面的 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;} }

在上述方法最后 , 調用了 AMS 的 startActivity 方法 , ActivityManager.getService().startActivity() 方法最終是 ActivityManagerService 執行的 ;
由于當前主線程與 ActivityManagerService 不再同一個進程中 , 因此需要使用 Binder 進行調用 ;

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 兩個內部類 , Binder 生成的 Java 類時內部生成上述 Stub 和 Proxy 兩個內部類 ;

反射的時候 , 反射

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

對象 , 最終調用 startActivity 的是 IActivityManager , 使用占坑的 Activity 隱瞞 IActivityManager , 實際上啟動我們從插件包中加載的 Activity ;

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





五、博客資源



博客資源 :

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。