diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt index d61a6bf8..237afefe 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt @@ -406,7 +406,7 @@ private fun InfoCard() { if (suSFS != "Unsupported") { InfoCardItem( label = stringResource(R.string.home_susfs_version), - content = "${getSuSFSVersion()} (${getSuSFSVariant()})", + content = "${getSuSFSVersion()} (${getSuSFSVariant()}) [+] sus_su mode: ${susfsSUSSU_Mode()}", icon = Icons.Filled.SettingsSuggest, ) } diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt index 6b0ebd7c..ee2b21da 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt @@ -19,17 +19,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Undo -import androidx.compose.material.icons.filled.BugReport -import androidx.compose.material.icons.filled.Compress -import androidx.compose.material.icons.filled.ContactPage -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.DeleteForever -import androidx.compose.material.icons.filled.DeveloperMode -import androidx.compose.material.icons.filled.Fence -import androidx.compose.material.icons.filled.RemoveModerator -import androidx.compose.material.icons.filled.Save -import androidx.compose.material.icons.filled.Share -import androidx.compose.material.icons.filled.Update +import androidx.compose.material.icons.filled.* import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -87,6 +77,7 @@ import com.rifsxd.ksunext.ui.component.rememberCustomDialog import com.rifsxd.ksunext.ui.component.rememberLoadingDialog import com.rifsxd.ksunext.ui.util.LocalSnackbarHost import com.rifsxd.ksunext.ui.util.getBugreportFile +import com.rifsxd.ksunext.ui.util.* import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -196,6 +187,26 @@ fun SettingScreen(navigator: DestinationsNavigator) { enableWebDebugging = it } + val suSFSVar = getSuSFSVariant() + if (suSFSVar != "NON-GKI") { + var isEnabled by rememberSaveable { + mutableStateOf(susfsSUSSU_Mode() == "2") + } + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(id = R.string.settings_susfs_toggle), + summary = stringResource(id = R.string.settings_susfs_toggle_summary), + checked = isEnabled + ) { + if (it) { + susfsSUSSU_1() + } else { + susfsSUSSU_0() + } + isEnabled = it + } + } + var showBottomsheet by remember { mutableStateOf(false) } ListItem( diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt index 8e2b706e..7bc4d90c 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt @@ -142,6 +142,24 @@ fun getSuSFSVariant(): String { return result } +fun susfsSUSSU_0(): String { + val shell = getRootShell() + val result = ShellUtils.fastCmd(shell, "${getSuSFSPath()} sus_su 0") + return result +} + +fun susfsSUSSU_1(): String { + val shell = getRootShell() + val result = ShellUtils.fastCmd(shell, "${getSuSFSPath()} sus_su 2") + return result +} + +fun susfsSUSSU_Mode(): String { + val shell = getRootShell() + val result = ShellUtils.fastCmd(shell, "${getSuSFSPath()} sus_su show_working_mode") + return result +} + fun getSuperuserCount(): Int { return Natives.allowList.size } @@ -426,7 +444,7 @@ fun getAppProfileTemplate(id: String): String { fun setAppProfileTemplate(id: String, template: String): Boolean { val shell = getRootShell() val escapedTemplate = template.replace("\"", "\\\"") - val cmd = """${getKsuDaemonPath()} profile set-template "$id" "$escapedTemplate'"""" + val cmd = """${getKsuDaemonPath()} profile set-template "$id" "$escapedTemplate'""" return shell.newJob().add(cmd) .to(ArrayList(), null).exec().isSuccess } diff --git a/manager/app/src/main/jniLibs/arm64-v8a/libsusfs.so b/manager/app/src/main/jniLibs/arm64-v8a/libsusfs.so index 77077b87..77167075 100755 Binary files a/manager/app/src/main/jniLibs/arm64-v8a/libsusfs.so and b/manager/app/src/main/jniLibs/arm64-v8a/libsusfs.so differ diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index a65d4336..72b9a863 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -89,6 +89,8 @@ The current KernelSU-Next version %d is too low for the manager to work properly. Please upgrade to version %d or higher! Umount modules by default The global default value for \"Umount modules\" in App Profile. If enabled, it will remove all module modifications to the system for apps that don\'t have a profile set. + Hide suspecious su with SuSFS + It disables kprobe hooks made by ksu, and instead the non-kprobe inline hooks will be enabled, just the same implementation for non-gki kernel without kprobe supported. Enabling this option will allow KernelSU-Next to restore any modified files by the modules for this app. Domain Rules diff --git a/userspace/susfs/jni/susfs.c b/userspace/susfs/jni/susfs.c index 6c8d596d..13276611 100644 --- a/userspace/susfs/jni/susfs.c +++ b/userspace/susfs/jni/susfs.c @@ -1,14 +1,57 @@ #include -#include #include +#include #include +#include #define KERNEL_SU_OPTION 0xDEADBEEF + #define CMD_SUSFS_SHOW_VERSION 0x555e1 +#define CMD_SUSFS_SHOW_ENABLED_FEATURES 0x555e2 #define CMD_SUSFS_SHOW_VARIANT 0x555e3 +#define CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE 0x555e4 +#define CMD_SUSFS_IS_SUS_SU_READY 0x555f0 +#define CMD_SUSFS_SUS_SU 0x60000 + +#define SUS_SU_DISABLED 0 +#define SUS_SU_WITH_HOOKS 2 + +struct st_sus_su { + int mode; +}; + +int enable_sus_su(int last_working_mode, int target_working_mode) { + struct st_sus_su info; + int error = -1; + + if (target_working_mode == SUS_SU_WITH_HOOKS) { + info.mode = SUS_SU_WITH_HOOKS; + prctl(KERNEL_SU_OPTION, CMD_SUSFS_SUS_SU, &info, NULL, &error); + if (error) { + if (error == 1) { + } else if (error == 2) { + } + return error; + } + printf("[+] sus_su mode 2 is enabled\n"); + } else if (target_working_mode == SUS_SU_DISABLED) { + info.mode = SUS_SU_DISABLED; + prctl(KERNEL_SU_OPTION, CMD_SUSFS_SUS_SU, &info, NULL, &error); + if (error) { + if (error == 1) { + } + return error; + } + printf("[+] sus_su mode 0 is enabled\n"); + } else { + return 1; + } + return 0; +} int main(int argc, char *argv[]) { int error = -1; + char support[16]; char version[16]; char variant[16]; @@ -20,9 +63,9 @@ int main(int argc, char *argv[]) { // If 'version' is given, show version if (strcmp(argv[1], "support") == 0) { - prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_VERSION, version, NULL, &error); + prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_VERSION, support, NULL, &error); if (!error) { - if (version[0] == 'v') { + if (support[0] == 'v') { printf("Supported\n"); } } else { @@ -43,6 +86,48 @@ int main(int argc, char *argv[]) { } else { printf("Invalid\n"); } + } else if (argc == 3 && !strcmp(argv[1], "sus_su")) { + int last_working_mode = 0; + int target_working_mode; + char* endptr; + + prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error); + if (error) + return error; + if (!strcmp(argv[2], "show_working_mode")) { + printf("%d\n", last_working_mode); + return 0; + } + target_working_mode = strtol(argv[2], &endptr, 10); + if (*endptr != '\0') { + return 1; + } + if (target_working_mode == SUS_SU_WITH_HOOKS) { + bool is_sus_su_ready; + prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error); + if (error) + return error; + if (!is_sus_su_ready) { + printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS); + return 1; + } + if (last_working_mode == SUS_SU_DISABLED) { + error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS); + } else if (last_working_mode == SUS_SU_WITH_HOOKS) { + printf("[-] sus_su is already in mode %d\n", last_working_mode); + return 1; + } else { + error = enable_sus_su(last_working_mode, SUS_SU_DISABLED); + if (!error) + error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS); + } + } else if (target_working_mode == SUS_SU_DISABLED) { + if (last_working_mode == SUS_SU_DISABLED) { + printf("[-] sus_su is already in mode %d\n", last_working_mode); + return 1; + } + error = enable_sus_su(last_working_mode, SUS_SU_DISABLED); + } } else { fprintf(stderr, "Invalid argument: %s\n", argv[1]); return 1;