diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 86b73f52..96605e01 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -425,6 +425,18 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } #endif + if (arg2 == CMD_ENABLE_KPM) { + #ifdef CONFIG_KPM + bool KPM_Enabled = true; + #else + bool KPM_Enabled = false; + #endif + if (copy_to_user((void __user *)arg3, &KPM_Enabled, sizeof(KPM_Enabled))) { + pr_info("KPM: copy_to_user() failed\n"); + } + return 0; + } + // all other cmds are for 'root manager' if (!from_manager) { return 0; diff --git a/kernel/ksu.h b/kernel/ksu.h index e5050024..8643c921 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -23,6 +23,7 @@ #define CMD_UID_SHOULD_UMOUNT 13 #define CMD_IS_SU_ENABLED 14 #define CMD_ENABLE_SU 15 +#define CMD_ENABLE_KPM 100 #define EVENT_POST_FS_DATA 1 #define EVENT_BOOT_COMPLETED 2 diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index 05463b35..846031c0 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -305,4 +305,10 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_sukisu_ultra_Natives_setSuEnabled(JNIEnv *env, jobject thiz, jboolean enabled) { return set_su_enabled(enabled); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_com_sukisu_ultra_Natives_isKPMEnabled(JNIEnv *env, jclass clazz) { + return (jboolean)is_KPM_enable(); } \ No newline at end of file diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc index 720c5fd0..78680c4f 100644 --- a/manager/app/src/main/cpp/ksu.cc +++ b/manager/app/src/main/cpp/ksu.cc @@ -29,6 +29,7 @@ #define CMD_IS_UID_SHOULD_UMOUNT 13 #define CMD_IS_SU_ENABLED 14 #define CMD_ENABLE_SU 15 +#define CMD_ENABLE_KPM 100 static bool ksuctl(int cmd, void* arg1, void* arg2) { int32_t result = 0; @@ -96,4 +97,10 @@ bool is_su_enabled() { // if ksuctl failed, we assume su is enabled, and it cannot be disabled. ksuctl(CMD_IS_SU_ENABLED, &enabled, nullptr); return enabled; +} + +bool is_KPM_enable() { + bool enabled = false; + ksuctl(CMD_ENABLE_KPM, &enabled, nullptr); + return enabled; } \ No newline at end of file diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 3854356a..7514a0a6 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -83,4 +83,6 @@ bool set_su_enabled(bool enabled); bool is_su_enabled(); +bool is_KPM_enable(); + #endif //KERNELSU_KSU_H diff --git a/manager/app/src/main/java/com/sukisu/ultra/Natives.kt b/manager/app/src/main/java/com/sukisu/ultra/Natives.kt index 6ee03dcf..00a637ff 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/Natives.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/Natives.kt @@ -26,6 +26,8 @@ object Natives { const val MINIMAL_SUPPORTED_SU_COMPAT = 12040 const val KERNEL_SU_DOMAIN = "u:r:su:s0" + const val MINIMAL_SUPPORTED_KPM = 12800 + const val ROOT_UID = 0 const val ROOT_GID = 0 @@ -66,6 +68,7 @@ object Natives { */ external fun isSuEnabled(): Boolean external fun setSuEnabled(enabled: Boolean): Boolean + external fun isKPMEnabled(): Boolean private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$" private const val NOBODY_UID = 9999 diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt index 14700f16..ac5afbc2 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt @@ -95,6 +95,7 @@ import com.ramcosta.composedestinations.generated.destinations.InstallScreenDest import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.sukisu.ultra.KernelVersion import com.sukisu.ultra.Natives +import com.sukisu.ultra.Natives.isKPMEnabled import com.sukisu.ultra.R import com.sukisu.ultra.getKernelVersion import com.sukisu.ultra.ksuApp @@ -895,7 +896,7 @@ private fun InfoCard() { if (!isSimpleMode) { if (lkmMode != true) { val kpmVersion = getKpmVersion() - val isKpmConfigured = checkKpmConfigured() + val isKpmConfigured = checkKPMEnabled() // 根据showKpmInfo决定是否显示KPM信息 if (showKpmInfo) { @@ -1010,55 +1011,6 @@ private object DeviceModelCache { } } } - -private object KpmConfigCache { - private var isChecked = false - private var isConfigured = false - - fun checkKpmConfigured(): Boolean { - if (isChecked) { - return isConfigured - } - - isConfigured = performKpmCheck() - isChecked = true - return isConfigured - } - - private fun performKpmCheck(): Boolean { - try { - val process = Runtime.getRuntime().exec("su -c cat /proc/config.gz") - val inputStream = process.inputStream - val gzipInputStream = GZIPInputStream(inputStream) - val reader = BufferedReader(InputStreamReader(gzipInputStream)) - - var line: String? - while (reader.readLine().also { line = it } != null) { - if (line?.contains("CONFIG_KPM=y") == true) { - reader.close() - return true - } - } - reader.close() - } catch (e: Exception) { - e.printStackTrace() - } - try { - val process = Runtime.getRuntime().exec("su -c grep sukisu_kpm /proc/kallsyms") - val reader = BufferedReader(InputStreamReader(process.inputStream)) - if (reader.readLine() != null) { - reader.close() - return true - } - reader.close() - } catch (e: Exception) { - e.printStackTrace() - } - - return false - } -} - // 获取设备型号 @SuppressLint("PrivateApi") private fun getDeviceModel(): String { @@ -1066,8 +1018,12 @@ private fun getDeviceModel(): String { } // 检查KPM是否存在 -private fun checkKpmConfigured(): Boolean { - return KpmConfigCache.checkKpmConfigured() +private fun checkKPMEnabled(): Boolean { + return if (Natives.version >= Natives.MINIMAL_SUPPORTED_KPM) { + isKPMEnabled() + } else { + false + } } @SuppressLint("UnnecessaryComposedModifier")