¿Cómo puedo detectar que una aplicación de iOS se esté ejecutando en un teléfono liberado?

Si quiero que mi aplicación se comporte de manera diferente en un iPhone con jailbreak, ¿cómo voy a determinar esto?

Depende de lo que quieras decir con jailbreak. En el caso simple, debería poder ver si Cydia está instalado y usarlo, algo así como

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

Para kernels pirateados, es un poco (mucho) más complicado.

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

Comprobar la ruta del archivo / /Applications/Cydia.app no está permitido en un teléfono normal. Nunca escuché que Apple detecta esto y rechaza una aplicación, pero Apple es impredecible. Cydia tiene un esquema de URL cydia: // que se puede verificar legalmente con UIApplication canOpenURL:

Comprobar si el kernel está roto no es mucho más complicado.

Jailbreaking hace que la verificación de firma del kernel del código firmado siempre informe que el código está firmado correctamente, los teléfonos intactos no pueden ejecutar código con una firma incorrecta.

Por lo tanto, incluye un ejecutable por separado en la aplicación con una mala firma. Podría ser simplemente un progtwig de 3 líneas que tenga main () y un valor de retorno. Compile el ejecutable sin la firma del código (desactívelo en Configuración del proyecto-> Construir) y fírmelo con una clave diferente usando la utilidad de línea de comandos “codesign”.

Haga que su aplicación ejecute el ejecutable por separado. Si su progtwig no puede obtener el valor de retorno cuando ejecuta el ejecutable separado con la sig mala, definitivamente está encarcelado. Si el ejecutable por separado devuelve A-OK, el teléfono definitivamente tiene jailbreak.

Este es un código que combina algunas respuestas que encontré para esta necesidad, y le dará una tasa de éxito mucho mayor:

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

Puede detectar si un dispositivo es JailBroken o no, verificando lo siguiente:

  • Cydia está instalado
  • Verificar algunas de las rutas del sistema
  • Realice un control de integridad de sandbox
  • Realizar la verificación de enlace simbólico
  • Verifique si crea y escribe archivos fuera de su Sandbox

Hay una biblioteca de código abierto que he creado a partir de varios artículos y libros. Pruébalo en GitHub !

Retrabajé en Swift 2.3 la solución provista por @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 } 

El método más sofisticado que conozco es usar la función objc_copyImageNames() . Devuelve una lista de las bibliotecas cargadas actualmente y, como la mayoría de las personas tiene MobileSubstrate en los dispositivos con jailbreak y la mayoría de las herramientas de crack de iAP dependen de él, al menos aparecerán algunas bibliotecas de MobileSubstrate.

Sugeriría buscar archivos que no están presentes en un iPhone “vanilla”. Todos los kits jailbreak que he visto instalan ssh. Eso podría ser un buen indicador de un teléfono con jailbreak.

Intenta encontrar un archivo creado por cydia o por jailbreak. O intente escribir en un archivo fuera de la caja negra de la aplicación. Si logras hacer eso, el dispositivo está en peligro / jailbroken 🙂

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

Intenta ejecutar código sin firmar a través de tu aplicación.

Un dispositivo jailbroken generalmente tiene las siguientes características:

  • ejecutar código sin firmar
  • tiene Cydia instalado
  • tiene archivos jailbreak
  • acceso r / w completo a todo el sistema de archivos
  • algunos archivos del sistema se habrán modificado (contenido y, por lo tanto, sha1 no coincide con los archivos originales)
  • pegado a la versión específica (versión jailbreakable)

Solo verificar la existencia del archivo para la detección de jailbreak está condenado al fracaso. Estos controles son fáciles de eludir.

No tengo conocimiento de ninguna “API” que exista para esto. Si lo hubiera, entonces un producto de enmascaramiento de jailbreak los cubriría rápidamente.

Como muchas personas señalan, es un juego del gato y el ratón. Y después de que ambos jugadores se vuelvan expertos, todo se reduce a quién consigue el primer movimiento. (Persona que sostiene el dispositivo)

Encontré muchas buenas sugerencias para detectar el jailbreak en el nuevo libro de Zdziarski “Hacking and Securing iOS Apps”. (Personalmente, pagué más por el libro electrónico O’Reilly porque permiten copiar y pegar).

No, no estoy afiliado a los editores. Pero lo encontré un buen libro. No me gusta simplemente publicar los errores de los hackers para que puedan arreglarlos, así que pensé en señalar el libro.

Lo que hicimos es que ya tenemos un feed RSS para comunicarnos con nuestros usuarios ( Stocks Live ), colocamos una noticia que dice algo como esto:

Algunos dispositivos liberados tienen problemas bla bla bla, hicimos un truco para resolver esos problemas, pero necesitamos saber si este es un dispositivo con jailbreak o no, presione aquí para que la aplicación solucione el problema. Si alguna vez vuelve a la normalidad, es decir, elimina el jailbreak, presione aquí.

Luego, procesa la interacción del usuario y hace lo que es apropiado, como comportarse diferente, etc.

Algunos archivos comunes para verificar: /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 mayoría busca los archivos relacionados con Cydia.

Seguirá un objective móvil, pero puede intentar seguir el progreso de estos recursos para ver qué tan efectiva es su técnica:

Heres mis soluciones:

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

y llámalo dentro de viewDidLoad() dentro de tu controlador de vista de pantalla de inicio (o cualquier VC que estés llamando por primera vez):

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

Intente acceder a /Application/Preferences.app/General.plist Debería poder hacerlo en un iPhone con jailbreak En un teléfono que no sea Jb no podrá acceder a él