web-dev-qa-db-fra.com

Comment détecter une application iOS en cours d'exécution sur un téléphone jailbreaké?

Si je veux que mon application se comporte différemment sur un iPhone jailbreaké, comment pourrais-je déterminer cela?

151
Ben Gottlieb

Cela dépend de ce que vous entendez par jailbreak. Dans le cas simple, vous devriez être capable de voir si Cydia est installé et aller par là - quelque chose comme

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

Pour les noyaux piratés, c'est un peu plus impliqué.

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

Vérifier le chemin du fichier /Applications/Cydia.app n'est pas autorisé sur un téléphone normal? Je n'ai jamais entendu parler d'Apple avoir détecté cela et rejeté une application, mais Apple est imprévisible. Cydia a un schéma d'URL cydia: // qui peut être vérifié légalement avec UIApplication canOpenURL: 

54
Mark Johnson

Vérifier si le noyau est cassé n'est pas beaucoup plus compliqué.

Jailbreaking fait que la vérification de la signature du code signé par le noyau indique toujours que le code est signé correctement, les téléphones non cassés ne peuvent pas exécuter de code avec une signature incorrecte.

Donc, inclure un exécutable séparé dans l'application avec une mauvaise signature. Ce pourrait être juste un programme de 3 lignes qui a main () et une valeur de retour. Compilez l'exécutable sans signer de code (désactivez-le dans Paramètres du projet -> Construire) et signez-le avec une clé différente à l'aide de l'utilitaire de ligne de commande "codesign".

Demandez à votre application d'exécuter l'exécutable séparé. Si votre programme ne peut pas obtenir la valeur de retour lors de l'exécution de l'exécutable séparé avec la mauvaise signature, il est définitivement jailed. Si l'exécutable séparé renvoie A-OK, le téléphone est définitivement jailbreaké.

51
GregH

C’est un code qui combine certaines des réponses que j’ai trouvées pour répondre à ce besoin et qui vous donnera un taux de réussite beaucoup plus élevé:

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;
}
48
Yossi
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
}
19

Vous pouvez détecter si un périphérique est bloqué ou non en vérifiant les éléments suivants:

  • Cydia est installé 
  • Vérifier certains des chemins du système 
  • Effectuer une vérification de l'intégrité du bac à sable 
  • Effectuer la vérification des liens symboliques 
  • Vérifiez si vous créez et écrivez des fichiers en dehors de votre bac à sable 

J'ai créé une bibliothèque open source à partir de divers articles et livres. Essayez-le sur GitHub !

14
user3088680

J'ai retravaillé dans Swift 2.3 la solution fournie par @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
}
10
Alex Peda

La méthode la plus sophistiquée que je connaisse utilise la fonction objc_copyImageNames(). Il retourne une liste des bibliothèques actuellement chargées et, comme la plupart des gens utilisent MobileSubstrate sur des périphériques jailbreakés et que la plupart des outils de crack iAP en dépendent, au moins certaines bibliothèques MobileSubstrate s'afficheront.

6
Maxthon Chan

Essayez d’exécuter du code non signé via votre application.

Un appareil jailbreaké a généralement les caractéristiques suivantes:

  • exécuter du code non signé
  • a Cydia installé
  • a des fichiers de jailbreak
  • accès r/w complet à l'ensemble du système de fichiers
  • certains fichiers système auront été modifiés (le contenu et donc sha1 ne correspond pas aux fichiers d'origine)
  • collé à une version spécifique (version jailbreakable)

Le simple fait de vérifier l’existence d’un fichier pour la détection de jailbreak est voué à l’échec . Ces contrôles sont faciles à contourner.

4
kurapix

Ce que nous avons fait est que nous avons déjà un flux RSS pour communiquer avec nos utilisateurs ( Stocks Live ), nous avons mis une nouvelle qui indique quelque chose comme ceci:

Certains appareils jailbreakés ont des problèmes bla bla bla, nous avons fait un bidouillage pour résoudre ces problèmes, mais nous devons savoir s'il s'agit d'un appareil jailbreaké ou non, appuyez ici pour que l'application corrige le problème. Si vous revenez à la normale, c’est-à-dire que vous avez supprimé le jailbreak, appuyez ici.

Ensuite, vous traitez l’interaction de l’utilisateur et faites ce qui est approprié, comme se comporter différemment, etc.

3
Ilam

Essayez de trouver un fichier créé par cydia ou un périphérique jailbreaké. Ou essayez d'écrire dans un fichier en dehors de la boîte noire de l'application. Si vous réussissez à faire cela, l'appareil est compromis/jailbreaké :)

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

Je ne suis au courant d'aucune "API" qui existe pour cela. S'il en existait, un produit masquant le jailbreak les recouvrirait rapidement.

Comme beaucoup de gens le soulignent, il s’agit d’un jeu de chat et de souris. Et après que les deux joueurs deviennent experts, tout se résume à qui obtient le premier coup. (Personne qui tient l'appareil.)

J'ai trouvé beaucoup de bonnes suggestions pour détecter le jailbreak dans le nouveau livre de Zdziarski "Piratage et sécurisation d'applications iOS". (Personnellement, j'ai payé plus pour le livre électronique O'Reilly, car ils autorisent le copier-coller.)

Non, je ne suis pas affilié aux éditeurs. Mais j'ai trouvé un bon livre. Je n'aime pas simplement publier les erreurs des pirates pour qu'ils puissent les réparer, alors j'ai pensé pointer vers le livre.

3
Walt Sellers

Quelques fichiers courants à vérifier: /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

La plupart vérifie les fichiers liés à Cydia.

3
DevC

Je suggérerais de rechercher des fichiers qui ne sont pas présents sur un iPhone "Vanilla". Tous les kits de jailbreak que j'ai vus installent ssh. Cela pourrait être un bon indicateur d'un téléphone jailbreaké.

3
Gordon Wilson

Vous allez suivre une cible en mouvement, mais vous pouvez essayer de suivre la progression de ces ressources pour voir l'efficacité de votre technique:

1
Michael Bishop

Heres mes solutions:

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

et appelez-le dans viewDidLoad() dans votre contrôleur de vue d'écran de lancement (ou le VC vous appelez pour la première fois):

    if UIDevice.current.isJailBroken() {
       // show a blank screen or some other view controller
       let jailbreakVC = JailBrokenViewController()
       self.navigationController?.present(jailbreakVC, animated: true, completion:nil)
    } else {
     // continue executing your next View controller
     let nextVC = NextViewController()
     self.navigationController?.present(nextVC, animated: true, completion:nil)
    }
0
imaginae