Add UID scanner functionality and related infrastructure
- Introduced a new module `uid_scanner` in userspace for managing UID scanning. - Created a new GitHub Actions workflow for building the `user_scanner`. - Implemented kernel communication in `throne_comm.c` and `throne_comm.h` to handle user space updates and rescan requests. - Developed the `uid_scanner` daemon in C to scan user directories and manage UID whitelists. - Added configuration management for the UID scanner with support for multiple users and auto-scanning. - Implemented logging and error handling throughout the UID scanning process. - Created necessary build files for the `user_scanner` JNI integration. - Added a `.gitignore` file to exclude build artifacts.
This commit is contained in:
@@ -31,6 +31,8 @@ object Natives {
|
||||
|
||||
const val MINIMAL_SUPPORTED_DYNAMIC_MANAGER = 13215
|
||||
|
||||
const val MINIMAL_SUPPORTED_UID_SCANNER = 13347
|
||||
|
||||
const val ROOT_UID = 0
|
||||
const val ROOT_GID = 0
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ import com.sukisu.ultra.ui.theme.getCardColors
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
import com.sukisu.ultra.ui.util.LocalSnackbarHost
|
||||
import com.sukisu.ultra.ui.util.getBugreportFile
|
||||
import com.sukisu.ultra.ui.util.setUidAutoScan
|
||||
import com.sukisu.ultra.ui.util.setUidMultiUserScan
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -127,7 +129,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
navigator.navigate(AppProfileTemplateScreenDestination)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// 卸载模块开关
|
||||
var umountChecked by rememberSaveable {
|
||||
mutableStateOf(Natives.isDefaultUmountModules())
|
||||
@@ -177,6 +179,80 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
forceSignatureVerification = enabled
|
||||
}
|
||||
)
|
||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_UID_SCANNER) {
|
||||
var uidAutoScanEnabled by rememberSaveable {
|
||||
mutableStateOf(prefs.getBoolean("uid_auto_scan", false))
|
||||
}
|
||||
|
||||
var uidMultiUserScanEnabled by rememberSaveable {
|
||||
mutableStateOf(prefs.getBoolean("uid_multi_user_scan", false))
|
||||
}
|
||||
// 用户态扫描应用列表开关
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Scanner,
|
||||
title = stringResource(R.string.uid_auto_scan_title),
|
||||
summary = stringResource(R.string.uid_auto_scan_summary),
|
||||
checked = uidAutoScanEnabled,
|
||||
onCheckedChange = { enabled ->
|
||||
scope.launch {
|
||||
try {
|
||||
if (setUidAutoScan(enabled)) {
|
||||
uidAutoScanEnabled = enabled
|
||||
prefs.edit { putBoolean("uid_auto_scan", enabled) }
|
||||
|
||||
// 如果关闭了用户态扫描,则同时关闭多用户扫描
|
||||
if (!enabled) {
|
||||
uidMultiUserScanEnabled = false
|
||||
prefs.edit { putBoolean("uid_multi_user_scan", false) }
|
||||
}
|
||||
} else {
|
||||
snackBarHost.showSnackbar(context.getString(R.string.uid_scanner_setting_failed))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(
|
||||
R.string.uid_scanner_setting_error,
|
||||
e.message ?: ""
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 多用户应用扫描开关 - 仅在启用用户态扫描时显示
|
||||
AnimatedVisibility(
|
||||
visible = uidAutoScanEnabled,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Groups,
|
||||
title = stringResource(R.string.uid_multi_user_scan_title),
|
||||
summary = stringResource(R.string.uid_multi_user_scan_summary),
|
||||
checked = uidMultiUserScanEnabled,
|
||||
onCheckedChange = { enabled ->
|
||||
scope.launch {
|
||||
try {
|
||||
if (setUidMultiUserScan(enabled)) {
|
||||
uidMultiUserScanEnabled = enabled
|
||||
prefs.edit { putBoolean("uid_multi_user_scan", enabled) }
|
||||
} else {
|
||||
snackBarHost.showSnackbar(context.getString(R.string.uid_scanner_setting_failed))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(
|
||||
R.string.uid_scanner_setting_error,
|
||||
e.message ?: ""
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -807,4 +883,4 @@ private fun TopBar(
|
||||
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -569,3 +569,47 @@ fun getZygiskImplement(): String {
|
||||
Log.i(TAG, "Zygisk implement: $result")
|
||||
return result
|
||||
}
|
||||
|
||||
fun getUidScannerDaemonPath(): String {
|
||||
return ksuApp.applicationInfo.nativeLibraryDir + File.separator + "libuid_scanner.so"
|
||||
}
|
||||
|
||||
fun ensureUidScannerExecutable(): Boolean {
|
||||
val shell = getRootShell()
|
||||
val uidScannerPath = getUidScannerDaemonPath()
|
||||
val targetPath = "/data/adb/uid_scanner"
|
||||
|
||||
if (!ShellUtils.fastCmdResult(shell, "test -f $targetPath")) {
|
||||
val copyResult = ShellUtils.fastCmdResult(shell, "cp $uidScannerPath $targetPath")
|
||||
if (!copyResult) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
val result = ShellUtils.fastCmdResult(shell, "chmod 755 $targetPath")
|
||||
return result
|
||||
}
|
||||
|
||||
fun setUidAutoScan(enabled: Boolean): Boolean {
|
||||
val shell = getRootShell()
|
||||
if (!ensureUidScannerExecutable()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val enableValue = if (enabled) 1 else 0
|
||||
val cmd = "${getUidScannerDaemonPath()} --auto-scan $enableValue && ${getUidScannerDaemonPath()} reload"
|
||||
val result = ShellUtils.fastCmdResult(shell, cmd)
|
||||
return result
|
||||
}
|
||||
|
||||
fun setUidMultiUserScan(enabled: Boolean): Boolean {
|
||||
val shell = getRootShell()
|
||||
if (!ensureUidScannerExecutable()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val enableValue = if (enabled) 1 else 0
|
||||
val cmd = "${getUidScannerDaemonPath()} --multi-user $enableValue && ${getUidScannerDaemonPath()} reload"
|
||||
val result = ShellUtils.fastCmdResult(shell, cmd)
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user