[core] Move signature verification to lspd (#822)
This commit is contained in:
parent
588bb062cb
commit
a9c0409cd9
|
|
@ -1,15 +1,15 @@
|
||||||
package org.lsposed.lspd.service;
|
package org.lsposed.lspd.service;
|
||||||
|
|
||||||
interface ILSPApplicationService {
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ abstract public class ApplicationServiceClient implements ILSPApplicationService
|
||||||
abstract public IBinder requestModuleBinder();
|
abstract public IBinder requestModuleBinder();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
abstract public IBinder requestManagerBinder(String packageName);
|
abstract public boolean requestManagerBinder(String packageName, String path, IBinder[] binder);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
abstract public boolean isResourcesHookEnabled();
|
abstract public boolean isResourcesHookEnabled();
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,12 @@ public class LSPApplicationServiceClient extends ApplicationServiceClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder requestManagerBinder(String packageName) {
|
public boolean requestManagerBinder(String packageName, String path, IBinder[] binder) {
|
||||||
try {
|
try {
|
||||||
return service.requestManagerBinder(packageName);
|
return service.requestManagerBinder(packageName, path, binder);
|
||||||
} catch (RemoteException | NullPointerException ignored) {
|
} catch (RemoteException | NullPointerException ignored) {
|
||||||
}
|
}
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,18 @@ public class LoadedApkGetCLHooker extends XC_MethodHook {
|
||||||
hookNewXSP(lpparam);
|
hookNewXSP(lpparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
IBinder binder = loadedApk.getApplicationInfo() != null ? serviceClient.requestManagerBinder(loadedApk.getApplicationInfo().packageName) : null;
|
var binder = new IBinder[1];
|
||||||
if (binder != null) {
|
var blocked = false;
|
||||||
if (InstallerVerifier.verifyInstallerSignature(loadedApk.getApplicationInfo())) {
|
var info = loadedApk.getApplicationInfo();
|
||||||
InstallerVerifier.hookXposedInstaller(lpparam.classLoader, binder);
|
if (info != null) {
|
||||||
} else {
|
var packageName = info.packageName;
|
||||||
InstallerVerifier.hookXposedInstaller(classLoader);
|
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 {
|
} else {
|
||||||
XC_LoadPackage.callAll(lpparam);
|
XC_LoadPackage.callAll(lpparam);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,14 +77,14 @@ public class ConfigManager {
|
||||||
"android.permission.WRITE_SECURE_SETTINGS"
|
"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 basePath = new File("/data/adb/lspd");
|
||||||
private static final File configPath = new File(basePath, "config");
|
private static final File configPath = new File(basePath, "config");
|
||||||
private static final File lockPath = new File(basePath, "lock");
|
private static final File lockPath = new File(basePath, "lock");
|
||||||
private static final SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(new File(configPath, "modules_config.db"), null);
|
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 static final File resourceHookSwitch = new File(configPath, "enable_resources");
|
||||||
private boolean resourceHook = false;
|
private boolean resourceHook = false;
|
||||||
|
|
@ -734,6 +734,11 @@ public class ConfigManager {
|
||||||
return uid == managerUid;
|
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) {
|
public String getPrefsPath(String fileName, int uid) {
|
||||||
int userId = uid / PER_USER_RANGE;
|
int userId = uid / PER_USER_RANGE;
|
||||||
return miscPath + File.separator + "prefs" + (userId == 0 ? "" : String.valueOf(userId)) + File.separator + fileName;
|
return miscPath + File.separator + "prefs" + (userId == 0 ? "" : String.valueOf(userId)) + File.separator + fileName;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.lsposed.lspd.util.InstallerVerifier;
|
||||||
import org.lsposed.lspd.util.Utils;
|
import org.lsposed.lspd.util.Utils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -101,16 +102,19 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder requestManagerBinder(String packageName) throws RemoteException {
|
public boolean requestManagerBinder(String packageName, String path, IBinder[] binder) throws RemoteException {
|
||||||
ensureRegistered();
|
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();
|
var service = ServiceManager.getManagerService();
|
||||||
if (Utils.isMIUI) {
|
if (Utils.isMIUI) {
|
||||||
service.new ManagerGuard(handles.get(getCallingPid()));
|
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) {
|
public boolean hasRegister(int uid, int pid) {
|
||||||
|
|
|
||||||
|
|
@ -279,11 +279,8 @@ public class PackageService {
|
||||||
// Uninstall manager when needed
|
// Uninstall manager when needed
|
||||||
PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0, 0);
|
PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0, 0);
|
||||||
if (pkgInfo != null && pkgInfo.versionName != null && pkgInfo.applicationInfo != null) {
|
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 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)
|
if (versionMatch && signatureMatch && pkgInfo.versionCode >= BuildConfig.VERSION_CODE)
|
||||||
return false;
|
return false;
|
||||||
if (!signatureMatch || !versionMatch && pkgInfo.versionCode > BuildConfig.VERSION_CODE)
|
if (!signatureMatch || !versionMatch && pkgInfo.versionCode > BuildConfig.VERSION_CODE)
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ import de.robv.android.xposed.XC_MethodHook;
|
||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
|
||||||
public class InstallerVerifier {
|
public class InstallerVerifier {
|
||||||
public static boolean verifyInstallerSignature(ApplicationInfo appInfo) {
|
public static boolean verifyInstallerSignature(String path) {
|
||||||
ApkVerifier verifier = new ApkVerifier.Builder(new File(appInfo.sourceDir))
|
ApkVerifier verifier = new ApkVerifier.Builder(new File(path))
|
||||||
.setMinCheckedPlatformVersion(27)
|
.setMinCheckedPlatformVersion(27)
|
||||||
.build();
|
.build();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue