From 92568985030a9ae7a5e3b957713cfb91384f727f Mon Sep 17 00:00:00 2001 From: solohsu Date: Thu, 27 Jun 2019 16:34:46 +0800 Subject: [PATCH] Delay the loaded package callbacks util LoadedApk#getClassLoader is called --- appveyor.yml | 2 +- .../riru/edxp/_hooker/impl/HandleBindApp.java | 29 ++---- .../riru/edxp/_hooker/impl/LoadedApkCstr.java | 14 +-- .../edxp/_hooker/impl/LoadedApkGetCL.java | 96 +++++++++++++++++++ edxp-core/build.gradle | 2 +- 5 files changed, 109 insertions(+), 34 deletions(-) create mode 100644 edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkGetCL.java diff --git a/appveyor.yml b/appveyor.yml index a63b6d9b..29935112 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: '0.4.5.4_beta({build})' +version: '0.4.5.5_beta({build})' environment: ANDROID_HOME: C:\android-sdk-windows diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/HandleBindApp.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/HandleBindApp.java index ad2f3446..bf27a3a9 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/HandleBindApp.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/HandleBindApp.java @@ -8,9 +8,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.XResources; import com.elderdrivers.riru.edxp.config.ConfigManager; -import com.elderdrivers.riru.edxp.hooker.SliceProviderFix; import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker; -import com.elderdrivers.riru.edxp.hooker.XposedInstallerHooker; import com.elderdrivers.riru.edxp.util.Hookers; import com.elderdrivers.riru.edxp.util.Utils; @@ -18,11 +16,6 @@ import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; -import de.robv.android.xposed.callbacks.XC_LoadPackage; - -import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME; -import static com.elderdrivers.riru.edxp.hooker.SliceProviderFix.SYSTEMUI_PACKAGE_NAME; -import static com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; // normal process initialization (for new Activity, Service, BroadcastReceiver etc.) public class HandleBindApp extends XC_MethodHook { @@ -64,23 +57,13 @@ public class HandleBindApp extends XC_MethodHook { XResources.setPackageNameForResDir(appInfo.packageName, loadedApk.getResDir()); - XC_LoadPackage.LoadPackageParam lpparam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks); - lpparam.packageName = reportedPackageName; - lpparam.processName = (String) XposedHelpers.getObjectField(bindData, "processName"); - lpparam.classLoader = loadedApk.getClassLoader(); - lpparam.appInfo = appInfo; - lpparam.isFirstApplication = true; - XC_LoadPackage.callAll(lpparam); + String processName = (String) XposedHelpers.getObjectField(bindData, "processName"); + + LoadedApkGetCL hook = new LoadedApkGetCL(loadedApk, reportedPackageName, + processName, true); + hook.setUnhook(XposedHelpers.findAndHookMethod( + LoadedApk.class, "getClassLoader", hook)); - if (reportedPackageName.equals(INSTALLER_PACKAGE_NAME)) { - XposedInstallerHooker.hookXposedInstaller(lpparam.classLoader); - } - if (reportedPackageName.equals(BLACK_LIST_PACKAGE_NAME)) { - XposedBlackListHooker.hook(lpparam.classLoader); - } - if (reportedPackageName.equals(SYSTEMUI_PACKAGE_NAME)) { - SliceProviderFix.hook(); - } } catch (Throwable t) { Hookers.logE("error when hooking bindApp", t); } diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkCstr.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkCstr.java index 04cc0e53..3464f4c2 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkCstr.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkCstr.java @@ -9,10 +9,8 @@ import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker; import com.elderdrivers.riru.edxp.util.Hookers; import de.robv.android.xposed.XC_MethodHook; -import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedInit; -import de.robv.android.xposed.callbacks.XC_LoadPackage; // when a package is loaded for an existing process, trigger the callbacks as well // ed: remove resources related hooking @@ -61,13 +59,11 @@ public class LoadedApkCstr extends XC_MethodHook { return; } - XC_LoadPackage.LoadPackageParam lpparam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks); - lpparam.packageName = packageName; - lpparam.processName = AndroidAppHelper.currentProcessName(); - lpparam.classLoader = loadedApk.getClassLoader(); - lpparam.appInfo = loadedApk.getApplicationInfo(); - lpparam.isFirstApplication = false; - XC_LoadPackage.callAll(lpparam); + LoadedApkGetCL hook = new LoadedApkGetCL(loadedApk, packageName, + AndroidAppHelper.currentProcessName(), false); + hook.setUnhook(XposedHelpers.findAndHookMethod( + LoadedApk.class, "getClassLoader", hook)); + } catch (Throwable t) { Hookers.logE("error when hooking LoadedApk.", t); } diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkGetCL.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkGetCL.java new file mode 100644 index 00000000..eb3bd523 --- /dev/null +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/LoadedApkGetCL.java @@ -0,0 +1,96 @@ +package com.elderdrivers.riru.edxp._hooker.impl; + +import android.app.LoadedApk; + +import com.elderdrivers.riru.edxp.hooker.SliceProviderFix; +import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker; +import com.elderdrivers.riru.edxp.hooker.XposedInstallerHooker; +import com.elderdrivers.riru.edxp.util.Hookers; + +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage; + +import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME; +import static com.elderdrivers.riru.edxp.hooker.SliceProviderFix.SYSTEMUI_PACKAGE_NAME; +import static com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; + + +public class LoadedApkGetCL extends XC_MethodHook { + + private final LoadedApk loadedApk; + private final String packageName; + private final String processName; + private final boolean isFirstApplication; + private Unhook unhook; + + public LoadedApkGetCL(LoadedApk loadedApk, String packageName, String processName, + boolean isFirstApplication) { + this.loadedApk = loadedApk; + this.packageName = packageName; + this.processName = processName; + this.isFirstApplication = isFirstApplication; + } + + @Override + protected void afterHookedMethod(MethodHookParam param) throws Throwable { + + try { + + if (XposedBlackListHooker.shouldDisableHooks("")) { + return; + } + + Hookers.logD("LoadedApk#getClassLoader starts"); + + LoadedApk loadedApk = (LoadedApk) param.thisObject; + + if (loadedApk != this.loadedApk) { + return; + } + + Object mAppDir = XposedHelpers.getObjectField(loadedApk, "mAppDir"); + ClassLoader classLoader = (ClassLoader) param.getResult(); + Hookers.logD("LoadedApk#getClassLoader ends: " + mAppDir + " -> " + classLoader); + + if (classLoader == null) { + return; + } + + XC_LoadPackage.LoadPackageParam lpparam = new XC_LoadPackage.LoadPackageParam( + XposedBridge.sLoadedPackageCallbacks); + lpparam.packageName = this.packageName; + lpparam.processName = this.processName; + lpparam.classLoader = classLoader; + lpparam.appInfo = loadedApk.getApplicationInfo(); + lpparam.isFirstApplication = this.isFirstApplication; + XC_LoadPackage.callAll(lpparam); + + if (this.packageName.equals(INSTALLER_PACKAGE_NAME)) { + XposedInstallerHooker.hookXposedInstaller(lpparam.classLoader); + } + if (this.packageName.equals(BLACK_LIST_PACKAGE_NAME)) { + XposedBlackListHooker.hook(lpparam.classLoader); + } + if (this.packageName.equals(SYSTEMUI_PACKAGE_NAME)) { + SliceProviderFix.hook(); + } + + } catch (Throwable t) { + Hookers.logE("error when hooking LoadedApk#getClassLoader", t); + } finally { + if (unhook != null) { + unhook.unhook(); + } + } + } + + public void setUnhook(Unhook unhook) { + this.unhook = unhook; + } + + public Unhook getUnhook() { + return unhook; + } +} diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle index a74b6124..d45e1ff3 100644 --- a/edxp-core/build.gradle +++ b/edxp-core/build.gradle @@ -4,7 +4,7 @@ import org.gradle.internal.os.OperatingSystem apply plugin: 'com.android.library' // Values set here will be overriden by AppVeyor, feel free to modify during development. -def buildVersionName = 'v0.4.5.4_beta' +def buildVersionName = 'v0.4.5.5_beta' def buildVersionCode = 10000 if (System.env.APPVEYOR_BUILD_VERSION != null) {