diff --git a/manager/app/src/main/assets/ksu_susfs_1.5.9 b/manager/app/src/main/assets/ksu_susfs_1.5.9 index 1a2ad5ad..d72c0a9a 100644 Binary files a/manager/app/src/main/assets/ksu_susfs_1.5.9 and b/manager/app/src/main/assets/ksu_susfs_1.5.9 differ diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt index 587e2dc7..68419044 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt @@ -136,6 +136,7 @@ fun SuSFSConfigScreen( var executeInPostFsData by remember { mutableStateOf(false) } var enableHideBl by remember { mutableStateOf(true) } var enableCleanupResidue by remember { mutableStateOf(false) } + var enableAvcLogSpoofing by remember { mutableStateOf(false) } // 槽位信息相关状态 var slotInfoList by remember { mutableStateOf(emptyList()) } @@ -311,6 +312,7 @@ fun SuSFSConfigScreen( enableHideBl = SuSFSManager.getEnableHideBl(context) enableCleanupResidue = SuSFSManager.getEnableCleanupResidue(context) umountForZygoteIsoService = SuSFSManager.getUmountForZygoteIsoService(context) + enableAvcLogSpoofing = SuSFSManager.getEnableAvcLogSpoofing(context) loadSlotInfo() } @@ -481,6 +483,7 @@ fun SuSFSConfigScreen( enableHideBl = SuSFSManager.getEnableHideBl(context) enableCleanupResidue = SuSFSManager.getEnableCleanupResidue(context) umountForZygoteIsoService = SuSFSManager.getUmountForZygoteIsoService(context) + enableAvcLogSpoofing = SuSFSManager.getEnableAvcLogSpoofing(context) } isLoading = false showRestoreConfirmDialog = false @@ -946,6 +949,7 @@ fun SuSFSConfigScreen( SuSFSManager.saveExecuteInPostFsData(context, executeInPostFsData) SuSFSManager.saveEnableHideBl(context, enableHideBl) SuSFSManager.saveEnableCleanupResidue(context, enableCleanupResidue) + SuSFSManager.saveEnableAvcLogSpoofing(context, enableAvcLogSpoofing) } isLoading = false } @@ -1237,6 +1241,17 @@ fun SuSFSConfigScreen( SuSFSManager.configureAutoStart(context, true) } } + }, + enableAvcLogSpoofing = enableAvcLogSpoofing, + onEnableAvcLogSpoofingChange = { enabled -> + coroutineScope.launch { + isLoading = true + val success = SuSFSManager.setEnableAvcLogSpoofing(context, enabled) + if (success) { + enableAvcLogSpoofing = enabled + } + isLoading = false + } } ) } @@ -1456,10 +1471,13 @@ private fun BasicSettingsContent( enableHideBl: Boolean, onEnableHideBlChange: (Boolean) -> Unit, enableCleanupResidue: Boolean, - onEnableCleanupResidueChange: (Boolean) -> Unit + onEnableCleanupResidueChange: (Boolean) -> Unit, + enableAvcLogSpoofing: Boolean, + onEnableAvcLogSpoofingChange: (Boolean) -> Unit ) { var scriptLocationExpanded by remember { mutableStateOf(false) } val isAbDevice = isAbDevice() + val isSusVersion159 = isSusVersion159() Column( modifier = Modifier @@ -1769,6 +1787,66 @@ private fun BasicSettingsContent( } } + // AVC日志欺骗开关(仅在1.5.9+版本显示) + if (isSusVersion159) { + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surface + ), + shape = RoundedCornerShape(12.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier.weight(1f) + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = Icons.Default.VisibilityOff, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(18.dp) + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = stringResource(R.string.avc_log_spoofing), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.onSurface + ) + } + Spacer(modifier = Modifier.height(6.dp)) + Text( + text = stringResource(R.string.avc_log_spoofing_description), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + lineHeight = 14.sp + ) + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = stringResource(R.string.avc_log_spoofing_warning), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.secondary, + lineHeight = 12.sp + ) + } + Switch( + checked = enableAvcLogSpoofing, + onCheckedChange = onEnableAvcLogSpoofingChange, + enabled = !isLoading + ) + } + } + } + // 槽位信息按钮 if (isAbDevice) { Card( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt index 5eca099c..1dbd267d 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt @@ -49,6 +49,7 @@ object SuSFSManager { private const val KEY_ENABLE_CLEANUP_RESIDUE = "enable_cleanup_residue" private const val KEY_ENABLE_HIDE_BL = "enable_hide_bl" private const val KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE = "umount_for_zygote_iso_service" + private const val KEY_ENABLE_AVC_LOG_SPOOFING = "enable_avc_log_spoofing" // 常量 @@ -156,7 +157,8 @@ object SuSFSManager { val support158: Boolean, val enableHideBl: Boolean, val enableCleanupResidue: Boolean, - val umountForZygoteIsoService: Boolean + val umountForZygoteIsoService: Boolean, + val enableAvcLogSpoofing: Boolean ) { /** * 检查是否有需要自启动的配置 @@ -232,7 +234,7 @@ object SuSFSManager { } /** - * 检查是否支持循环路径功能(1.5.9+) + * 检查是否支持循环路径和AVC日志欺骗等功能(1.5.9+) */ fun isSusVersion159(): Boolean { return try { @@ -266,6 +268,7 @@ object SuSFSManager { enableHideBl = getEnableHideBl(context), enableCleanupResidue = getEnableCleanupResidue(context), umountForZygoteIsoService = getUmountForZygoteIsoService(context), + enableAvcLogSpoofing = getEnableAvcLogSpoofing(context) ) } @@ -335,6 +338,13 @@ object SuSFSManager { fun getUmountForZygoteIsoService(context: Context): Boolean = getPrefs(context).getBoolean(KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE, false) + // AVC日志欺骗配置 + fun saveEnableAvcLogSpoofing(context: Context, enabled: Boolean) = + getPrefs(context).edit { putBoolean(KEY_ENABLE_AVC_LOG_SPOOFING, enabled) } + + fun getEnableAvcLogSpoofing(context: Context): Boolean = + getPrefs(context).getBoolean(KEY_ENABLE_AVC_LOG_SPOOFING, false) + // 路径和配置管理 fun saveSusPaths(context: Context, paths: Set) = @@ -502,6 +512,7 @@ object SuSFSManager { KEY_ENABLE_HIDE_BL to getEnableHideBl(context), KEY_ENABLE_CLEANUP_RESIDUE to getEnableCleanupResidue(context), KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE to getUmountForZygoteIsoService(context), + KEY_ENABLE_AVC_LOG_SPOOFING to getEnableAvcLogSpoofing(context), ) } @@ -858,6 +869,25 @@ object SuSFSManager { return success } + // AVC日志欺骗开关 + suspend fun setEnableAvcLogSpoofing(context: Context, enabled: Boolean): Boolean { + if (!isSusVersion159()) { + return false + } + + val success = executeSusfsCommand(context, "enable_avc_log_spoofing ${if (enabled) 1 else 0}") + if (success) { + saveEnableAvcLogSpoofing(context, enabled) + if (isAutoStartEnabled(context)) updateMagiskModule(context) + showToast(context, if (enabled) + context.getString(R.string.avc_log_spoofing_enabled) + else + context.getString(R.string.avc_log_spoofing_disabled) + ) + } + return success + } + // SUS挂载隐藏控制 suspend fun setHideSusMountsForAllProcs(context: Context, hideForAll: Boolean): Boolean { if (!isSusVersion158()) { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt index 5d511084..1cf9cf82 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt @@ -117,6 +117,14 @@ object ScriptGenerator { appendLine() } + private fun StringBuilder.generateAvcLogSpoofingSection(enableAvcLogSpoofing: Boolean) { + appendLine("# 设置AVC日志欺骗状态") + val avcLogValue = if (enableAvcLogSpoofing) 1 else 0 + appendLine("\"${'$'}SUSFS_BIN\" enable_avc_log_spoofing $avcLogValue") + appendLine("echo \"$(get_current_time): AVC日志欺骗功能设置为: ${if (enableAvcLogSpoofing) "启用" else "禁用"}\" >> \"${'$'}LOG_FILE\"") + appendLine() + } + private fun StringBuilder.generateSusPathsSection(susPaths: Set) { if (susPaths.isNotEmpty()) { appendLine("# 添加SUS路径") @@ -386,6 +394,9 @@ object ScriptGenerator { generateUmountZygoteIsoServiceSection(config.umountForZygoteIsoService, config.support158) + // 添加AVC日志欺骗设置 + generateAvcLogSpoofingSection(config.enableAvcLogSpoofing) + appendLine("echo \"$(get_current_time): Post-FS-Data脚本执行完成\" >> \"${'$'}LOG_FILE\"") } } diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index b711ac43..82780348 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -606,6 +606,18 @@ SUS循环路径 循环路径配置 循环路径会在每次非root用户应用或隔离服务启动时重新标记为SUS_PATH。这有助于解决添加的路径可能因inode状态重置或内核中inode重新创建而失效的问题 + AVC 日志欺骗 + AVC 日志欺骗已启用 + AVC 日志欺骗已禁用 + +禁用: 禁用在内核 AVC 日志中欺骗 \'su\' 的 sus tcontext。\n +启用: 启用在内核 AVC 日志中将 \'su\' 的 sus tcontext 欺骗为 \'kernel\' + + +重要提示:\n +- 内核中默认设置为 \'0\'\n +- 启用此功能有时会使开发人员在调试权限或 SELinux 问题时难以识别原因,因此建议用户在调试时禁用此功能。 + 已验证 模块签名已验证 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index bdcf051e..84dd9fdb 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -609,6 +609,18 @@ SUS Loop Path Loop Path Configuration Loop paths are re-flagged as SUS_PATH on each non-root user app or isolated service startup. This helps address issues where added paths may have their inode status reset or inode re-created in the kernel. + AVC Log Spoofing + AVC log spoofing has been enabled + AVC log spoofing has been disabled + +disabled : Disable spoofing the sus tcontext of \'su\' shown in avc log in kernel.\n +enabled : Enable spoofing the sus tcontext of \'su\' with \'kernel\' shown in avc log in kernel + + +Important Note:\n +- It is set to \'0\' by default in kernel\n +- Enabling this will sometimes make developers hard to identify the cause when they are debugging with some permission or SELinux issue, so users are advised to disable this when doing so. + Validated Module signature verified