M9: Reverse Engineering

M9: Reverse Engineering

Mobile apps can be reverse engineered to understand logic, extract secrets, or find vulnerabilities.

// iOS - Anti-reverse engineering techniques
class AntiReverseEngineering {
    
    // Obfuscation techniques
    class CodeObfuscation {
        
        // String obfuscation
        private let obfuscatedAPIKey = [0x41, 0x42, 0x43, 0x44, 0x45] // "ABCDE" obfuscated
        
        func getAPIKey() -> String {
            return obfuscatedAPIKey.map { Character(UnicodeScalar($0)) }.map(String.init).joined()
        }
        
        // Control flow obfuscation
        func performSensitiveOperation(input: Int) -> Int {
            var result = input
            
            // Confuse static analysis
            for i in 0..<10 {
                if i % 2 == 0 {
                    result = complexCalculation1(result)
                } else {
                    result = complexCalculation2(result)
                }
                
                // Add dummy operations
                let dummy = Int.random(in: 0...100)
                _ = dummy * 2 + 1
            }
            
            return result ^ 0xDEADBEEF
        }
        
        // Symbol stripping (done at build time)
        // Use Xcode build settings:
        // - Strip Debug Symbols During Copy: YES
        // - Strip Linked Product: YES
        // - Strip Style: All Symbols
        
        // Binary packing (using external tools)
        // - UPX
        // - Custom packers
    }
    
    // Runtime protection
    class RuntimeProtection {
        
        // Detect common reverse engineering tools
        func detectReverseEngineeringTools() -> Bool {
            let suspiciousLibraries = [
                "FridaGadget",
                "cynject",
                "libcycript",
                "SubstrateLoader"
            ]
            
            for i in 0..<_dyld_image_count() {
                if let name = _dyld_get_image_name(i) {
                    let imageName = String(cString: name)
                    
                    for lib in suspiciousLibraries {
                        if imageName.contains(lib) {
                            return true
                        }
                    }
                }
            }
            
            return false
        }
        
        // Anti-debugging with ptrace
        func enableAntiDebugging() {
            #if !DEBUG
            // Prevent debugging
            ptrace(PT_DENY_ATTACH, 0, 0, 0)
            
            // Additional check using sysctl
            var info = kinfo_proc()
            var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
            var size = MemoryLayout<kinfo_proc>.stride
            
            if sysctl(&mib, u_int(mib.count), &info, &size, nil, 0) == 0 {
                if (info.kp_proc.p_flag & P_TRACED) != 0 {
                    exit(0)
                }
            }
            #endif
        }
        
        // Method swizzling detection
        func detectMethodSwizzling() -> Bool {
            let originalMethod = class_getInstanceMethod(
                UIApplication.self,
                #selector(UIApplication.sendAction(_:to:from:for:))
            )
            
            let originalImplementation = method_getImplementation(originalMethod!)
            
            // Store original implementation address
            let expectedAddress = unsafeBitCast(
                UIApplication.sendAction(_:to:from:for:),
                to: IMP.self
            )
            
            return originalImplementation != expectedAddress
        }
    }
}