feat(security_features): mod detection version check

This feature tells users who are using more recent/latest versions to use earlier versions, because after version 12.81.0.44 (126022), Snapchat now detects changes made to the app
This commit is contained in:
rhunk
2024-10-06 11:43:42 +02:00
parent 574775f65c
commit beb5217404
4 changed files with 26 additions and 34 deletions

View File

@@ -18,7 +18,6 @@ import androidx.compose.ui.window.Dialog
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.navigation.NavBackStackEntry import androidx.navigation.NavBackStackEntry
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.rhunk.snapenhance.common.Constants
import me.rhunk.snapenhance.common.action.EnumAction import me.rhunk.snapenhance.common.action.EnumAction
import me.rhunk.snapenhance.common.bridge.InternalFileHandleType import me.rhunk.snapenhance.common.bridge.InternalFileHandleType
import me.rhunk.snapenhance.common.ui.rememberAsyncMutableState import me.rhunk.snapenhance.common.ui.rememberAsyncMutableState
@@ -60,7 +59,7 @@ class HomeSettings : Routes.Route() {
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Text(text = text) Text(text = text, modifier = Modifier.padding(end = 16.dp), fontSize = 14.sp)
Switch(checked = value, onCheckedChange = { Switch(checked = value, onCheckedChange = {
value = it value = it
sharedPreferences.edit().putBoolean(realKey, it).apply() sharedPreferences.edit().putBoolean(realKey, it).apply()
@@ -288,6 +287,7 @@ class HomeSettings : Routes.Route() {
PreferenceToggle(context.sharedPreferences, key = "disable_feature_loading", text = "Disable Feature Loading") PreferenceToggle(context.sharedPreferences, key = "disable_feature_loading", text = "Disable Feature Loading")
PreferenceToggle(context.sharedPreferences, key = "disable_mapper", text = "Disable Auto Mapper") PreferenceToggle(context.sharedPreferences, key = "disable_mapper", text = "Disable Auto Mapper")
PreferenceToggle(context.sharedPreferences, key = "disable_sif", text = "Disable Security Features") PreferenceToggle(context.sharedPreferences, key = "disable_sif", text = "Disable Security Features")
PreferenceToggle(context.sharedPreferences, key = "disable_mod_detection_version_check", text = "Disable Mod Detection Version Check")
} }
} }
Spacer(modifier = Modifier.height(50.dp)) Spacer(modifier = Modifier.height(50.dp))

View File

@@ -3,4 +3,9 @@ package me.rhunk.snapenhance.common.config
/* /*
Due to recent resource obfuscation, some UI features will no longer work because it depends on non obfuscated resources Due to recent resource obfuscation, some UI features will no longer work because it depends on non obfuscated resources
*/ */
val RES_OBF_VERSION_CHECK = VersionCheck(maxVersion = ("13.7.0.42" to 157172)) val RES_OBF_VERSION_CHECK = VersionCheck(maxVersion = ("13.7.0.42" to 157172))
/*
After this version, Snapchat will start detecting modifications to their app (to be confirmed)
*/
val MOD_DETECTION_VERSION_CHECK = VersionCheck(maxVersion = ("12.81.0.44 (126022)" to 126023))

View File

@@ -2,23 +2,19 @@ package me.rhunk.snapenhance.core.features.impl
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.system.Os import android.system.Os
import android.widget.TextView import androidx.compose.material.icons.Icons
import androidx.compose.ui.graphics.Color import androidx.compose.material.icons.filled.NotInterested
import androidx.compose.ui.graphics.toArgb import me.rhunk.snapenhance.common.config.MOD_DETECTION_VERSION_CHECK
import kotlinx.coroutines.Dispatchers import me.rhunk.snapenhance.common.config.VersionRequirement
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent
import me.rhunk.snapenhance.core.features.Feature import me.rhunk.snapenhance.core.features.Feature
import me.rhunk.snapenhance.core.util.ktx.getId
import me.rhunk.snapenhance.core.util.ktx.setObjectField import me.rhunk.snapenhance.core.util.ktx.setObjectField
import java.io.FileDescriptor import java.io.FileDescriptor
class SecurityFeatures : Feature("Security Features") { class SecurityFeatures : Feature("Security Features") {
private fun transact(option: Int, option2: Long) = kotlin.runCatching { Os.prctl(option, option2, 0, 0, 0) }.getOrNull() private fun transact(option: Int, option2: Long) = runCatching { Os.prctl(option, option2, 0, 0, 0) }.getOrNull()
private val token by lazy { private val token by lazy {
transact(0, 0) transact(0, 0)
@@ -71,28 +67,18 @@ class SecurityFeatures : Feature("Security Features") {
} }
} }
val hovaPageTitleId = context.resources.getId("hova_page_title") val status = getStatus()
val canCheckVersion = context.bridgeClient.getDebugProp("disable_mod_detection_version_check", "false") != "true"
val snapchatVersionCode = context.androidContext.packageManager.getPackageInfo(context.androidContext.packageName, 0).longVersionCode
fun findHovaPageTitle(): TextView? { if (canCheckVersion && MOD_DETECTION_VERSION_CHECK.checkVersion(snapchatVersionCode)?.second == VersionRequirement.OLDER_REQUIRED && (status == null || status < 2)) {
return context.mainActivity?.findViewById(hovaPageTitleId) onNextActivityCreate {
} context.inAppOverlay.showStatusToast(
icon = Icons.Filled.NotInterested,
context.coroutineScope.launch { text = "SnapEnhance is not compatible with this version of Snapchat without SIF and will result in a ban.\nUse Snapchat ${MOD_DETECTION_VERSION_CHECK.maxVersion?.first ?: "0.0.0"} or older to avoid detections or use test accounts.",
while (true) { durationMs = 10000,
val status = getStatus() maxLines = 6
withContext(Dispatchers.Main) { )
val textView = findHovaPageTitle() ?: return@withContext
if (status == null || status == 0) {
textView.text = "SIF not loaded"
textView.textSize = 13F
textView.setTextColor(Color.Red.toArgb())
} else {
textView.setTextColor(Color.Green.toArgb())
val prefix = textView.text.toString().substringBeforeLast(" (")
textView.text = "$prefix (${status})"
}
}
delay(1000)
} }
} }
} }

View File

@@ -255,11 +255,12 @@ class InAppOverlay(
text: String, text: String,
durationMs: Int = 2000, durationMs: Int = 2000,
showDuration: Boolean = true, showDuration: Boolean = true,
maxLines: Int = 3
) { ) {
showToast( showToast(
icon = { Icon(icon, contentDescription = "icon", modifier = Modifier.size(32.dp)) }, icon = { Icon(icon, contentDescription = "icon", modifier = Modifier.size(32.dp)) },
text = { text = {
Text(text, modifier = Modifier.fillMaxWidth(), maxLines = 3, overflow = TextOverflow.Ellipsis, lineHeight = 15.sp, fontSize = 15.sp) Text(text, modifier = Modifier.fillMaxWidth(), maxLines = maxLines, overflow = TextOverflow.Ellipsis, lineHeight = 15.sp, fontSize = 15.sp)
}, },
durationMs = durationMs, durationMs = durationMs,
showDuration = showDuration showDuration = showDuration