如果我希望我的应用程序在越狱的iPhone上表现不同,我将如何确定这一点?
这取决于越狱的意思.在简单的情况下,您应该能够看到Cydia是否已经安装并且可以通过它来实现
NSString *filePath = @"/Applications/Cydia.app"; if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { // do something useful }
对于被黑客攻击的内核,它涉及的内容有点多(很多).
+(BOOL)isJailbroken { NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"]; return [[UIApplication sharedApplication] canOpenURL:url]; }
/Applications/Cydia.app
普通手机不允许检查文件路径?我从来没有听说过Apple检测到这个并且拒绝了它的应用程序,但Apple是不可预测的.Cydia有一个URL方案cydia:// 可以通过UIApplication合法检查canOpenURL:
这是一个代码,它结合了我为此需求找到的一些答案,并将为您提供更高的成功率:
BOOL isJailbroken() { #if !(TARGET_IPHONE_SIMULATOR) if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"] || [[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"] || [[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"] || [[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"] || [[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"] || [[NSFileManager defaultManager] fileExistsAtPath:@"/private/var/lib/apt/"] || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) { return YES; } FILE *f = NULL ; if ((f = fopen("/bin/bash", "r")) || (f = fopen("/Applications/Cydia.app", "r")) || (f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r")) || (f = fopen("/usr/sbin/sshd", "r")) || (f = fopen("/etc/apt", "r"))) { fclose(f); return YES; } fclose(f); NSError *error; NSString *stringToBeWritten = @"This is a test."; [stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error]; [[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil]; if(error == nil) { return YES; } #endif return NO; }
检查内核是否坏了不是更多涉及.
越狱使内核对签名代码的签名检查始终报告代码已正确签名,不间断的手机无法运行带有错误签名的代码.
因此,在应用程序中包含一个带有错误签名的单独可执行文件.它可能只是一个具有main()和返回值的3行程序.在没有代码签名的情况下编译可执行文件(在"项目设置" - >"构建"中将其关闭),并使用"codesign"命令行实用程序使用其他密钥对其进行签名.
让您的应用执行单独的可执行文件.如果您的程序在使用错误的sig运行单独的可执行文件时无法获得返回值,那么它肯定会被判入狱.如果单独的可执行文件返回A-OK,那么手机肯定会被越狱.
BOOL isJailbroken() { #if TARGET_IPHONE_SIMULATOR return NO; #else FILE *f = fopen("/bin/bash", "r"); if (errno == ENOENT) { // device is NOT jailbroken fclose(f); return NO; } else { // device IS jailbroken fclose(f); return YES; } #endif }
您可以通过检查以下内容来检测设备是否为JailBroken:
Cydia已安装
验证一些系统路径
执行沙箱完整性检查
执行符号链接验证
验证您是否在沙箱外创建和写入文件
我从各种文章和书籍中创建了一个开源库.在GitHub上试一试!
我在Swift 2.3中重写了@Yossi提供的解决方案
public static func jailbroken(application: UIApplication) -> Bool { guard let cydiaUrlScheme = NSURL(string: "cydia://package/com.example.package") else { return isJailbroken() } return application.canOpenURL(cydiaUrlScheme) || isJailbroken() } static func isJailbroken() -> Bool { if isSimulator { return false } let fileManager = NSFileManager.defaultManager() if fileManager.fileExistsAtPath("/Applications/Cydia.app") || fileManager.fileExistsAtPath("/Library/MobileSubstrate/MobileSubstrate.dylib") || fileManager.fileExistsAtPath("/bin/bash") || fileManager.fileExistsAtPath("/usr/sbin/sshd") || fileManager.fileExistsAtPath("/etc/apt") || fileManager.fileExistsAtPath("/usr/bin/ssh") { return true } if canOpen("/Applications/Cydia.app") || canOpen("/Library/MobileSubstrate/MobileSubstrate.dylib") || canOpen("/bin/bash") || canOpen("/usr/sbin/sshd") || canOpen("/etc/apt") || canOpen("/usr/bin/ssh") { return true } let path = "/private/" + NSUUID().UUIDString do { try "anyString".writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding) try fileManager.removeItemAtPath(path) return true } catch { return false } } static func canOpen(path: String) -> Bool { let file = fopen(path, "r") guard file != nil else { return false } fclose(file) return true }
我所知道的最复杂的方法是使用objc_copyImageNames()
函数.它返回一个当前加载的库列表,因为大多数人在越狱设备上都有MobileSubstrate,并且大多数iAP破解工具依赖它,至少会出现一些MobileSubstrate库.