iOS

iOS脱獄チェックメモ

とりあえずまるごとまとめたもの。
現在いろいろ脱獄端末を用意しつつ検証中

+(BOOL)isJailbroken{

#if !(TARGET_IPHONE_SIMULATOR)

    if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"]){
        return YES;
    }else if([[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"]){
        return YES;
    }else if([[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"]){
        return YES;
    }else if([[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"]){
        return YES;
    }else if([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"]){
        return YES;
    }

    NSError *error;
    NSString *stringToBeWritten = @"This is a test.";
    [stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if(error==nil){
        //Device is jailbroken
        return YES;
    } else {
        [[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil];
    }

    if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]){
        //Device is jailbroken
        return YES;
    }

    FILE *f = fopen("/bin/bash", "r");
    BOOL isJB = NO;
    if (f != NULL)
    {
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);
    f = fopen("/bin/ssh", "r");
    if ( f != NULL){
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);
    f = fopen("/Applications/Cydia.app", "r");
    if (f != NULL)
    {
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);
    f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r");
    if (f != NULL)
    {
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);
    f = fopen("/usr/sbin/sshd", "r");
    if (f != NULL)
    {
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);
    f = fopen("/etc/apt", "r");
    if (f != NULL)
    {
        //Device is jailbroken
        isJB = YES;
    }
    fclose(f);

    if(isJB) return YES;

    NSFileManager * fileManager = [NSFileManager defaultManager];
    if([fileManager fileExistsAtPath:@"/private/var/lib/apt/"]){
        //Device is jailbroken
        return YES;
    }
#endif

    //All checks have failed. Most probably, the device is not jailbroken
    return NO;
}

How do I detect that an iOS app is running on a jailbroken phone?
上記に記載されてたのを全部まとめてみただけのメモです。
脱獄していると中身を書き換えられる場合もあるので、関数名は'isRedColor'とかわからない系にしておくのがいいみたい。

検証

検証用コード(それぞれの項目に番号付与)

+ (BOOL)isJailbroken
{

#if !(TARGET_IPHONE_SIMULATOR)

    if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"]) {
//        return YES;
        NSLog(@"1");
    } //else
        if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Library/MobileSubstrate/MobileSubstrate.dylib"]) {
//        return YES;
        NSLog(@"2");
    } //else
        if ([[NSFileManager defaultManager] fileExistsAtPath:@"/bin/bash"]) {
//        return YES;
        NSLog(@"3");
    } //else
        if ([[NSFileManager defaultManager] fileExistsAtPath:@"/usr/sbin/sshd"]) {
//        return YES;
        NSLog(@"4");
    } //else
        if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt"]) {
//        return YES;
        NSLog(@"5");
    }

    NSError *error;
    NSString *stringToBeWritten = @"This is a test.";
    [stringToBeWritten writeToFile:@"/private/jailbreak.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if (error == nil) {
        // Device is jailbroken
//        return YES;
        NSLog(@"6");
    } else {
        [[NSFileManager defaultManager] removeItemAtPath:@"/private/jailbreak.txt" error:nil];
    }

    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) {
        // Device is jailbroken
//        return YES;
        NSLog(@"7");
    }

    FILE *f = fopen("/bin/bash", "r");
    BOOL isJB = NO;
    if (f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"8");
    }
    fclose(f);
    f = fopen("/bin/ssh", "r");
    if ( f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"9");
    }
    fclose(f);
    f = fopen("/Applications/Cydia.app", "r");
    if (f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"10");
    }
    fclose(f);
    f = fopen("/Library/MobileSubstrate/MobileSubstrate.dylib", "r");
    if (f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"11");
    }
    fclose(f);
    f = fopen("/usr/sbin/sshd", "r");
    if (f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"12");
    }
    fclose(f);
    f = fopen("/etc/apt", "r");
    if (f != NULL) {
        // Device is jailbroken
        isJB = YES;
        NSLog(@"13");
    }
    fclose(f);

    if (isJB) {
//        return YES;
        NSLog(@"14");
    }

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:@"/private/var/lib/apt/"]) {
        // Device is jailbroken
//        return YES;
        NSLog(@"15");
    }
#endif /* if !(TARGET_IPHONE_SIMULATOR) */

    // All checks have failed. Most probably, the device is not jailbroken
    return NO;
}

7: CydiaのURLスキームチェック

if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]])

URLスキームに関しては、脱獄する必要のない通常のアプリのURLスキームにcydiaが設定されていた場合引っかかるため、一般ユーザーも検知する可能性があるため脱獄チェックには向かない。

端末でのチェック結果

iPhone5S iOS 7.1.2 panguを使っての脱獄直後

BreakThrough⇒脱獄回避アプリ

項目 脱獄直後 脱獄専用アプリインストール BreakThrough
1 ×
2 ×
3 ×
4 × ×
5
6 × × ×
7 ×
8 ×
9 × × ×
10
11 ×
12 ×
13
14
15 ×