diff --git a/core/build.gradle.kts b/core/build.gradle.kts index dbccbf77..b55166da 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -47,4 +47,5 @@ dependencies { implementation(libs.androidx.material.ripple) implementation(libs.androidx.material.icons.extended) implementation(libs.androidx.material3) + implementation(libs.hiddenapibypass) } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt index e8661217..51b562ef 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt @@ -30,6 +30,7 @@ import me.rhunk.snapenhance.core.ui.InAppOverlay import me.rhunk.snapenhance.core.util.LSPatchUpdater import me.rhunk.snapenhance.core.util.hook.HookAdapter import me.rhunk.snapenhance.core.util.hook.HookStage +import me.rhunk.snapenhance.core.util.hook.findRestrictedMethod import me.rhunk.snapenhance.core.util.hook.hook import kotlin.reflect.KClass import kotlin.system.exitProcess @@ -240,12 +241,12 @@ class SnapEnhance { appContext.log.warn("sif is disabled") } - Runtime::class.java.declaredMethods.first { + Runtime::class.java.findRestrictedMethod { it.name == "loadLibrary0" && it.parameterTypes.contentEquals( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) arrayOf(Class::class.java, String::class.java) else arrayOf(ClassLoader::class.java, String::class.java) ) - }.apply { + }!!.apply { if (safeMode) { hook(HookStage.BEFORE) { param -> if (param.arg(1) != "scplugin") return@hook diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt index 4de6fd93..ffda96aa 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt @@ -30,6 +30,7 @@ import me.rhunk.snapenhance.core.features.impl.downloader.decoder.MessageDecoder import me.rhunk.snapenhance.core.features.impl.experiments.BetterTranscript import me.rhunk.snapenhance.core.features.impl.spying.StealthMode import me.rhunk.snapenhance.core.util.hook.HookStage +import me.rhunk.snapenhance.core.util.hook.findRestrictedMethod import me.rhunk.snapenhance.core.util.hook.hook import me.rhunk.snapenhance.core.util.ktx.setObjectField import me.rhunk.snapenhance.core.util.media.PreviewUtils @@ -509,7 +510,7 @@ class Notifications : Feature("Notifications") { } } - NotificationManager::class.java.declaredMethods.find { + NotificationManager::class.java.findRestrictedMethod { it.name == "cancelAsUser" }?.hook(HookStage.AFTER) { param -> val notificationId = param.arg(1) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/util/hook/Hooker.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/util/hook/Hooker.kt index 842570ea..9dcd5c09 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/util/hook/Hooker.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/util/hook/Hooker.kt @@ -3,6 +3,7 @@ package me.rhunk.snapenhance.core.util.hook import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge import me.rhunk.snapenhance.common.logger.AbstractLogger +import org.lsposed.hiddenapibypass.HiddenApiBypass import java.lang.reflect.Member import java.lang.reflect.Method import java.lang.reflect.Modifier @@ -183,3 +184,9 @@ fun Array.hookAll(stage: HookStage, param: (HookAdapter) -> Unit) { it.hook(stage, param) } } + +fun Class<*>.findRestrictedMethod( + predicate: (Method) -> Boolean +): Method? { + return declaredMethods.find(predicate) ?: HiddenApiBypass.getDeclaredMethods(this).filterIsInstance().find(predicate) +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 010b780c..59e57427 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ okhttp = "5.0.0-alpha.14" rhino = "1.7.15" rhino-android = "1.6.0" rust-android = "0.9.4" +hiddenapibypass = "4.3" [libraries] androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } @@ -51,6 +52,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } junit = { group = "org.junit.vintage", name = "junit-vintage-engine", version.ref = "junit" } okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } osmdroid-android = { group = "org.osmdroid", name = "osmdroid-android", version.ref = "osmdroid-android" } +hiddenapibypass = { module = "org.lsposed.hiddenapibypass:hiddenapibypass", version.ref = "hiddenapibypass" } recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" } rhino = { module = "org.mozilla:rhino", version.ref = "rhino" } rhino-android = { group = "com.faendir.rhino", name = "rhino-android", version.ref = "rhino-android" }