[core] Move signature verification to lspd (#822)

This commit is contained in:
vvb2060 2021-07-19 03:34:36 +08:00 committed by GitHub
parent 588bb062cb
commit a9c0409cd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 29 deletions

View File

@ -1,15 +1,15 @@
package org.lsposed.lspd.service;
interface ILSPApplicationService {
IBinder requestModuleBinder() = 2;
IBinder requestModuleBinder();
IBinder requestManagerBinder(String packageName) = 3;
boolean requestManagerBinder(String packageName, String path, out IBinder[] binder);
boolean isResourcesHookEnabled() = 5;
boolean isResourcesHookEnabled();
Map getModulesList(String processName) = 6;
Map getModulesList(String processName);
String getPrefsPath(String packageName) = 7;
String getPrefsPath(String packageName);
ParcelFileDescriptor getModuleLogger() = 9;
ParcelFileDescriptor getModuleLogger();
}

View File

@ -15,7 +15,7 @@ abstract public class ApplicationServiceClient implements ILSPApplicationService
abstract public IBinder requestModuleBinder();
@Override
abstract public IBinder requestManagerBinder(String packageName);
abstract public boolean requestManagerBinder(String packageName, String path, IBinder[] binder);
@Override
abstract public boolean isResourcesHookEnabled();

View File

@ -68,12 +68,12 @@ public class LSPApplicationServiceClient extends ApplicationServiceClient {
}
@Override
public IBinder requestManagerBinder(String packageName) {
public boolean requestManagerBinder(String packageName, String path, IBinder[] binder) {
try {
return service.requestManagerBinder(packageName);
return service.requestManagerBinder(packageName, path, binder);
} catch (RemoteException | NullPointerException ignored) {
}
return null;
return false;
}
@Override

View File

@ -90,13 +90,18 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
hookNewXSP(lpparam);
}
IBinder binder = loadedApk.getApplicationInfo() != null ? serviceClient.requestManagerBinder(loadedApk.getApplicationInfo().packageName) : null;
if (binder != null) {
if (InstallerVerifier.verifyInstallerSignature(loadedApk.getApplicationInfo())) {
InstallerVerifier.hookXposedInstaller(lpparam.classLoader, binder);
} else {
InstallerVerifier.hookXposedInstaller(classLoader);
}
var binder = new IBinder[1];
var blocked = false;
var info = loadedApk.getApplicationInfo();
if (info != null) {
var packageName = info.packageName;
var path = info.sourceDir;
blocked = serviceClient.requestManagerBinder(packageName, path, binder);
}
if (binder[0] != null) {
InstallerVerifier.hookXposedInstaller(lpparam.classLoader, binder[0]);
} else if (blocked) {
InstallerVerifier.hookXposedInstaller(classLoader);
} else {
XC_LoadPackage.callAll(lpparam);
}

View File

@ -77,14 +77,14 @@ public class ConfigManager {
"android.permission.WRITE_SECURE_SETTINGS"
};
static ConfigManager instance = null;
private static ConfigManager instance = null;
private static final File basePath = new File("/data/adb/lspd");
private static final File configPath = new File(basePath, "config");
private static final File lockPath = new File(basePath, "lock");
private static final SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(new File(configPath, "modules_config.db"), null);
boolean packageStarted = false;
private boolean packageStarted = false;
private static final File resourceHookSwitch = new File(configPath, "enable_resources");
private boolean resourceHook = false;
@ -734,6 +734,11 @@ public class ConfigManager {
return uid == managerUid;
}
public boolean shouldBlock(String packageName) {
return packageName.equals("io.github.lsposed.manager") ||
packageName.equals(BuildConfig.DEFAULT_MANAGER_PACKAGE_NAME);
}
public String getPrefsPath(String fileName, int uid) {
int userId = uid / PER_USER_RANGE;
return miscPath + File.separator + "prefs" + (userId == 0 ? "" : String.valueOf(userId)) + File.separator + fileName;

View File

@ -27,6 +27,7 @@ import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import org.lsposed.lspd.util.InstallerVerifier;
import org.lsposed.lspd.util.Utils;
import java.util.Map;
@ -101,16 +102,19 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
}
@Override
public IBinder requestManagerBinder(String packageName) throws RemoteException {
public boolean requestManagerBinder(String packageName, String path, IBinder[] binder) throws RemoteException {
ensureRegistered();
if (ConfigManager.getInstance().isManager(getCallingUid()) && ConfigManager.getInstance().isManager(packageName)) {
if (ConfigManager.getInstance().isManager(getCallingUid()) &&
ConfigManager.getInstance().isManager(packageName) &&
InstallerVerifier.verifyInstallerSignature(path)) {
var service = ServiceManager.getManagerService();
if (Utils.isMIUI) {
service.new ManagerGuard(handles.get(getCallingPid()));
}
return service;
binder[0] = service;
return false;
}
return null;
return ConfigManager.getInstance().shouldBlock(packageName);
}
public boolean hasRegister(int uid, int pid) {

View File

@ -279,11 +279,8 @@ public class PackageService {
// Uninstall manager when needed
PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0, 0);
if (pkgInfo != null && pkgInfo.versionName != null && pkgInfo.applicationInfo != null) {
if ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0) {
return false;
}
boolean versionMatch = pkgInfo.versionName.equals(BuildConfig.VERSION_NAME);
boolean signatureMatch = InstallerVerifier.verifyInstallerSignature(pkgInfo.applicationInfo);
boolean signatureMatch = InstallerVerifier.verifyInstallerSignature(pkgInfo.applicationInfo.sourceDir);
if (versionMatch && signatureMatch && pkgInfo.versionCode >= BuildConfig.VERSION_CODE)
return false;
if (!signatureMatch || !versionMatch && pkgInfo.versionCode > BuildConfig.VERSION_CODE)

View File

@ -38,8 +38,8 @@ import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
public class InstallerVerifier {
public static boolean verifyInstallerSignature(ApplicationInfo appInfo) {
ApkVerifier verifier = new ApkVerifier.Builder(new File(appInfo.sourceDir))
public static boolean verifyInstallerSignature(String path) {
ApkVerifier verifier = new ApkVerifier.Builder(new File(path))
.setMinCheckedPlatformVersion(27)
.build();
try {