ServiceClient

This commit is contained in:
Nullptr 2022-03-23 22:35:35 +08:00
parent 6f92a67bd7
commit 7905b343dc
24 changed files with 226 additions and 219 deletions

2
core

@ -1 +1 @@
Subproject commit 3049dbb29b6d03f7c49722dbe2fa9c9b278f7120 Subproject commit 57c1b8b904ca3606e59d337cbcb2b595ac0f5acd

View File

@ -1,20 +0,0 @@
plugins {
id("com.android.library")
}
android {
flavorDimensions += "api"
productFlavors.create("Riru") {
dimension = "api"
}
buildTypes {
release {
isMinifyEnabled = true
}
}
}
dependencies {
api(projects.services.daemonService)
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.lsposed.lspatch.manager" />

View File

@ -1,7 +0,0 @@
package org.lsposed.lspatch.manager;
import org.lsposed.lspd.models.Module;
interface IManagerService {
List<Module> getModules();
}

View File

@ -63,8 +63,9 @@ afterEvaluate {
} }
dependencies { dependencies {
implementation(projects.imanager)
implementation(projects.patch) implementation(projects.patch)
implementation(projects.services.daemonService)
implementation(projects.share.android)
implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.activity:activity-compose:1.5.0-alpha03") implementation("androidx.activity:activity-compose:1.5.0-alpha03")

View File

@ -0,0 +1,30 @@
package org.lsposed.lspatch.manager
import android.os.Bundle
import android.os.IBinder
import android.os.ParcelFileDescriptor
import org.lsposed.lspd.models.Module
import org.lsposed.lspd.service.ILSPApplicationService
object ManagerService : ILSPApplicationService.Stub() {
override fun requestModuleBinder(name: String): IBinder {
TODO("Not yet implemented")
}
override fun getModulesList(): List<Module> {
return ModuleProvider.allModules
}
override fun getPrefsPath(packageName: String): String {
TODO("Not yet implemented")
}
override fun requestRemotePreference(packageName: String, userId: Int, callback: IBinder?): Bundle {
TODO("Not yet implemented")
}
override fun requestInjectedManagerBinder(binder: List<IBinder>?): ParcelFileDescriptor? {
return null
}
}

View File

@ -1,9 +0,0 @@
package org.lsposed.lspatch.manager
import org.lsposed.lspd.models.Module
class ManagerServiceImpl : IManagerService.Stub() {
override fun getModules(): List<Module> {
return ModuleProvider.allModules
}
}

View File

@ -9,10 +9,10 @@ import android.os.Binder
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import org.lsposed.lspatch.TAG import org.lsposed.lspatch.TAG
import org.lsposed.lspatch.util.ModuleLoader
import org.lsposed.lspd.models.Module import org.lsposed.lspd.models.Module
class ModuleProvider : ContentProvider() { class ModuleProvider : ContentProvider() {
companion object { companion object {
lateinit var allModules: List<Module> lateinit var allModules: List<Module>
} }
@ -28,7 +28,7 @@ class ModuleProvider : ContentProvider() {
"getBinder" -> { "getBinder" -> {
loadAllModules() loadAllModules()
return Bundle().apply { return Bundle().apply {
putBinder("binder", ManagerServiceImpl()) putBinder("binder", ManagerService.asBinder())
} }
} }
else -> throw IllegalArgumentException("Invalid method name") else -> throw IllegalArgumentException("Invalid method name")

View File

@ -57,8 +57,8 @@ dependencies {
implementation(projects.core) implementation(projects.core)
implementation(projects.hiddenapi.bridge) implementation(projects.hiddenapi.bridge)
implementation(projects.services.daemonService) implementation(projects.services.daemonService)
implementation(projects.imanager) implementation(projects.share.android)
implementation(projects.share) implementation(projects.share.java)
implementation("com.google.code.gson:gson:2.9.0") implementation("com.google.code.gson:gson:2.9.0")
} }

View File

@ -1,29 +0,0 @@
package de.robv.android.xposed;
import java.lang.reflect.Member;
public class XposedHelper {
private static final String TAG = "XposedHelper";
public static void initSeLinux(String processName) {
// SELinuxHelper.initOnce();
// SELinuxHelper.initForProcess(processName);
}
public static boolean isIXposedMod(Class<?> moduleClass) {
return IXposedMod.class.isAssignableFrom(moduleClass);
}
public static XC_MethodHook.Unhook newUnHook(XC_MethodHook XC_MethodHook, Member member) {
return XC_MethodHook.new Unhook(member);
}
public static void callInitZygote(String modulePath, Object moduleInstance) throws Throwable {
IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
param.modulePath = modulePath;
param.startsSystemServer = false;
((IXposedHookZygoteInit) moduleInstance).initZygote(param);
}
}

View File

@ -12,12 +12,8 @@ import android.content.pm.PackageInfo;
import android.content.pm.Signature; import android.content.pm.Signature;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.system.Os; import android.system.Os;
import android.util.Log; import android.util.Log;
@ -25,13 +21,13 @@ import com.google.gson.Gson;
import org.lsposed.lspatch.loader.util.FileUtils; import org.lsposed.lspatch.loader.util.FileUtils;
import org.lsposed.lspatch.loader.util.XLog; import org.lsposed.lspatch.loader.util.XLog;
import org.lsposed.lspatch.manager.ModuleLoader; import org.lsposed.lspatch.service.LocalApplicationService;
import org.lsposed.lspatch.service.RemoteApplicationService;
import org.lsposed.lspatch.share.Constants; import org.lsposed.lspatch.share.Constants;
import org.lsposed.lspatch.share.PatchConfig; import org.lsposed.lspatch.share.PatchConfig;
import org.lsposed.lspd.config.ApplicationServiceClient;
import org.lsposed.lspd.core.Startup; import org.lsposed.lspd.core.Startup;
import org.lsposed.lspd.models.Module;
import org.lsposed.lspd.nativebridge.SigBypass; import org.lsposed.lspd.nativebridge.SigBypass;
import org.lsposed.lspd.service.ILSPApplicationService;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -46,7 +42,6 @@ import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermissions; import java.nio.file.attribute.PosixFilePermissions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
@ -59,7 +54,10 @@ import hidden.HiddenApiBridge;
* Created by Windysha * Created by Windysha
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class LSPApplication extends ApplicationServiceClient { public class LSPApplication {
public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
public static final int PER_USER_RANGE = 100000;
private static final String TAG = "LSPatch"; private static final String TAG = "LSPatch";
private static ActivityThread activityThread; private static ActivityThread activityThread;
@ -67,16 +65,8 @@ public class LSPApplication extends ApplicationServiceClient {
private static LoadedApk appLoadedApk; private static LoadedApk appLoadedApk;
private static PatchConfig config; private static PatchConfig config;
private static ManagerResolver managerResolver = null;
final static public int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; public static boolean isIsolated() {
final static public int PER_USER_RANGE = 100000;
static private LSPApplication instance = null;
static private final List<Module> modules = new ArrayList<>();
static public boolean isIsolated() {
return (android.os.Process.myUid() % PER_USER_RANGE) >= FIRST_APP_ZYGOTE_ISOLATED_UID; return (android.os.Process.myUid() % PER_USER_RANGE) >= FIRST_APP_ZYGOTE_ISOLATED_UID;
} }
@ -92,20 +82,19 @@ public class LSPApplication extends ApplicationServiceClient {
return; return;
} }
if (config.useManager) try { Log.d(TAG, "Initialize service client");
managerResolver = new ManagerResolver(context); ILSPApplicationService service;
} catch (RemoteException e) { if (config.useManager) {
Log.e(TAG, "Failed to instantiate manager resolver", e); service = new RemoteApplicationService(context);
} else {
service = new LocalApplicationService(context);
} }
instance = new LSPApplication();
serviceClient = instance;
try { try {
disableProfile(context); disableProfile(context);
loadModules(context); Startup.initXposed(false, ActivityThread.currentProcessName(), service);
Startup.initXposed(false);
Log.i(TAG, "Start loading modules"); Log.i(TAG, "Start loading modules");
Startup.bootstrapXposed(ActivityThread.currentProcessName()); Startup.bootstrapXposed();
// WARN: Since it uses `XResource`, the following class should not be initialized // WARN: Since it uses `XResource`, the following class should not be initialized
// before forkPostCommon is invoke. Otherwise, you will get failure of XResources // before forkPostCommon is invoke. Otherwise, you will get failure of XResources
LSPLoader.initModules(appLoadedApk); LSPLoader.initModules(appLoadedApk);
@ -246,48 +235,6 @@ public class LSPApplication extends ApplicationServiceClient {
} }
public static void loadModules(Context context) {
if (config.useManager) {
try {
modules.addAll(managerResolver.getModules());
modules.forEach(m -> Log.i(TAG, "load module from manager: " + m.packageName));
} catch (NullPointerException | RemoteException e) {
Log.e(TAG, "Failed to get modules from manager", e);
}
} else {
try {
for (var name : context.getAssets().list("lspatch/modules")) {
String packageName = name.substring(0, name.length() - 4);
String modulePath = context.getCacheDir() + "/lspatch/" + packageName + "/";
String cacheApkPath;
try (ZipFile sourceFile = new ZipFile(context.getPackageResourcePath())) {
cacheApkPath = modulePath + sourceFile.getEntry("assets/lspatch/modules/" + name).getCrc();
}
if (!Files.exists(Paths.get(cacheApkPath))) {
Log.i(TAG, "Extract module apk: " + packageName);
FileUtils.deleteFolderIfExists(Paths.get(modulePath));
Files.createDirectories(Paths.get(modulePath));
try (var is = context.getAssets().open("lspatch/modules/" + name)) {
Files.copy(is, Paths.get(cacheApkPath));
}
}
var module = new Module();
module.apkPath = cacheApkPath;
module.packageName = packageName;
module.file = ModuleLoader.loadModule(cacheApkPath);
modules.add(module);
}
} catch (Throwable ignored) {
}
}
}
public LSPApplication() {
super();
}
private static int getTranscationId(String clsName, String trasncationName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { private static int getTranscationId(String clsName, String trasncationName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Field field = Class.forName(clsName).getDeclaredField(trasncationName); Field field = Class.forName(clsName).getDeclaredField(trasncationName);
field.setAccessible(true); field.setAccessible(true);
@ -377,39 +324,4 @@ public class LSPApplication extends ApplicationServiceClient {
var obj = XposedHelpers.getObjectField(appLoadedApk, fieldName); var obj = XposedHelpers.getObjectField(appLoadedApk, fieldName);
XposedHelpers.setObjectField(stubLoadedApk, fieldName, obj); XposedHelpers.setObjectField(stubLoadedApk, fieldName, obj);
} }
@Override
public IBinder requestModuleBinder(String name) {
return null;
}
@Override
public List getModulesList(String processName) {
return getModulesList();
}
@Override
public List<Module> getModulesList() {
return modules;
}
@Override
public String getPrefsPath(String packageName) {
return new File(Environment.getDataDirectory(), "data/" + packageName + "/shared_prefs/").getAbsolutePath();
}
@Override
public Bundle requestRemotePreference(String packageName, int userId, IBinder callback) {
return null;
}
@Override
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) throws RemoteException {
return null;
}
@Override
public IBinder asBinder() {
return null;
}
} }

View File

@ -1,36 +0,0 @@
package org.lsposed.lspatch.loader;
import static org.lsposed.lspatch.share.Constants.MANAGER_PACKAGE_NAME;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import org.lsposed.lspatch.manager.IManagerService;
import org.lsposed.lspd.models.Module;
import java.util.List;
public class ManagerResolver {
private static final Uri PROVIDER = Uri.parse("content://" + MANAGER_PACKAGE_NAME + ".provider");
private final IManagerService service;
public ManagerResolver(Context context) throws RemoteException {
try {
Bundle back = context.getContentResolver().call(PROVIDER, "getBinder", null, null);
service = IManagerService.Stub.asInterface(back.getBinder("binder"));
if (service == null) throw new RemoteException("Binder is null");
} catch (Throwable t) {
var e = new RemoteException("Failed to get manager binder");
e.setStackTrace(new StackTraceElement[0]);
e.addSuppressed(t);
throw e;
}
}
public List<Module> getModules() throws RemoteException {
return service.getModules();
}
}

View File

@ -0,0 +1,83 @@
package org.lsposed.lspatch.service;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import org.lsposed.lspatch.loader.util.FileUtils;
import org.lsposed.lspatch.util.ModuleLoader;
import org.lsposed.lspd.models.Module;
import org.lsposed.lspd.service.ILSPApplicationService;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;
public class LocalApplicationService extends ILSPApplicationService.Stub {
private static final String TAG = "LSPatch";
private final List<Module> modules = new ArrayList<>();
public LocalApplicationService(Context context) {
try {
for (var name : context.getAssets().list("lspatch/modules")) {
String packageName = name.substring(0, name.length() - 4);
String modulePath = context.getCacheDir() + "/lspatch/" + packageName + "/";
String cacheApkPath;
try (ZipFile sourceFile = new ZipFile(context.getPackageResourcePath())) {
cacheApkPath = modulePath + sourceFile.getEntry("assets/lspatch/modules/" + name).getCrc();
}
if (!Files.exists(Paths.get(cacheApkPath))) {
Log.i(TAG, "Extract module apk: " + packageName);
FileUtils.deleteFolderIfExists(Paths.get(modulePath));
Files.createDirectories(Paths.get(modulePath));
try (var is = context.getAssets().open("lspatch/modules/" + name)) {
Files.copy(is, Paths.get(cacheApkPath));
}
}
var module = new Module();
module.apkPath = cacheApkPath;
module.packageName = packageName;
module.file = ModuleLoader.loadModule(cacheApkPath);
modules.add(module);
}
} catch (IOException e) {
Log.e(TAG, "Error when initializing LocalApplicationServiceClient", e);
}
}
@Override
public IBinder requestModuleBinder(String name) {
return null;
}
@Override
public List<Module> getModulesList() {
return modules;
}
@Override
public String getPrefsPath(String packageName) {
return new File(Environment.getDataDirectory(), "data/" + packageName + "/shared_prefs/").getAbsolutePath();
}
@Override
public Bundle requestRemotePreference(String packageName, int userId, IBinder callback) {
return null;
}
@Override
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) {
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.lsposed.lspatch.service;
import static org.lsposed.lspatch.share.Constants.MANAGER_PACKAGE_NAME;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import org.lsposed.lspd.models.Module;
import org.lsposed.lspd.service.ILSPApplicationService;
import java.util.List;
public class RemoteApplicationService implements ILSPApplicationService {
private static final Uri PROVIDER = Uri.parse("content://" + MANAGER_PACKAGE_NAME + ".provider");
private ILSPApplicationService service;
public RemoteApplicationService(Context context) {
try {
Bundle back = context.getContentResolver().call(PROVIDER, "getBinder", null, null);
service = ILSPApplicationService.Stub.asInterface(back.getBinder("binder"));
if (service == null) throw new RemoteException("Binder is null");
} catch (RemoteException e) {
Log.e("LSPatch", "Error when initializing RemoteApplicationServiceClient", e);
}
}
@Override
public IBinder requestModuleBinder(String name) {
return service.asBinder();
}
@Override
public List<Module> getModulesList() throws RemoteException {
return service.getModulesList();
}
@Override
public String getPrefsPath(String packageName) throws RemoteException {
return service.getPrefsPath(packageName);
}
@Override
public Bundle requestRemotePreference(String packageName, int userId, IBinder callback) throws RemoteException {
return service.requestRemotePreference(packageName, userId, callback);
}
@Override
public IBinder asBinder() {
return service.asBinder();
}
@Override
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) {
return null;
}
}

View File

@ -14,7 +14,7 @@ dependencies {
implementation(fileTree("dir" to "libs", "include" to listOf("*.jar"))) implementation(fileTree("dir" to "libs", "include" to listOf("*.jar")))
implementation(projects.apkzlib) implementation(projects.apkzlib)
implementation(projects.axmlprinter) implementation(projects.axmlprinter)
implementation(projects.share) implementation(projects.share.java)
implementation("commons-io:commons-io:2.11.0") implementation("commons-io:commons-io:2.11.0")
implementation("com.beust:jcommander:1.82") implementation("com.beust:jcommander:1.82")

View File

@ -19,7 +19,6 @@ import com.wind.meditor.property.AttributeItem;
import com.wind.meditor.property.ModificationProperty; import com.wind.meditor.property.ModificationProperty;
import com.wind.meditor.utils.NodeValue; import com.wind.meditor.utils.NodeValue;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.lsposed.lspatch.share.PatchConfig; import org.lsposed.lspatch.share.PatchConfig;
import org.lsposed.patch.util.ApkSignatureHelper; import org.lsposed.patch.util.ApkSignatureHelper;
@ -34,7 +33,6 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -29,7 +29,6 @@ include(
":core", ":core",
":hiddenapi:bridge", ":hiddenapi:bridge",
":hiddenapi:stubs", ":hiddenapi:stubs",
":imanager",
":manager", ":manager",
":patch", ":patch",
":patch-jar", ":patch-jar",
@ -37,7 +36,8 @@ include(
":services:daemon-service", ":services:daemon-service",
":services:manager-service", ":services:manager-service",
":services:xposed-service:interface", ":services:xposed-service:interface",
":share" ":share:android",
":share:java"
) )
project(":core").projectDir = file("core/core") project(":core").projectDir = file("core/core")

View File

@ -0,0 +1,23 @@
plugins {
id("com.android.library")
}
android {
namespace = "org.lsposed.lspatch.share"
buildFeatures {
androidResources = false
buildConfig = false
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
}
}
}
dependencies {
implementation(projects.services.daemonService)
}

View File

@ -1,4 +1,4 @@
package org.lsposed.lspatch.manager; package org.lsposed.lspatch.util;
import android.os.SharedMemory; import android.os.SharedMemory;
import android.system.ErrnoException; import android.system.ErrnoException;