New permission manager workaround (#2598)
This commit is contained in:
parent
6f6c4b67d7
commit
df4ce63f41
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue