New permission manager workaround (#2598)

This commit is contained in:
5ec1cff 2023-07-03 15:47:22 +08:00 committed by GitHub
parent 6f6c4b67d7
commit df4ce63f41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 17 deletions

View File

@ -210,16 +210,6 @@ public class ConfigManager {
@SuppressLint("BlockedPrivateApi")
public List<Module> getModulesForSystemServer() {
var at = ActivityThread.currentActivityThread();
Field permissionManager = null;
try {
// PackageParser need to access PermissionManager, but it's not initialized yet
permissionManager = ActivityThread.class.getDeclaredField("sPermissionManager");
permissionManager.setAccessible(true);
permissionManager.set(at, (IPermissionManager) ArrayList::new);
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
List<Module> modules = new LinkedList<>();
try (Cursor cursor = db.query("scope INNER JOIN modules ON scope.mid = modules.mid", new String[]{"module_pkg_name", "apk_path"}, "app_pkg_name=? AND enabled=1", new String[]{"system"}, null, null, null)) {
int apkPathIdx = cursor.getColumnIndex("apk_path");
@ -247,13 +237,6 @@ public class ConfigManager {
}
}
if (permissionManager != null) {
try {
permissionManager.set(at, null);
} catch (IllegalAccessException ignored) {
}
}
return modules.parallelStream().filter(m -> {
var file = ConfigFileManager.loadModule(m.apkPath, dexObfuscate);
if (file == null) {

View File

@ -22,13 +22,18 @@ package org.lsposed.lspd.service;
import android.app.ActivityThread;
import android.content.Context;
import android.ddm.DdmHandleAppName;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.IServiceManager;
import android.os.Looper;
import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.android.internal.os.BinderInternal;
@ -36,6 +41,11 @@ import com.android.internal.os.BinderInternal;
import org.lsposed.daemon.BuildConfig;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -105,6 +115,9 @@ public class ServiceManager {
logcatService = new LogcatService();
logcatService.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
permissionManagerWorkaround();
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
Looper.prepareMainLooper();
@ -208,4 +221,56 @@ public class ServiceManager {
public static boolean existsInGlobalNamespace(String path) {
return toGlobalNamespace(path).exists();
}
private static void permissionManagerWorkaround() {
try {
Field sCacheField = android.os.ServiceManager.class.getDeclaredField("sCache");
sCacheField.setAccessible(true);
var sCache = (Map) sCacheField.get(null);
sCache.put("permissionmgr", new BinderProxy("permissionmgr"));
sCache.put("legacy_permission", new BinderProxy("legacy_permission"));
sCache.put("appops", new BinderProxy("appops"));
} catch (Throwable e) {
Log.e(TAG, "failed to init permission manager", e);
}
}
private static class BinderProxy extends Binder {
private static final Method rawGetService;
static {
try {
rawGetService = android.os.ServiceManager.class.getDeclaredMethod("rawGetService", String.class);
rawGetService.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
private IBinder mReal = null;
private final String mName;
BinderProxy(String name) {
mName = name;
}
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
synchronized (this) {
if (mReal == null) {
try {
mReal = (IBinder) rawGetService.invoke(null, mName);
} catch (IllegalAccessException | InvocationTargetException ignored){
}
}
if (mReal != null) {
return mReal.transact(code, data, reply, flags);
}
}
// getSplitPermissions
if (reply != null && mName.equals("permissionmgr"))
reply.writeTypedList(List.of());
return true;
}
}
}