diff --git a/app/src/main/java/io/mesalabs/knoxpatch/MainHook.kt b/app/src/main/java/io/mesalabs/knoxpatch/MainHook.kt index 360fbee..a9c0c56 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/MainHook.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/MainHook.kt @@ -21,7 +21,7 @@ package io.mesalabs.knoxpatch import com.highcapable.yukihookapi.YukiHookAPI.encase import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed import com.highcapable.yukihookapi.hook.factory.configs -import com.highcapable.yukihookapi.hook.log.loggerE +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit import io.mesalabs.knoxpatch.hooks.KnoxSDKHooks @@ -61,16 +61,16 @@ object MainHook : IYukiHookXposedInit { */ when { sepVersion == -1 -> { - loggerE(msg = "$TAG: onHook: This module only supports One UI running devices.") + YLog.error(msg = "$TAG: onHook: This module only supports One UI running devices.") return@encase } sepVersion < Constants.ONEUI_1_0 -> { - loggerE(msg = "$TAG: onHook: unknown SEP version: $sepVersion") + YLog.error(msg = "$TAG: onHook: unknown SEP version: $sepVersion") return@encase } sepVersion > Constants.ONEUI_6_0 -> { val oneUiVersion: String = BuildUtils.getFormattedOneUIVersion() - loggerE(msg = "$TAG: onHook: One UI $oneUiVersion is not yet supported.") + YLog.error(msg = "$TAG: onHook: One UI $oneUiVersion is not yet supported.") return@encase } } diff --git a/app/src/main/java/io/mesalabs/knoxpatch/hooks/KnoxSDKHooks.kt b/app/src/main/java/io/mesalabs/knoxpatch/hooks/KnoxSDKHooks.kt index 9e7820a..e4b8f87 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/hooks/KnoxSDKHooks.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/hooks/KnoxSDKHooks.kt @@ -19,26 +19,25 @@ package io.mesalabs.knoxpatch.hooks import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker -import com.highcapable.yukihookapi.hook.log.loggerD +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.java.IntType object KnoxSDKHooks : YukiBaseHooker() { private const val TAG: String = "KnoxSDKHooks" override fun onHook() { - loggerD(msg = "$TAG: onHook: loaded.") + YLog.debug(msg = "$TAG: onHook: loaded.") /* Disable Knox support */ - findClass("com.samsung.android.knox.EnterpriseDeviceManager").hook { - injectMember { - method { - name = "getAPILevel" - emptyParam() - returnType = IntType - } + "com.samsung.android.knox.EnterpriseDeviceManager".toClass() + .method { + name = "getAPILevel" + emptyParam() + returnType = IntType + }.hook { replaceTo(-1) } - } } } diff --git a/app/src/main/java/io/mesalabs/knoxpatch/hooks/PropSpoofHooks.kt b/app/src/main/java/io/mesalabs/knoxpatch/hooks/PropSpoofHooks.kt index ce1db72..24e335b 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/hooks/PropSpoofHooks.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/hooks/PropSpoofHooks.kt @@ -19,22 +19,23 @@ package io.mesalabs.knoxpatch.hooks import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker -import com.highcapable.yukihookapi.hook.log.loggerD +import com.highcapable.yukihookapi.hook.factory.constructor +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.java.StringClass object PropSpoofHooks : YukiBaseHooker() { private const val TAG: String = "PropSpoofHooks" override fun onHook() { - loggerD(msg = "$TAG: onHook: loaded.") + YLog.debug(msg = "$TAG: onHook: loaded.") /* Spoof critical system props */ - findClass("java.lang.ProcessBuilder").hook { - injectMember { - constructor { - param(Array::class.java) - } - beforeHook { + "java.lang.ProcessBuilder".toClass() + .constructor { + param(Array::class.java) + }.hook { + before { val cmdarray: Array = args(0).array() // Fix SPCMAgent (SAK) @@ -48,16 +49,14 @@ object PropSpoofHooks : YukiBaseHooker() { } } } - } - findClass("android.os.SemSystemProperties").hook { - injectMember { - method { - name = "get" - param(String::class.java) - returnType = StringClass - } - beforeHook { + "android.os.SemSystemProperties".toClass() + .method { + name = "get" + param(String::class.java) + returnType = StringClass + }.hook { + before { val key: String = args(0).string() // Fixes: @@ -70,13 +69,13 @@ object PropSpoofHooks : YukiBaseHooker() { } } - injectMember { - method { - name = "get" - param(String::class.java, String::class.java) - returnType = StringClass - } - beforeHook { + "android.os.SemSystemProperties".toClass() + .method { + name = "get" + param(String::class.java, String::class.java) + returnType = StringClass + }.hook { + before { val key: String = args(0).string() val def: String = args(1).string() @@ -88,7 +87,6 @@ object PropSpoofHooks : YukiBaseHooker() { } } } - } } } diff --git a/app/src/main/java/io/mesalabs/knoxpatch/hooks/RootDetectionHooks.kt b/app/src/main/java/io/mesalabs/knoxpatch/hooks/RootDetectionHooks.kt index b13a003..5aa2b39 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/hooks/RootDetectionHooks.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/hooks/RootDetectionHooks.kt @@ -23,8 +23,10 @@ import android.os.Build import java.io.IOException import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker +import com.highcapable.yukihookapi.hook.factory.constructor import com.highcapable.yukihookapi.hook.factory.field -import com.highcapable.yukihookapi.hook.log.loggerD +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.java.BooleanType import com.highcapable.yukihookapi.hook.type.java.IntType import com.highcapable.yukihookapi.hook.type.java.StringClass @@ -57,7 +59,7 @@ object RootDetectionHooks : YukiBaseHooker() { ) override fun onHook() { - loggerD(msg = "$TAG: onHook: loaded.") + YLog.debug(msg = "$TAG: onHook: loaded.") /* Spoof root checks */ if (Build.TAGS.contains("test-keys")) { @@ -67,12 +69,11 @@ object RootDetectionHooks : YukiBaseHooker() { }.get(null).set("release-keys") } - findClass("java.io.File").hook { - injectMember { - constructor { - param(String::class.java) - } - beforeHook { + "java.io.File".toClass() + .constructor { + param(String::class.java) + }.hook { + before { val pathname: String = args(0).string() if (pathname.endsWith("su") || pathname.contains("Superuser.apk")) { @@ -80,12 +81,11 @@ object RootDetectionHooks : YukiBaseHooker() { } } } - - injectMember { - constructor { - param(String::class.java, String::class.java) - } - beforeHook { + "java.io.File".toClass() + .constructor { + param(String::class.java, String::class.java) + }.hook { + before { val child: String = args(1).string() if (child == "su" || child == "busybox") { @@ -93,24 +93,21 @@ object RootDetectionHooks : YukiBaseHooker() { } } } - - injectMember { - method { - name = "canWrite" - emptyParam() - returnType = BooleanType - } + "java.io.File".toClass() + .method { + name = "canWrite" + emptyParam() + returnType = BooleanType + }.hook { replaceToFalse() } - } - findClass("java.lang.Runtime").hook { - injectMember { - method { - name = "exec" - param(String::class.java) - } - beforeHook { + "java.lang.Runtime".toClass() + .method { + name = "exec" + param(String::class.java) + }.hook { + before { val command: String = args(0).string() if (command == "su") { @@ -118,13 +115,12 @@ object RootDetectionHooks : YukiBaseHooker() { } } } - - injectMember { - method { - name = "exec" - param(Array::class.java) - } - beforeHook { + "java.lang.Runtime".toClass() + .method { + name = "exec" + param(Array::class.java) + }.hook { + before { val cmdarray: Array = args(0).array() for (cmd in cmdarray) { @@ -134,15 +130,13 @@ object RootDetectionHooks : YukiBaseHooker() { } } } - } - findClass("android.app.ApplicationPackageManager").hook { - injectMember { - method { - name = "getPackageInfo" - param(String::class.java, IntType) - } - beforeHook { + "android.app.ApplicationPackageManager".toClass() + .method { + name = "getPackageInfo" + param(String::class.java, IntType) + }.hook { + before { val packageName: String = args(0).string() for (cmd in rootPackages) { @@ -153,7 +147,6 @@ object RootDetectionHooks : YukiBaseHooker() { } } } - } } } diff --git a/app/src/main/java/io/mesalabs/knoxpatch/hooks/SamsungKeystoreHooks.kt b/app/src/main/java/io/mesalabs/knoxpatch/hooks/SamsungKeystoreHooks.kt index debbf8f..33291f9 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/hooks/SamsungKeystoreHooks.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/hooks/SamsungKeystoreHooks.kt @@ -19,31 +19,29 @@ package io.mesalabs.knoxpatch.hooks import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker -import com.highcapable.yukihookapi.hook.log.loggerD -import com.highcapable.yukihookapi.hook.log.loggerE +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.java.BooleanType object SamsungKeystoreHooks : YukiBaseHooker() { private const val TAG: String = "SamsungKeystoreHooks" override fun onHook() { - loggerD(msg = "$TAG: onHook: loaded.") + YLog.debug(msg = "$TAG: onHook: loaded.") /* Bypass SAK integrity check */ - findClass("com.samsung.android.security.keystore.AttestParameterSpec").hook { - injectMember { - method { - name = "isVerifiableIntegrity" - emptyParam() - returnType = BooleanType - } + "com.samsung.android.security.keystore.AttestParameterSpec".toClass() + .method { + name = "isVerifiableIntegrity" + emptyParam() + returnType = BooleanType + }.hook { replaceToTrue() + }.onAllFailure { + YLog.error(msg = "$TAG: couldn't access class " + + "com.samsung.android.security.keystore.AttestParameterSpec " + + "(${it.javaClass.simpleName})") } - }.onHookClassNotFoundFailure { - loggerE(msg = "$TAG: couldn't access class " + - "com.samsung.android.security.keystore.AttestParameterSpec " + - "(${it.javaClass.simpleName})") - } } } diff --git a/app/src/main/java/io/mesalabs/knoxpatch/hooks/SystemHooks.kt b/app/src/main/java/io/mesalabs/knoxpatch/hooks/SystemHooks.kt index b24ee1b..1000de8 100644 --- a/app/src/main/java/io/mesalabs/knoxpatch/hooks/SystemHooks.kt +++ b/app/src/main/java/io/mesalabs/knoxpatch/hooks/SystemHooks.kt @@ -27,8 +27,9 @@ import java.security.cert.Certificate import de.robv.android.xposed.XposedBridge import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker -import com.highcapable.yukihookapi.hook.log.loggerD -import com.highcapable.yukihookapi.hook.log.loggerE +import com.highcapable.yukihookapi.hook.factory.constructor +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.type.java.BooleanType import io.mesalabs.knoxpatch.utils.BuildUtils @@ -38,7 +39,7 @@ object SystemHooks : YukiBaseHooker() { private const val TAG: String = "SystemHooks" override fun onHook() { - loggerD(msg = "$TAG: onHook: loaded.") + YLog.debug(msg = "$TAG: onHook: loaded.") /* Fix Secure Folder/Work profile */ val sepVersion: Int = BuildUtils.getSEPVersion() @@ -54,65 +55,55 @@ object SystemHooks : YukiBaseHooker() { private fun applySAKHooks() { if (Build.VERSION.SDK_INT >= 31) { - findClass("com.android.server.knox.dar.DarManagerService").hook { - injectMember { - method { - name = "checkDeviceIntegrity" - param(Array::class.java) - returnType = BooleanType - } + "com.android.server.knox.dar.DarManagerService".toClass() + .method { + name = "checkDeviceIntegrity" + param(Array::class.java) + returnType = BooleanType + }.hook { replaceToTrue() } - } } else { - findClass("com.android.server.pm.PersonaManagerService").hook { - injectMember { - method { - name = "isKnoxKeyInstallable" - emptyParam() - returnType = BooleanType - } + "com.android.server.pm.PersonaManagerService".toClass() + .method { + name = "isKnoxKeyInstallable" + emptyParam() + returnType = BooleanType + }.hook { replaceToTrue() } - } } } private fun applyTIMAHooks() { - findClass("com.android.server.pm.PersonaServiceHelper").hook { - injectMember { - method { - name = "isTimaAvailable" - param(Context::class.java) - returnType = BooleanType - } + "com.android.server.pm.PersonaServiceHelper".toClass() + .method { + name = "isTimaAvailable" + param(Context::class.java) + returnType = BooleanType + }.hook { replaceToTrue() } - } if (Build.VERSION.SDK_INT >= 29) { - findClass("com.android.server.SdpManagerService\$LocalService").hook { - injectMember { - method { - name = "isKnoxKeyInstallable" - emptyParam() - returnType = BooleanType - } + "com.android.server.SdpManagerService\$LocalService".toClass() + .method { + name = "isKnoxKeyInstallable" + emptyParam() + returnType = BooleanType + }.hook { replaceToTrue() } - } } - findClass("com.android.server.locksettings.SyntheticPasswordManager").hook { - injectMember { - method { - name = "isUnifiedKeyStoreSupported" - emptyParam() - returnType = BooleanType - } + "com.android.server.locksettings.SyntheticPasswordManager".toClass() + .method { + name = "isUnifiedKeyStoreSupported" + emptyParam() + returnType = BooleanType + }.hook { replaceToTrue() } - } findAndDeoptimizeMethod("com.android.server.locksettings.LockSettingsService", "verifyToken") @@ -125,28 +116,24 @@ object SystemHooks : YukiBaseHooker() { } private fun applyKGHooks() { - findClass("com.samsung.android.knoxguard.service.KnoxGuardService").hook { - injectMember { - constructor { - param(Context::class.java) - } - beforeHook { + "com.samsung.android.knoxguard.service.KnoxGuardService".toClass() + .constructor { + param(Context::class.java) + }.hook { + before { UnsupportedOperationException("KnoxGuard is unsupported").throwToApp() } } - } if (Build.VERSION.SDK_INT >= 30) { - findClass("com.samsung.android.knoxguard.service.KnoxGuardSeService").hook { - injectMember { - constructor { - param(Context::class.java) - } - beforeHook { + "com.samsung.android.knoxguard.service.KnoxGuardSeService".toClass() + .constructor { + param(Context::class.java) + }.hook { + before { UnsupportedOperationException("KnoxGuard is unsupported").throwToApp() } } - } } } @@ -156,13 +143,13 @@ object SystemHooks : YukiBaseHooker() { val clz: Class<*> = Class.forName(className, false, appClassLoader) for (m in clz.declaredMethods) { if (methodName == m.name) { - loggerD(msg = "$TAG: findAndDeoptimizeMethod: $m") + YLog.debug(msg = "$TAG: findAndDeoptimizeMethod: $m") XposedBridge::class.java.getDeclaredMethod("deoptimizeMethod", Member::class.java) .invoke(null, m) } } } catch (e: Throwable) { - loggerE(msg = "$TAG: findAndDeoptimizeMethod: $e") + YLog.error(msg = "$TAG: findAndDeoptimizeMethod: $e") } }