如何检测iOS应用程序是否已在越狱手机上运行?

时间:2009-01-05 14:23:12

标签: ios iphone jailbreak

如果我希望我的应用在越狱的iPhone上表现不同,我该如何判断?

19 个答案:

答案 0 :(得分:84)

这取决于越狱的意思。在简单的情况下,你应该能够看到Cydia是否已经安装并且通过它 - 比如

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

对于被黑客攻击的内核,它会涉及更多(很多)。

答案 1 :(得分:54)

+(BOOL)isJailbroken {
    NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
    return [[UIApplication sharedApplication] canOpenURL:url];
}

普通手机上不允许检查文件路径/Applications/Cydia.app吗?我从来没有听说过Apple检测到这个并且拒绝了它的应用程序,但Apple是不可预测的。 Cydia有a URL scheme cydia://,可以使用UIApplication canOpenURL:

合法检查

答案 2 :(得分:51)

检查内核是否损坏不是那么多了。

越狱使内核对签名代码的签名检查始终报告代码已正确签名,不间断的手机无法运行带有错误签名的代码。

因此,在应用程序中包含一个带有错误签名的单独可执行文件。它可能只是一个具有main()和返回值的3行程序。编译可执行文件而不进行代码签名(在Project Settings-> Build中将其关闭),并使用“codesign”命令行实用程序使用其他密钥对其进行签名。

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

答案 3 :(得分:51)

这是一个代码,它结合了我为此需求找到的一些答案,并将为您提供更高的成功率:

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

答案 4 :(得分: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
}

答案 5 :(得分:14)

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

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

我从各种文章和书籍中创建了一个开源库。 Try it out on GitHub

答案 6 :(得分:12)

我在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
}

答案 7 :(得分:6)

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

答案 8 :(得分:4)

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

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

  • 运行未签名的代码
  • 安装了Cydia
  • 有越狱档案
  • 完整的r / w访问整个文件系统
  • 某些系统文件将被修改(内容,因此sha1与原始文件不匹配)
  • 坚持特定版本(越狱版)

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

答案 9 :(得分: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相关文件。

答案 10 :(得分:4)

我不知道存在任何“API”。如果有,那么越狱掩盖的产品会迅速掩盖它们。

很多人都指出,这是一场猫捉老鼠的比赛。在两位球员成为专家之后,这一切都取决于谁获得了第一步。 (拿着设备的人。)

我在Zdziarski的新书“黑客攻击和保护iOS应用程序”中找到了很多关于检测越狱的好建议。 (就个人而言,我为O'Reilly电子书支付了更多费用,因为它们允许复制和粘贴。)

不,我与发布商没有任何关系。但我确实觉得这本书很好。我不喜欢发布黑客的错误,所以他们可以解决它们,所以我想我会指向这本书。

答案 11 :(得分:3)

我建议寻找“香草”iPhone上没有的文件。我见过的所有越狱套件都安装了ssh。这可能是越狱电话的一个很好的指标。

答案 12 :(得分:3)

尝试查找cydia或越狱设备创建的文件。或者尝试在应用程序的黑盒子外写一个文件。如果您成功执行此操作,设备将遭到入侵/越狱:)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}

答案 13 :(得分:3)

我们所做的是,我们已经有一个RSS提要与我们的用户进行沟通(Stocks Live),我们提出了一个类似这样的新闻:

  

一些越狱设备存在问题,我们做了一个黑客来解决这些问题,但我们需要知道这是否是一个越狱设备,请按此处,以便应用程序解决问题。如果你恢复正常,即取消越狱,请按此处。

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

答案 14 :(得分:1)

您将关注移动目标,但您可以尝试关注这些资源的进展情况,以了解您的技术效果如何:

答案 15 :(得分:1)

对于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
    }
}

func applicationDidBecomeActive(_应用程序: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()
            }
        }
    }
}

答案 16 :(得分:0)

继承我的解决方案:

public $timestamps = true;

并在启动屏幕视图控制器(或您第一次呼叫的任何VC)内的extension UIDevice { func isJailBroken() -> Bool { var jailBroken = false let cydiaPath = "/Applications/Cydia.app" let aptPath = "/private/var/lib/apt/" if FileManager.default.fileExists(atPath: cydiaPath) { jailBroken = true } if FileManager.default.fileExists(atPath: aptPath) { jailBroken = true } return jailBroken } } 内调用它:

viewDidLoad()

答案 17 :(得分:0)

在iOS 14中,有一项服务 App Attest 。选中此article

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

因此,我决定测试此仓库https://github.com/wearebeatcode/SwiftJailbreakDetection/blob/master/Sources/SwiftJailbreakDetection/JailbreakDetection.swift。该算法仍然不好,并且导致越狱在未越狱的手机中处于活动状态。正在进一步搜索。

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

答案 18 :(得分:-2)

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