Implement module service

This commit is contained in:
Nullptr 2022-12-31 20:18:09 +08:00 committed by LoveSy
parent d29a3bf16e
commit fb0ceca588
12 changed files with 157 additions and 44 deletions

View File

@ -57,15 +57,6 @@ public class ApplicationServiceClient implements ILSPApplicationService, IBinder
}
}
@Override
public IBinder requestModuleBinder(String name) {
try {
return service.requestModuleBinder(name);
} catch (RemoteException | NullPointerException ignored) {
}
return null;
}
@Override
public List<Module> getLegacyModulesList() {
try {

View File

@ -25,7 +25,6 @@ import static org.lsposed.lspd.core.ApplicationServiceClient.serviceClient;
import android.app.ActivityThread;
import android.app.AndroidAppHelper;
import android.app.LoadedApk;
import android.os.IBinder;
import org.lsposed.lspd.impl.LSPosedContext;
import org.lsposed.lspd.util.Hookers;
@ -89,10 +88,7 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
lpparam.appInfo = loadedApk.getApplicationInfo();
lpparam.isFirstApplication = isFirstApplication;
IBinder moduleBinder = serviceClient.requestModuleBinder(lpparam.packageName);
if (moduleBinder != null) {
hookNewXSP(lpparam);
}
Hookers.logD("Call handleLoadedPackage: packageName=" + lpparam.packageName + " processName=" + lpparam.processName + " isFirstApplication=" + isFirstApplication + " classLoader=" + lpparam.classLoader + " appInfo=" + lpparam.appInfo);
XC_LoadPackage.callAll(lpparam);

View File

@ -0,0 +1,15 @@
package io.github.libxposed.service;
import io.github.xposed.xposedservice.IXposedService;
public abstract class XposedService extends IXposedService.Stub {
public static final int API = 100;
public static final String AUTHORITY_SUFFIX = ".XposedService";
public static final String SEND_BINDER = "SendBinder";
@Override
public final int getVersion() {
return API;
}
}

View File

@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
import android.app.IActivityManager;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.IUidObserver;
import android.app.ProfilerInfo;
import android.content.Context;
import android.content.IContentProvider;
@ -194,4 +195,9 @@ public class ActivityManagerService {
}
}
public static void registerUidObserver(IUidObserver observer, int which, int cutpoint, String callingPackage) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null) return;
am.registerUidObserver(observer, which, cutpoint, callingPackage);
}
}

View File

@ -151,15 +151,6 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
return bundle;
}
@Override
public IBinder requestModuleBinder(String name) throws RemoteException {
var processInfo = ensureRegistered();
if (ConfigManager.getInstance().isModule(processInfo.uid, name)) {
ConfigManager.getInstance().ensureModulePrefsPermission(processInfo.uid, name);
return ServiceManager.getModuleService(name);
} else return null;
}
@Override
public ParcelFileDescriptor requestInjectedManagerBinder(List<IBinder> binder) throws RemoteException {
var processInfo = ensureRegistered();

View File

@ -19,27 +19,95 @@
package org.lsposed.lspd.service;
import android.os.IBinder;
import android.app.IUidObserver;
import android.content.AttributionSource;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import org.lsposed.daemon.BuildConfig;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import io.github.xposed.xposedservice.IXposedService;
import hidden.HiddenApiBridge;
import io.github.libxposed.service.XposedService;
public class LSPModuleService extends IXposedService.Stub {
public class LSPModuleService extends XposedService {
final private String name;
private static final String TAG = "LSPosedModuleService";
public LSPModuleService(String name) {
this.name = name;
private final Set<Integer> uidSet = ConcurrentHashMap.newKeySet();
private final IUidObserver uidObserver = new IUidObserver.Stub() {
@Override
public void onUidActive(int uid) {
uidStarts(uid);
}
@Override
public IBinder asBinder() {
return this;
public void onUidCachedChanged(int uid, boolean cached) {
if (!cached) uidStarts(uid);
}
@Override
public int getVersion() {
return BuildConfig.API_CODE;
public void onUidIdle(int uid, boolean disabled) {
uidStarts(uid);
}
@Override
public void onUidGone(int uid, boolean disabled) {
uidSet.remove(uid);
}
};
void registerObserver() {
uidSet.clear();
int flags = HiddenApiBridge.ActivityManager_UID_OBSERVER_ACTIVE()
| HiddenApiBridge.ActivityManager_UID_OBSERVER_GONE()
| HiddenApiBridge.ActivityManager_UID_OBSERVER_IDLE()
| HiddenApiBridge.ActivityManager_UID_OBSERVER_CACHED();
try {
ActivityManagerService.registerUidObserver(uidObserver, flags, HiddenApiBridge.ActivityManager_PROCESS_STATE_UNKNOWN(), null);
Log.i(TAG, "registered uid observer");
} catch (RemoteException e) {
Log.e(TAG, "failed to register uid observer", e);
}
}
private void uidStarts(int uid) {
if (!uidSet.contains(uid)) {
uidSet.add(uid);
var module = ConfigManager.getInstance().getModule(uid);
if (module != null) sendBinder(uid, module);
}
}
private void sendBinder(int uid, String name) {
try {
int userId = uid / PackageService.PER_USER_RANGE;
var authority = name + AUTHORITY_SUFFIX;
var provider = ActivityManagerService.getContentProvider(authority, userId);
if (provider == null) {
Log.d(TAG, "no service provider for " + name);
return;
}
var extra = new Bundle();
extra.putBinder("binder", asBinder());
Bundle reply = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
reply = provider.call(new AttributionSource.Builder(1000).setPackageName("android").build(),
authority, SEND_BINDER, null, extra);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
reply = provider.call("android", null, authority, SEND_BINDER, null, extra);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
reply = provider.call("android", authority, SEND_BINDER, null, extra);
}
if (reply != null) {
Log.d(TAG, "sent module binder to " + name);
} else {
Log.w(TAG, "failed to send module binder to " + name);
}
} catch (RemoteException | NoSuchMethodError e) {
Log.w(TAG, "failed to send module binder for uid " + uid, e);
}
}
}

View File

@ -36,7 +36,6 @@ import com.android.internal.os.BinderInternal;
import org.lsposed.daemon.BuildConfig;
import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -44,12 +43,12 @@ import hidden.HiddenApiBridge;
public class ServiceManager {
public static final String TAG = "LSPosedService";
private static final ConcurrentHashMap<String, LSPModuleService> moduleServices = new ConcurrentHashMap<>();
private static final File globalNamespace = new File("/proc/1/root");
@SuppressWarnings("FieldCanBeLocal")
private static LSPosedService mainService = null;
private static LSPApplicationService applicationService = null;
private static LSPManagerService managerService = null;
private static LSPModuleService moduleService = null;
private static LSPSystemServerService systemServerService = null;
private static LogcatService logcatService = null;
private static Dex2OatService dex2OatService = null;
@ -114,6 +113,7 @@ public class ServiceManager {
mainService = new LSPosedService();
applicationService = new LSPApplicationService();
managerService = new LSPManagerService();
moduleService = new LSPModuleService();
systemServerService = new LSPSystemServerService(systemServerMaxRetry);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
dex2OatService = new Dex2OatService();
@ -142,6 +142,7 @@ public class ServiceManager {
@Override
public void onSystemServerRestarted() {
Log.w(TAG, "system restarted...");
moduleService.registerObserver();
}
@Override
@ -152,6 +153,7 @@ public class ServiceManager {
Log.w(TAG, "no response from bridge");
}
systemServerService.maybeRetryInject();
moduleService.registerObserver();
}
@Override
@ -171,10 +173,6 @@ public class ServiceManager {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
public static LSPModuleService getModuleService(String module) {
return moduleServices.computeIfAbsent(module, LSPModuleService::new);
}
public static LSPApplicationService getApplicationService() {
return applicationService;
}

View File

@ -19,6 +19,7 @@
package hidden;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@ -127,4 +128,24 @@ public class HiddenApiBridge {
return Os.ioctlInt(fd, cmd);
}
}
public static int ActivityManager_UID_OBSERVER_GONE() {
return ActivityManager.UID_OBSERVER_GONE;
}
public static int ActivityManager_UID_OBSERVER_ACTIVE() {
return ActivityManager.UID_OBSERVER_ACTIVE;
}
public static int ActivityManager_UID_OBSERVER_IDLE() {
return ActivityManager.UID_OBSERVER_IDLE;
}
public static int ActivityManager_UID_OBSERVER_CACHED() {
return ActivityManager.UID_OBSERVER_CACHED;
}
public static int ActivityManager_PROCESS_STATE_UNKNOWN() {
return ActivityManager.PROCESS_STATE_UNKNOWN;
}
}

View File

@ -0,0 +1,9 @@
package android.app;
public class ActivityManager {
public static int UID_OBSERVER_GONE;
public static int UID_OBSERVER_ACTIVE;
public static int UID_OBSERVER_IDLE;
public static int UID_OBSERVER_CACHED;
public static int PROCESS_STATE_UNKNOWN;
}

View File

@ -40,6 +40,7 @@ public interface IActivityManager extends IInterface {
String[] requiredPermissions, String[] excludedPermissions,
String[] excludePackages, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) throws RemoteException;
@RequiresApi(31)
int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo,
@ -122,6 +123,8 @@ public interface IActivityManager extends IInterface {
Configuration getConfiguration() throws RemoteException;
void registerUidObserver(IUidObserver observer, int which, int cutpoint, String callingPackage) throws RemoteException;
abstract class Stub extends Binder implements IActivityManager {
public static int TRANSACTION_setActivityController;

View File

@ -0,0 +1,17 @@
package android.app;
import android.os.Binder;
public interface IUidObserver {
void onUidGone(int uid, boolean disabled);
void onUidActive(int uid);
void onUidIdle(int uid, boolean disabled);
void onUidCachedChanged(int uid, boolean cached);
abstract class Stub extends Binder implements IUidObserver {
}
}

View File

@ -3,8 +3,6 @@ package org.lsposed.lspd.service;
import org.lsposed.lspd.models.Module;
interface ILSPApplicationService {
IBinder requestModuleBinder(String name);
List<Module> getLegacyModulesList();
List<Module> getModulesList();