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;