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

后端 未结 17 1317
情书的邮戳
情书的邮戳 2020-11-22 10:48

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

相关标签:
17条回答
  • 2020-11-22 11:23

    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

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

    0 讨论(0)
  • 2020-11-22 11:24
    +(BOOL)isJailbroken {
        NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
        return [[UIApplication sharedApplication] canOpenURL:url];
    }
    

    Checking the file path /Applications/Cydia.app is 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:

    0 讨论(0)
  • 2020-11-22 11:24

    I reworked in Swift 2.3 the solution provided by @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
    }
    
    0 讨论(0)
  • 2020-11-22 11:26

    I am not aware of any "APIs" that exist for this. If there were, then a jailbreak-masking product would quickly cover them up.

    As lots of people point out, it is a cat-and-mouse game. And after both players become expert, it all comes down to who gets the first move. (Person holding the device.)

    I found many good suggestions for detecting jailbreak in Zdziarski's new book "Hacking and Securing iOS Apps". (Personally, I paid more for the O'Reilly eBook because they permit copy-and-paste.)

    No, I am not affiliated with the publishers. But I did find it a good book. I don't like to just publish hackers' mistakes so they can fix them, so I thought I'd point to the book.

    0 讨论(0)
  • 2020-11-22 11:31

    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.

    0 讨论(0)
  • 2020-11-22 11:33

    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;
    }
    
    0 讨论(0)
提交回复
热议问题