Delay the loaded package callbacks

util LoadedApk#getClassLoader is called
This commit is contained in:
solohsu 2019-06-27 16:34:46 +08:00
parent a26990ec99
commit 9256898503
5 changed files with 109 additions and 34 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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.<init>", t);
}

View File

@ -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;
}
}

View File

@ -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) {