目錄:andorid jar/庫源碼解析 HotXposed: 作用: 免重啟手機,實現Xposed hook更新。(當然app是要重啟的) 慄子: 入口: // Hook 入口 public void handleLoadPackage(XC_LoadPackage.LoadPackagePara ...
HotXposed:
作用:
免重啟手機,實現Xposed hook更新。(當然app是要重啟的)
慄子:
入口:
// Hook 入口
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { hook(HookerDispatcher.class, lpparam); } public static void hook(Class clazz, XC_LoadPackage.LoadPackageParam lpparam) throws Exception { String packageName = clazz.getName().replace("." + clazz.getSimpleName(), ""); Log.i(tag, "packageName " + packageName); File apkFile = getApkFile(packageName); Log.i(tag, "apkFile.getAbsolutePath " + apkFile.getAbsolutePath()); if (!apkFile.exists()) { Log.i(tag, "apk file not found"); return; } Log.i(tag, "去掉 xposed 通知"); filterNotify(lpparam); PathClassLoader classLoader = new PathClassLoader(apkFile.getAbsolutePath(), lpparam.getClass().getClassLoader()); Log.i(tag, "classLoader " + classLoader); XposedHelpers.callMethod(classLoader.loadClass(clazz.getName()).newInstance(), "dispatch", lpparam); }
熱更新的Hook:
public class HookerDispatcher implements IHookerDispatcher { private static String tag = "HotXposed"; @Override public void dispatch(final XC_LoadPackage.LoadPackageParam lpparam) { if(!Constants.TARGET_PACKAGE_NAME.equals(lpparam.packageName)){ return; } Log.i(tag, "dispatch 被調用 熱更新代碼從這裡開始"); if (lpparam.packageName.contains(Constants.TARGET_PACKAGE_NAME) && lpparam.processName.equals(lpparam.packageName)) { findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() { @Override protected void afterHookedMethod(final MethodHookParam param) throws Throwable { final ClassLoader cl = ((Context) param.args[0]).getClassLoader(); Log.i(tag, "enter 2 " + lpparam.packageName); } }); } } }
源碼解讀:
首先來看入口實現。
1、通過集成 IXposedHookLoadPackage 實現他的 handleLoadPackage方法來實現他的入口。
2、首先,確定 HookerDispatcher 在包名下麵,然後通過去掉他自身的名稱,即是包名,也可以寫死包名。
3、通過包名,得到當前安裝模塊(即Apk)的,路徑,一般是(/data/app/包名-1/2/base.apk).這個路徑下麵。通過判斷文件是否存在,可以知道是1還是2
4、然後 因為得到了apk的路徑,可以通過構造一個 PathClassLoader對象,入參傳入apk路徑和當前的ClassLoader,來創建一個PathClassLoader對象。(下一步大有用處)
5、把這個ClassLoader,作為入口,調用Xposed的Hook入口方法,即;用於熱更新的部分(這裡有點繞,我詳細解釋一下。)
5.1、因為xposed,載入是在apk載入的時候,這個時候,上面的源碼1.是不會被熱更新的。
5.2、而源碼2中,是通過載入apk得到的ClassLoader的調用,因為app安裝之後,產生了變化,是可以被熱更新到的。
源碼:https://github.com/githubwing/HotXposed
引入:
implementation 'com.github.githubwing:HotXposed:v1.0.0
'