parent
81448c3958
commit
85a05bbbd1
|
|
@ -29,9 +29,8 @@ import com.android.internal.os.ZygoteInit;
|
|||
|
||||
import org.lsposed.lspd.deopt.PrebuiltMethodsDeopter;
|
||||
import org.lsposed.lspd.hooker.CrashDumpHooker;
|
||||
import org.lsposed.lspd.hooker.HandleBindAppHooker;
|
||||
import org.lsposed.lspd.hooker.HandleSystemServerProcessHooker;
|
||||
import org.lsposed.lspd.hooker.LoadedApkCstrHooker;
|
||||
import org.lsposed.lspd.hooker.LoadedApkCtorHooker;
|
||||
import org.lsposed.lspd.service.ILSPApplicationService;
|
||||
import org.lsposed.lspd.util.Utils;
|
||||
|
||||
|
|
@ -48,14 +47,10 @@ public class Startup {
|
|||
XposedBridge.hookAllMethods(ZygoteInit.class,
|
||||
"handleSystemServerProcess", new HandleSystemServerProcessHooker());
|
||||
}
|
||||
XposedHelpers.findAndHookMethod(ActivityThread.class,
|
||||
"handleBindApplication",
|
||||
"android.app.ActivityThread$AppBindData",
|
||||
new HandleBindAppHooker());
|
||||
XposedHelpers.findAndHookConstructor(LoadedApk.class,
|
||||
ActivityThread.class, ApplicationInfo.class, CompatibilityInfo.class,
|
||||
ClassLoader.class, boolean.class, boolean.class, boolean.class,
|
||||
new LoadedApkCstrHooker());
|
||||
new LoadedApkCtorHooker());
|
||||
}
|
||||
|
||||
public static void bootstrapXposed() {
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* This file is part of LSPosed.
|
||||
*
|
||||
* LSPosed is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* LSPosed is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright (C) 2020 EdXposed Contributors
|
||||
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
||||
*/
|
||||
|
||||
package org.lsposed.lspd.hooker;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.app.LoadedApk;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.XResources;
|
||||
|
||||
import org.lsposed.lspd.util.Hookers;
|
||||
import org.lsposed.lspd.util.Utils;
|
||||
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.XposedInit;
|
||||
|
||||
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
|
||||
public class HandleBindAppHooker extends XC_MethodHook {
|
||||
|
||||
@Override
|
||||
protected void beforeHookedMethod(MethodHookParam param) {
|
||||
try {
|
||||
Hookers.logD("ActivityThread#handleBindApplication() starts");
|
||||
ActivityThread activityThread = (ActivityThread) param.thisObject;
|
||||
Object bindData = param.args[0];
|
||||
final ApplicationInfo appInfo = (ApplicationInfo) XposedHelpers.getObjectField(bindData, "appInfo");
|
||||
// save app process name here for later use
|
||||
String appProcessName = (String) XposedHelpers.getObjectField(bindData, "processName");
|
||||
String reportedPackageName = appInfo.packageName.equals("android") ? "system" : appInfo.packageName;
|
||||
|
||||
// Note: packageName="android" -> system_server process, ams pms etc;
|
||||
// packageName="system" -> android pkg, system dialogues.
|
||||
Utils.logD("processName=" + appProcessName + ", packageName=" + reportedPackageName);
|
||||
|
||||
CompatibilityInfo compatInfo = (CompatibilityInfo) XposedHelpers.getObjectField(bindData, "compatInfo");
|
||||
if (appInfo.sourceDir == null) {
|
||||
return;
|
||||
}
|
||||
XposedHelpers.setObjectField(activityThread, "mBoundApplication", bindData);
|
||||
XposedInit.loadedPackagesInProcess.add(reportedPackageName);
|
||||
LoadedApk loadedApk = activityThread.getPackageInfoNoCheck(appInfo, compatInfo);
|
||||
|
||||
if (!XposedInit.disableResources) {
|
||||
XResources.setPackageNameForResDir(appInfo.packageName, loadedApk.getResDir());
|
||||
}
|
||||
|
||||
String processName = (String) XposedHelpers.getObjectField(bindData, "processName");
|
||||
|
||||
LoadedApkGetCLHooker hook = new LoadedApkGetCLHooker(loadedApk, reportedPackageName,
|
||||
processName, true);
|
||||
hook.setUnhook(XposedHelpers.findAndHookMethod(
|
||||
LoadedApk.class, "getClassLoader", hook));
|
||||
|
||||
} catch (Throwable t) {
|
||||
Hookers.logE("error when hooking bindApp", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
package org.lsposed.lspd.hooker;
|
||||
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.app.LoadedApk;
|
||||
import android.content.res.XResources;
|
||||
import android.util.Log;
|
||||
|
|
@ -32,7 +31,7 @@ import de.robv.android.xposed.XposedHelpers;
|
|||
import de.robv.android.xposed.XposedInit;
|
||||
|
||||
// when a package is loaded for an existing process, trigger the callbacks as well
|
||||
public class LoadedApkCstrHooker extends XC_MethodHook {
|
||||
public class LoadedApkCtorHooker extends XC_MethodHook {
|
||||
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
|
|
@ -49,8 +48,12 @@ public class LoadedApkCstrHooker extends XC_MethodHook {
|
|||
}
|
||||
|
||||
if (packageName.equals("android")) {
|
||||
Hookers.logD("LoadedApk#<init> is android, skip: " + mAppDir);
|
||||
return;
|
||||
if (XposedInit.startsSystemServer) {
|
||||
Hookers.logD("LoadedApk#<init> is android, skip: " + mAppDir);
|
||||
return;
|
||||
} else {
|
||||
packageName = "system";
|
||||
}
|
||||
}
|
||||
|
||||
// mIncludeCode checking should go ahead of loadedPackagesInProcess added checking
|
||||
|
|
@ -59,11 +62,6 @@ public class LoadedApkCstrHooker extends XC_MethodHook {
|
|||
return;
|
||||
}
|
||||
|
||||
if (XposedInit.loadedPackagesInProcess.isEmpty()) {
|
||||
Hookers.logD("First LoadedApk should be called by handleBindApplication, skip: " + mAppDir);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!XposedInit.loadedPackagesInProcess.add(packageName)) {
|
||||
Hookers.logD("LoadedApk#<init> has been loaded before, skip: " + mAppDir);
|
||||
return;
|
||||
|
|
@ -76,11 +74,7 @@ public class LoadedApkCstrHooker extends XC_MethodHook {
|
|||
return;
|
||||
}
|
||||
|
||||
LoadedApkGetCLHooker hook = new LoadedApkGetCLHooker(loadedApk, packageName,
|
||||
AndroidAppHelper.currentProcessName(), false);
|
||||
hook.setUnhook(XposedHelpers.findAndHookMethod(
|
||||
LoadedApk.class, "getClassLoader", hook));
|
||||
|
||||
new LoadedApkGetCLHooker(loadedApk);
|
||||
} catch (Throwable t) {
|
||||
Hookers.logE("error when hooking LoadedApk.<init>", t);
|
||||
}
|
||||
|
|
@ -22,6 +22,8 @@ package org.lsposed.lspd.hooker;
|
|||
|
||||
import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.app.LoadedApk;
|
||||
import android.os.IBinder;
|
||||
|
||||
|
|
@ -41,17 +43,11 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
|||
|
||||
public class LoadedApkGetCLHooker extends XC_MethodHook {
|
||||
private final LoadedApk loadedApk;
|
||||
private final String packageName;
|
||||
private final String processName;
|
||||
private final boolean isFirstApplication;
|
||||
private Unhook unhook;
|
||||
private final Unhook unhook;
|
||||
|
||||
public LoadedApkGetCLHooker(LoadedApk loadedApk, String packageName, String processName,
|
||||
boolean isFirstApplication) {
|
||||
public LoadedApkGetCLHooker(LoadedApk loadedApk) {
|
||||
this.loadedApk = loadedApk;
|
||||
this.packageName = packageName;
|
||||
this.processName = processName;
|
||||
this.isFirstApplication = isFirstApplication;
|
||||
unhook = XposedHelpers.findAndHookMethod(LoadedApk.class, "getClassLoader", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -63,7 +59,17 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
|
|||
}
|
||||
|
||||
try {
|
||||
Hookers.logD("LoadedApk#getClassLoader starts: isFirst=" + isFirstApplication);
|
||||
Hookers.logD("LoadedApk#getClassLoader starts");
|
||||
|
||||
String packageName = ActivityThread.currentPackageName();
|
||||
String processName = ActivityThread.currentProcessName();
|
||||
boolean isFirstApplication = packageName != null && processName != null && packageName.equals(loadedApk.getPackageName());
|
||||
if (!isFirstApplication) {
|
||||
packageName = loadedApk.getPackageName();
|
||||
processName = AndroidAppHelper.currentProcessName();
|
||||
} else if (packageName.equals("android")) {
|
||||
packageName = "system";
|
||||
}
|
||||
|
||||
Object mAppDir = XposedHelpers.getObjectField(loadedApk, "mAppDir");
|
||||
ClassLoader classLoader = (ClassLoader) param.getResult();
|
||||
|
|
@ -86,15 +92,13 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
|
|||
hookNewXSP(lpparam);
|
||||
}
|
||||
|
||||
Hookers.logD("Call handleLoadedPackage: packageName=" + lpparam.packageName + " processName=" + lpparam.processName + " isFirstApplication=" + isFirstApplication + " classLoader=" + lpparam.classLoader + " appInfo=" + lpparam.appInfo);
|
||||
XC_LoadPackage.callAll(lpparam);
|
||||
|
||||
} catch (Throwable t) {
|
||||
Hookers.logE("error when hooking LoadedApk#getClassLoader", t);
|
||||
} finally {
|
||||
if (unhook != null) {
|
||||
unhook.unhook();
|
||||
unhook = null;
|
||||
}
|
||||
unhook.unhook();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,8 +136,4 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void setUnhook(Unhook unhook) {
|
||||
this.unhook = unhook;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue