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

Ben*_*ieb 162 iphone jailbreak ios

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

wis*_*ark 85

这取决于越狱的意思.在简单的情况下,您应该能够看到Cydia是否已经安装并且可以通过它来实现

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

对于被黑客攻击的内核,它涉及的内容有点多(很多).

  • 请注意,并非所有用户都安装了Cydia - 这不是一个好的检查,你应该检查/ bin/bash/all/users/will/have. (57认同)
  • 在沙箱外寻找_any_ file/dir是不够的?喜欢/ etc? (17认同)
  • apt会在哪里存储其信息?或者我可以只调用system()命令并找出答案。我想知道他们是否有某些应用程序,是否有它们,然后限制该应用程序 (2认同)
  • @RazorSharp此时,几乎所有用户都拥有Cydia.现在可能已经足够检查了.但是,如果您想要100%可靠的检查,您将需要使用基于内核的检查,如下所示. (2认同)

小智 54

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

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

  • 对于iOS9.0 +,您还需要在app plist中添加LSApplicationQueriesSchemes键.否则canOpenURL将始终返回false. (7认同)

Yos*_*ssi 53

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 此方法应该是内联的C函数,*不是*Objective-C.发现并绕过Objective-C方法太容易了,特别是如果你称之为`isJailbroken` (4认同)
  • @yossi和porizm apple批准了包含上述代码的应用程序?请回复 (3认同)
  • @Lakshay我不知道..你被邀请检查并在这里添加答案:) (3认同)
  • @Yossi不使用Taig越狱此盖设备? (2认同)

小智 51

检查内核是否坏了不是更多涉及.

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

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

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

  • 事情可能已经改变但是不会执行单独的可执行文件会阻止您被批准进入应用程序商店? (34认同)
  • 你能获得一个(子)可执行文件,其签名无效,就像通过App Store一样吗? (13认同)
  • 有人可以回答之前的评论吗?这是重要的问题. (4认同)

Ric*_*III 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
}
Run Code Online (Sandbox Code Playgroud)

  • @AlexeiRobsky没有完美的解决方案.永远都会有人找到绕过保护的方法,这只是一个事实. (7认同)

小智 14

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

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

我从各种文章和书籍中创建了一个开源库.在GitHub上试一试!


Ale*_*eda 13

我在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
}
Run Code Online (Sandbox Code Playgroud)


Max*_*han 6

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


小智 5

对于 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
    }
}
Run Code Online (Sandbox Code Playgroud)

在 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()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)