Si je souhaite que mon application se comporte différemment sur un iPhone jailbreaké, comment procéder pour le déterminer?
Si je souhaite que mon application se comporte différemment sur un iPhone jailbreaké, comment procéder pour le déterminer?
Réponses:
Cela dépend de ce que vous entendez par jailbreak. Dans le cas simple, vous devriez pouvoir voir si Cydia est installé et passer 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 (beaucoup) plus compliqué.
fileExistsAtPath:
et le faire revenir NO
pour le chemin spécifique que vous vérifiez.
C'est un code qui combine quelques réponses que j'ai trouvées pour ce besoin, et 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;
}
isJailbroken
+(BOOL)isJailbroken {
NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
return [[UIApplication sharedApplication] canOpenURL:url];
}
La vérification du chemin du fichier /Applications/Cydia.app
n'est pas autorisée sur un téléphone normal? Je n'ai jamais entendu parler d'Apple détectant cela et rejetant une application pour cela, mais Apple est imprévisible. Cydia a un schéma d'URL cydia: // qui peut être vérifié légalement avec UIApplicationcanOpenURL:
Vérifier si le noyau est cassé n'est pas tellement plus compliqué.
Le jailbreaking fait que la vérification de la signature du noyau du code signé signale toujours que le code est signé correctement, les téléphones ininterrompus ne peuvent pas exécuter de code avec une mauvaise signature.
Donc, incluez 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 signature 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 le mauvais sig, il est définitivement emprisonné. Si l'exécutable séparé renvoie A-OK, le téléphone est définitivement jailbreaké.
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
}
Vous pouvez détecter si un appareil est JailBroken ou non en vérifiant les éléments suivants:
Il existe une bibliothèque open source que j'ai créée à partir de divers articles et livres. Essayez-le sur GitHub !
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
}
La méthode la plus sophistiquée que je connaisse utilise la objc_copyImageNames()
fonction. Il renvoie une liste des bibliothèques actuellement chargées et comme la plupart des gens ont MobileSubstrate sur des appareils jailbreakés et que la plupart des outils de crack iAP en dépendent, au moins certaines bibliothèques MobileSubstrate apparaîtront.
deb
fichier de MobileSubstrate, le décompresser et la liste noire (presque) tout .dylib
est emballé.
Je n'ai connaissance d'aucune "API" qui existe pour cela. S'il y en avait, alors un produit de masquage de jailbreak les couvrirait rapidement.
Comme beaucoup de gens le soulignent, c'est un jeu du chat et de la souris. Et une fois que les deux joueurs sont devenus des experts, tout dépend de qui obtient le premier coup. (Personne tenant l'appareil.)
J'ai trouvé de nombreuses bonnes suggestions pour détecter le jailbreak dans le nouveau livre de Zdziarski "Hacking and Securing iOS Apps". (Personnellement, j'ai payé plus cher le livre électronique O'Reilly car ils permettent le copier-coller.)
Non, je ne suis pas affilié aux éditeurs. Mais j'ai trouvé que c'était un bon livre. Je n'aime pas simplement publier les erreurs des hackers pour qu'ils puissent les corriger, alors j'ai pensé que je voudrais pointer vers le livre.
Essayez d'exécuter du code non signé via votre application.
Un appareil jailbreaké a généralement les caractéristiques suivantes:
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.
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érifient les fichiers liés à Cydia.
Je suggère 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é.
Ce que nous avons fait, c'est que nous avons déjà un flux RSS pour communiquer avec nos utilisateurs ( Stocks Live ), nous mettons une actualité qui énonce quelque chose comme ceci:
Certains appareils jailbreakés ont des problèmes bla bla bla, nous avons fait un hack 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 jamais vous revenez à la normale, c'est-à-dire supprimez le jailbreak, appuyez ici.
Ensuite, vous traitez l'interaction de l'utilisateur et faites ce qui est approprié, comme un comportement différent, etc.
Essayez de trouver un fichier créé par cydia ou un appareil jailbreaké. Ou essayez d'écrire dans un fichier en dehors de la boîte noire de l'application. Si vous réussissez à le faire, l'appareil est compromis / jailbreaké :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Veuillez utiliser le code suivant pour Swift 4 et supérieur: Ajoutez le code suivant dans l'appdelegate:
private func getJailbrokenStatus() -> Bool {
if TARGET_IPHONE_SIMULATOR != 1 {
// Check 1 : existence of files that are common for jailbroken devices
if FileManager.default.fileExists(atPath: "/Applications/Cydia.app")
|| FileManager.default.fileExists(atPath: "/Library/MobileSubstrate/MobileSubstrate.dylib")
|| FileManager.default.fileExists(atPath: "/bin/bash")
|| FileManager.default.fileExists(atPath: "/usr/sbin/sshd")
|| FileManager.default.fileExists(atPath: "/etc/apt")
|| FileManager.default.fileExists(atPath: "/private/var/lib/apt/")
|| UIApplication.shared.canOpenURL(URL(string:"cydia://package/com.example.package")!) {
return true
}
// Check 2 : Reading and writing in system directories (sandbox violation)
let stringToWrite = "Jailbreak Test"
do {
try stringToWrite.write(toFile:"/private/JailbreakTest.txt", atomically:true, encoding:String.Encoding.utf8)
//Device is jailbroken
return true
} catch {
return false
}
}
else {
return false
}
}
func applicationDidBecomeActive (_ application: UIApplication) {
if getJailbrokenStatus() {
let alert = UIAlertController(title: LocalizedKeys.Errors.jailbreakError, message: LocalizedKeys.Errors.jailbreakErrorMessage, preferredStyle: UIAlertController.Style.alert)
let jailBrokenView = UIViewController()
jailBrokenView.view.frame = UIScreen.main.bounds
jailBrokenView.view.backgroundColor = .white
self.window?.rootViewController = jailBrokenView
jailBrokenView.present(alert, animated: true, completion: nil)
}
if #available(iOS 11.0, *) {
if !UIScreen.main.isCaptured {
DispatchQueue.main.async {
self.blockImageView.removeFromSuperview()
}
}
}
}
Voici mes solutions: Étape 1
extension UIDevice {
func isJailBroken() -> Bool {
let cydiaPath = "/Applications/Cydia.app"
let aptPath = "/private/var/lib/apt/"
if FileManager.default.fileExists(atPath: cydiaPath) || FileManager.default.fileExists(atPath: aptPath) {
return true
}
return false
}
}
Étape 2: Appelez-le à l' viewDidLoad()
intérieur de votre contrôleur de vue d'écran de lancement (ou quel que soit le VC que vous appelez pour la première fois):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Essayez d'accéder à /Application/Preferences.app/General.plist Vous devriez pouvoir le faire sur un iPhone jailbreaké Sur un téléphone non Jb, vous ne pourrez pas y accéder