Anti-Tampering and Root Detection
Anti-Tampering and Root Detection
Protecting apps from tampering and detecting rooted devices helps maintain security integrity.
// Comprehensive security checks
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import java.io.File
class SecurityChecker(private val context: Context) {
fun performSecurityChecks(): SecurityStatus {
return SecurityStatus(
isDebuggable = isDebuggable(),
isRooted = isRooted(),
isEmulator = isEmulator(),
isIntegrityCompromised = !verifySignature(),
hasHooks = detectHooks()
)
}
private fun isDebuggable(): Boolean {
return context.applicationInfo.flags and
android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE != 0
}
private fun isRooted(): Boolean {
// Check for root binaries
val rootBinaries = arrayOf("su", "busybox", "supersu", "magisk")
val paths = arrayOf(
"/system/bin/",
"/system/xbin/",
"/sbin/",
"/system/sd/xbin/",
"/system/bin/failsafe/",
"/data/local/xbin/",
"/data/local/bin/",
"/data/local/"
)
for (path in paths) {
for (binary in rootBinaries) {
if (File(path + binary).exists()) {
return true
}
}
}
// Check for root packages
val rootPackages = arrayOf(
"com.koushikdutta.superuser",
"com.topjohnwu.magisk",
"eu.chainfire.supersu",
"com.noshufou.android.su"
)
val packageManager = context.packageManager
for (packageName in rootPackages) {
try {
packageManager.getPackageInfo(packageName, 0)
return true
} catch (e: PackageManager.NameNotFoundException) {
// Package not found, continue checking
}
}
// Check for root properties
val buildTags = Build.TAGS
return buildTags != null && buildTags.contains("test-keys")
}
private fun isEmulator(): Boolean {
return (Build.FINGERPRINT.startsWith("generic") ||
Build.FINGERPRINT.startsWith("unknown") ||
Build.MODEL.contains("google_sdk") ||
Build.MODEL.contains("Emulator") ||
Build.MODEL.contains("Android SDK built for x86") ||
Build.MANUFACTURER.contains("Genymotion") ||
Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
"google_sdk" == Build.PRODUCT)
}
private fun verifySignature(): Boolean {
try {
val packageInfo = context.packageManager.getPackageInfo(
context.packageName,
PackageManager.GET_SIGNATURES
)
val signatures = packageInfo.signatures
val expectedSignature = "YOUR_APP_SIGNATURE" // Replace with actual signature
for (signature in signatures) {
val signatureHash = signature.toCharsString()
if (signatureHash != expectedSignature) {
return false
}
}
return true
} catch (e: Exception) {
return false
}
}
private fun detectHooks(): Boolean {
// Check for Xposed Framework
try {
throw Exception()
} catch (e: Exception) {
for (stackTraceElement in e.stackTrace) {
if (stackTraceElement.className.contains("xposed") ||
stackTraceElement.className.contains("substrate")) {
return true
}
}
}
return false
}
data class SecurityStatus(
val isDebuggable: Boolean,
val isRooted: Boolean,
val isEmulator: Boolean,
val isIntegrityCompromised: Boolean,
val hasHooks: Boolean
)
}