[parasitic] Fix 8.1 compatibility (#1157)

This commit is contained in:
LoveSy 2021-09-22 01:16:23 +08:00 committed by GitHub
parent 41755d4464
commit e95c9acbb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 47 additions and 28 deletions

View File

@ -13,6 +13,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo; import android.content.pm.ProviderInfo;
import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
@ -24,7 +25,10 @@ import android.webkit.WebViewFactoryProvider;
import org.lsposed.lspd.BuildConfig; import org.lsposed.lspd.BuildConfig;
import org.lsposed.lspd.ILSPManagerService; import org.lsposed.lspd.ILSPManagerService;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.channels.FileChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -44,6 +48,17 @@ public class ParasiticManagerHooker {
if (managerPkgInfo == null) { if (managerPkgInfo == null) {
Context ctx = ActivityThread.currentActivityThread().getSystemContext(); Context ctx = ActivityThread.currentActivityThread().getSystemContext();
var sourceDir = "/proc/self/fd/" + managerFd; var sourceDir = "/proc/self/fd/" + managerFd;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
var dstDir = appInfo.dataDir + "/cache/lsposed.apk";
try (var inStream = new FileInputStream(sourceDir); var outStream = new FileOutputStream(dstDir)) {
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
sourceDir = dstDir;
} catch (Throwable e) {
Hookers.logE("copy apk", e);
}
}
managerPkgInfo = ctx.getPackageManager().getPackageArchiveInfo(sourceDir, PackageManager.GET_ACTIVITIES); managerPkgInfo = ctx.getPackageManager().getPackageArchiveInfo(sourceDir, PackageManager.GET_ACTIVITIES);
var newAppInfo = managerPkgInfo.applicationInfo; var newAppInfo = managerPkgInfo.applicationInfo;
newAppInfo.sourceDir = sourceDir; newAppInfo.sourceDir = sourceDir;
@ -60,6 +75,35 @@ public class ParasiticManagerHooker {
} }
private static void hookForManager(ILSPManagerService managerService) { private static void hookForManager(ILSPManagerService managerService) {
var managerApkHooker = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
Hookers.logD("ActivityThread#handleBindApplication() starts");
Object bindData = param.args[0];
ApplicationInfo appInfo = (ApplicationInfo) XposedHelpers.getObjectField(bindData, "appInfo");
XposedHelpers.setObjectField(bindData, "appInfo", getManagerPkgInfo(appInfo).applicationInfo);
}
};
XposedHelpers.findAndHookMethod(ActivityThread.class,
"handleBindApplication",
"android.app.ActivityThread$AppBindData",
managerApkHooker);
var unhooks = new XC_MethodHook.Unhook[]{null};
unhooks[0] = XposedHelpers.findAndHookMethod(
LoadedApk.class, "getClassLoader", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (XposedHelpers.getObjectField(param.thisObject, "mApplicationInfo") == getManagerPkgInfo(null).applicationInfo) {
InstallerVerifier.sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder());
unhooks[0].unhook();
}
}
});
if (Process.myUid() != BuildConfig.MANAGER_INJECTED_UID) return;
var activityHooker = new XC_MethodHook() { var activityHooker = new XC_MethodHook() {
@Override @Override
protected void beforeHookedMethod(MethodHookParam param) { protected void beforeHookedMethod(MethodHookParam param) {
@ -81,37 +125,12 @@ public class ParasiticManagerHooker {
} }
} }
}; };
var managerApkHooker = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
Hookers.logD("ActivityThread#handleBindApplication() starts");
Object bindData = param.args[0];
ApplicationInfo appInfo = (ApplicationInfo) XposedHelpers.getObjectField(bindData, "appInfo");
XposedHelpers.setObjectField(bindData, "appInfo", getManagerPkgInfo(appInfo).applicationInfo);
}
};
XposedHelpers.findAndHookMethod(ActivityThread.class,
"handleBindApplication",
"android.app.ActivityThread$AppBindData",
managerApkHooker);
var activityClientRecordClass = XposedHelpers.findClass("android.app.ActivityThread$ActivityClientRecord", ActivityThread.class.getClassLoader()); var activityClientRecordClass = XposedHelpers.findClass("android.app.ActivityThread$ActivityClientRecord", ActivityThread.class.getClassLoader());
XposedBridge.hookAllConstructors(activityClientRecordClass, activityHooker); XposedBridge.hookAllConstructors(activityClientRecordClass, activityHooker);
var unhooks = new XC_MethodHook.Unhook[]{null}; if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
unhooks[0] = XposedHelpers.findAndHookMethod( XposedBridge.hookAllMethods(XposedHelpers.findClass("android.app.ActivityThread$ApplicationThread", ActivityThread.class.getClassLoader()), "scheduleLaunchActivity", activityHooker);
LoadedApk.class, "getClassLoader", new XC_MethodHook() { }
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (XposedHelpers.getObjectField(param.thisObject, "mApplicationInfo") == getManagerPkgInfo(null).applicationInfo) {
InstallerVerifier.sendBinderToManager((ClassLoader) param.getResult(), managerService.asBinder());
unhooks[0].unhook();
}
}
});
if (Process.myUid() != BuildConfig.MANAGER_INJECTED_UID) return;
XposedBridge.hookAllMethods(ActivityThread.class, "handleReceiver", new XC_MethodReplacement() { XposedBridge.hookAllMethods(ActivityThread.class, "handleReceiver", new XC_MethodReplacement() {
@Override @Override