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
    )
}