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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/413242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:29:49  来源:igfitidea点击:

How do I detect that an iOS app is running on a jailbroken phone?

iosiphonejailbreak

提问by Ben Gottlieb

If I want my app to behave differently on a jailbroken iPhone, how would I go about determining this?

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

采纳答案by wisequark

It depends what you mean by jailbreak. In the simple case, you should be able to see if Cydia is installed and go by that - something like

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

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

For hacked kernels, it's a little (lot) more involved.

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

回答by Yossi

This is a code that combine some answers I found for this need, and will give you much higher success rate :

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

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

回答by Mark Johnson

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

Checking the file path /Applications/Cydia.appis not allowed on a normal phone? I've never heard of Apple detecting this and rejecting an app for it, but Apple is unpredictable. Cydia has a URL scheme cydia://which can be legally checked with UIApplication canOpenURL:

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

回答by GregH

Checking if the kernel is broken isn't THAT much more involved.

检查内核是否损坏并没有那么复杂。

Jailbreaking makes the kernel's signature check of signed code always report that code is signed correctly, unbroken phones cannot run code with a bad signature.

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

So, include a separate executable in the app with a bad signature. It could just be a 3-line program that has main() and a return value. Compile the executable without code signing (turn it off in Project Settings->Build) and sign it with a different key using the "codesign" commandline utility.

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

Have your app exec the separate executable. If your program can't get the return value when running the separate executable with the bad sig, it's definitely jailed. If the separate executable returns A-OK, the phone is definitely jailbroken.

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

回答by Richard J. Ross III

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
}

回答by Alex Peda

I reworked in Swift 2.3 the solution provided by @Yossi

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

回答by user3088680

You can detect if a device is JailBroken or not by checking for the following:

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

  • Cydia is installed
  • Verify some of the system paths
  • Perform a sandbox integrity check
  • Perform symlink verification
  • Verify whether you create and write files outside your Sandbox
  • Cydia 已安装
  • 验证一些系统路径
  • 执行沙箱完整性检查
  • 执行符号链接验证
  • 验证您是否在沙箱外创建和写入文件

There is an open source library I created from various articles and books. Try it out on GitHub!

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

回答by Maxthon Chan

The most sophisticated method I know is using objc_copyImageNames()function. It returns a list of currently loaded libraries and since most people have MobileSubstrate on jailbroken devices and most iAP crack tools depend on it, at least some MobileSubstrate libraries will show up.

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

回答by kurapix

Try executing unsigned code through your application.

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

A jailbroken devices usually has the following characteristics:

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

  • run unsigned code
  • has Cydia installed
  • has jailbreak files
  • full r/w access to the whole filesystem
  • some system files will have been modified (content and so sha1 doesn't match with original files)
  • stuck to specific version (jailbreakable version)
  • 运行未签名的代码
  • 安装了 Cydia
  • 有越狱文件
  • 对整个文件系统的完全 r/w 访问
  • 一些系统文件将被修改(内容等 sha1 与原始文件不匹配)
  • 坚持特定版本(越狱版本)

Just checking file existence for jailbreak detection is doomed to fail. These checks are easy to bypass.

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

回答by DevC

Some common files to check for: /Library/MobileSubstrate/MobileSubstrate.dylib

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

/Applications/Cydia.app

/Applications/Cydia.app

/var/cache/apt

/var/cache/apt

/var/lib/apt

/var/lib/apt

/var/lib/cydia

/var/lib/cydia

/var/log/syslog

/var/log/syslog

/var/tmp/cydia.log

/var/tmp/cydia.log

/bin/bash

/bin/bash

/bin/sh

/bin/sh

/usr/sbin/sshd

/usr/sbin/sshd

/usr/libexec/ssh-keysign

/usr/libexec/ssh-keysign

/etc/ssh/sshd_config

/etc/ssh/sshd_config

/etc/apt

/etc/apt

Most check for Cydia related files.

大多数检查 Cydia 相关文件。