178

如果我希望我的应用程序在越狱的 iPhone 上表现不同,我将如何确定这一点?

4

18 回答 18

92

这取决于您所说的越狱是什么意思。在简单的情况下,您应该能够查看是否安装了 Cydia 并通过它 - 比如

NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
   // do something useful
}

对于被黑的内核,它涉及更多一点(很多)。

于 2009-01-05T18:00:49.790 回答
61

这是一个结合了我为这个需求找到的一些答案的代码,并且会给你更高的成功率:

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;
}
于 2014-11-03T10:36:08.170 回答
54
+(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:

于 2012-08-28T16:50:55.853 回答
52

检查内核是否损坏并不涉及更多。

越狱使内核对签名代码的签名检查始终报告代码签名正确,完整的手机无法运行签名错误的代码。

因此,请在应用程序中包含一个带有错误签名的单独可执行文件。它可能只是一个具有 main() 和返回值的 3 行程序。在没有代码签名的情况下编译可执行文件(在项目设置->构建中将其关闭)并使用“codedesign”命令行实用程序使用不同的密钥对其进行签名。

让您的应用程序执行单独的可执行文件。如果您的程序在运行带有错误 sig 的单独可执行文件时无法获得返回值,那么它肯定会被监禁。如果单独的可执行文件返回 A-OK,则手机肯定是越狱了。

于 2009-08-18T07:50:07.300 回答
20
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
}
于 2012-03-05T14:17:04.043 回答
16

我在 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
}
于 2016-12-05T08:13:06.713 回答
14

您可以通过检查以下内容来检测设备是否越狱:

  • 安装了 Cydia
  • 验证一些系统路径
  • 执行沙盒完整性检查
  • 执行符号链接验证
  • 验证您是否在沙盒之外创建和写入文件

我根据各种文章和书籍创建了一个开源库。在 GitHub 上试试吧

于 2013-12-10T21:27:04.150 回答
6

我知道的最复杂的方法是使用objc_copyImageNames()函数。它返回当前加载的库列表,并且由于大多数人在越狱设备上都有 MobileSubstrate 并且大多数 iAP 破解工具都依赖它,因此至少会显示一些 MobileSubstrate 库。

于 2013-10-22T04:47:28.977 回答
4

我不知道为此存在任何“API”。如果有,那么越狱掩蔽产品会很快掩盖它们。

正如很多人指出的那样,这是一场猫捉老鼠的游戏。在两位玩家都成为专家之后,这一切都归结为谁先出手。(手持设备的人。)

我在 Zdziarski 的新书《Hacking and Securing iOS Apps》中找到了很多检测越狱的好建议。(就个人而言,我为 O'Reilly 电子书支付了更多费用,因为它们允许复制和粘贴。)

不,我不隶属于出版商。但我确实发现这是一本好书。我不喜欢仅仅发布黑客的错误以便他们修复它们,所以我想我会指向这本书。

于 2012-04-11T16:57:54.723 回答
4

尝试通过您的应用程序执行未签名的代码。

越狱设备通常具有以下特点:

  • 运行未签名的代码
  • 安装了 Cydia
  • 有越狱文件
  • 对整个文件系统的完全读写访问
  • 一些系统文件将被修改(内容等 sha1 与原始文件不匹配)
  • 坚持特定版本(越狱版本)

只检查文件是否存在以进行越狱检测注定会失败。这些检查很容易绕过。

于 2013-05-26T12:11:19.217 回答
4

要检查的一些常见文件: /Library/MobileSubstrate/MobileSubstrate.dylib

/Applications/Cydia.app

/var/cache/apt

/var/lib/apt

/var/lib/cydia

/var/log/syslog

/var/tmp/cydia.log

/bin/bash

/bin/sh

/usr/sbin/sshd

/usr/libexec/ssh-keysign

/etc/ssh/sshd_config

/etc/apt

大多数检查 Cydia 相关文件。

于 2015-01-22T12:48:05.930 回答
4

请为 Swift 4 及更高版本使用以下代码:在 appdelegate 中添加以下代码:

private func getJailbrokenStatus() -> Bool {
    if TARGET_IPHONE_SIMULATOR != 1 {
        // Check 1 : existence of files that are common for jailbroken devices
        if FileManager.default.fileExists(atPath: "/Applications/Cydia.app")
            || FileManager.default.fileExists(atPath: "/Library/MobileSubstrate/MobileSubstrate.dylib")
            || FileManager.default.fileExists(atPath: "/bin/bash")
            || FileManager.default.fileExists(atPath: "/usr/sbin/sshd")
            || FileManager.default.fileExists(atPath: "/etc/apt")
            || FileManager.default.fileExists(atPath: "/private/var/lib/apt/")
            || UIApplication.shared.canOpenURL(URL(string:"cydia://package/com.example.package")!) {
            return true
        }
        // Check 2 : Reading and writing in system directories (sandbox violation)
        let stringToWrite = "Jailbreak Test"
        do {
            try stringToWrite.write(toFile:"/private/JailbreakTest.txt", atomically:true, encoding:String.Encoding.utf8)
            //Device is jailbroken
            return true
        } catch {
            return false
        }
    }
    else {
        return false
    }
}

在 Appdelegate 方法中,编写如下代码

func applicationDidBecomeActive (_ application: UIApplication) {
    
    if getJailbrokenStatus() {
        let alert = UIAlertController(title: LocalizedKeys.Errors.jailbreakError, message: LocalizedKeys.Errors.jailbreakErrorMessage, preferredStyle: UIAlertController.Style.alert)
        let jailBrokenView = UIViewController()
        
        jailBrokenView.view.frame = UIScreen.main.bounds
        jailBrokenView.view.backgroundColor = .white
        self.window?.rootViewController = jailBrokenView
        jailBrokenView.present(alert, animated: true, completion: nil)
    }
    
    if #available(iOS 11.0, *) {
        if !UIScreen.main.isCaptured {
            DispatchQueue.main.async {
                self.blockImageView.removeFromSuperview()
            }
        }
    }
}
于 2019-09-06T12:02:29.053 回答
3

我建议寻找“香草”iPhone 上不存在的文件。我见过的所有越狱工具包都安装了 ssh。这可能是越狱手机的一个很好的指标。

于 2009-01-05T17:54:10.490 回答
3

我们所做的是,我们已经有一个 RSS 提要来与我们的用户交流(Stocks Live),我们放了一个新闻项目,内容如下:

一些越狱设备有问题 bla bla bla,我们进行了破解来解决这些问题,但我们需要知道这是否是越狱设备,请按此处以便应用程序解决问题。如果您恢复正常,即删除越狱,请按此处。

然后你处理用户交互并做适当的事情,比如表现不同等......

于 2012-09-13T09:27:13.923 回答
3

尝试查找 cydia 或越狱设备创建的文件。或者尝试在应用程序黑盒之外的文件中写入。如果您成功执行此操作,则该设备已被盗用/越狱 :)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
于 2013-05-14T08:14:17.670 回答
1

这是我的解决方案: 第 1 步

extension UIDevice {
    func isJailBroken() -> Bool {
        let cydiaPath = "/Applications/Cydia.app"
        let aptPath = "/private/var/lib/apt/"
        if FileManager.default.fileExists(atPath: cydiaPath) || FileManager.default.fileExists(atPath: aptPath) {
            return true
        }
        return false
    }
}

第 2 步:viewDidLoad()在您的启动屏幕视图控制器(或您第一次调用的任何 VC)内部调用它:

       // show a blank screen or some other view controller
       let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
       self.navigationController?.present(viewController, animated: true, completion:nil)
于 2018-06-01T13:04:14.607 回答
1

在 iOS 14 中有一个服务App Attest。检查这篇文章

我也使用了这个 repo https://github.com/fiber-inc/SecurityDetector,但是有些用户告诉他们,当检测器触发时,他们没有越狱。

所以我决定测试这个 repo https://github.com/wearebeatcode/SwiftJailbreakDetection/blob/master/Sources/SwiftJailbreakDetection/JailbreakDetection.swift。算法仍然不好,并给出越狱活动在未越狱手机中的结果。进一步搜索..

现在我正在尝试这个:https ://github.com/securing/IOSSecuritySuite

于 2020-12-02T21:41:56.177 回答
-2

尝试访问 /Application/Preferences.app/General.plist 你应该可以在越狱的 iPhone 上这样做 在非 Jb 手机上你将无法访问它

于 2012-06-09T10:28:42.220 回答