Wenn ich möchte, dass sich meine App auf einem iPhone mit Jailbreak anders verhält, wie würde ich dies feststellen?
Wenn ich möchte, dass sich meine App auf einem iPhone mit Jailbreak anders verhält, wie würde ich dies feststellen?
Antworten:
Es kommt darauf an, was du mit Jailbreak meinst. Im einfachen Fall sollten Sie in der Lage sein zu sehen, ob Cydia installiert ist, und danach vorgehen - so etwas wie
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
Für gehackte Kernel ist es etwas (viel) komplizierter.
fileExistsAtPath:
um es einzuhaken und NO
für den spezifischen Pfad, den Sie überprüfen, zurückzukehren.
Dies ist ein Code, der einige Antworten kombiniert, die ich für diesen Bedarf gefunden habe, und der Ihnen eine viel höhere Erfolgsquote bietet:
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];
}
Das Überprüfen des Dateipfads /Applications/Cydia.app
ist auf einem normalen Telefon nicht zulässig? Ich habe noch nie davon gehört, dass Apple dies erkannt und eine App dafür abgelehnt hat, aber Apple ist unvorhersehbar. Cydia hat ein URL-Schema cydia: //, das mit UIApplication legal überprüft werden kanncanOpenURL:
Zu überprüfen, ob der Kernel defekt ist, ist nicht viel komplizierter.
Durch Jailbreaking wird bei der Signaturprüfung des Kernels für signierten Code immer gemeldet, dass der Code korrekt signiert ist. Auf nicht unterbrochenen Telefonen kann kein Code mit einer schlechten Signatur ausgeführt werden.
Fügen Sie daher eine separate ausführbare Datei mit einer schlechten Signatur in die App ein. Es könnte nur ein dreizeiliges Programm sein, das main () und einen Rückgabewert hat. Kompilieren Sie die ausführbare Datei ohne Codesignatur (deaktivieren Sie sie unter Projekteinstellungen-> Erstellen) und signieren Sie sie mit einem anderen Schlüssel mit dem Befehlszeilenprogramm "Codesign".
Lassen Sie Ihre App die separate ausführbare Datei ausführen. Wenn Ihr Programm beim Ausführen der separaten ausführbaren Datei mit dem fehlerhaften Sig den Rückgabewert nicht erhalten kann, ist es definitiv inhaftiert. Wenn die separate ausführbare Datei A-OK zurückgibt, ist das Telefon definitiv jailbroken.
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
}
Sie können feststellen, ob ein Gerät JailBroken ist oder nicht, indem Sie Folgendes überprüfen:
Es gibt eine Open-Source-Bibliothek, die ich aus verschiedenen Artikeln und Büchern erstellt habe. Probieren Sie es auf GitHub aus !
Ich habe in Swift 2.3 die von @Yossi bereitgestellte Lösung überarbeitet
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
}
Die ausgefeilteste Methode, die ich kenne, ist die Verwendung von objc_copyImageNames()
Funktionen. Es gibt eine Liste der aktuell geladenen Bibliotheken zurück. Da die meisten Benutzer MobileSubstrate auf Geräten mit Jailbreak haben und die meisten iAP-Crack-Tools davon abhängen, werden zumindest einige MobileSubstrate-Bibliotheken angezeigt.
deb
Datei von MobileSubstrate suchen, sie entpacken und (fast) alles auf .dylib
die schwarze Liste setzen , was sie gepackt hat.
Mir sind keine "APIs" bekannt, die dafür existieren. Wenn dies der Fall wäre, würde ein Produkt mit Jailbreak-Maskierung sie schnell verdecken.
Wie viele Leute betonen, handelt es sich um ein Katz-und-Maus-Spiel. Und nachdem beide Spieler Experten geworden sind, kommt es darauf an, wer den ersten Zug bekommt. (Person, die das Gerät hält.)
In Zdziarskis neuem Buch "Hacking and Securing iOS Apps" habe ich viele gute Vorschläge zur Erkennung von Jailbreak gefunden. (Ich persönlich habe mehr für das O'Reilly eBook bezahlt, weil sie das Kopieren und Einfügen ermöglichen.)
Nein, ich bin nicht mit dem Verlag verbunden. Aber ich fand es ein gutes Buch. Ich mag es nicht, nur die Fehler von Hackern zu veröffentlichen, damit sie sie beheben können, also dachte ich, ich würde auf das Buch verweisen.
Versuchen Sie, nicht signierten Code über Ihre Anwendung auszuführen.
Geräte mit Jailbreak weisen normalerweise die folgenden Eigenschaften auf:
Nur die Überprüfung der Existenz von Dateien auf Jailbreak-Erkennung ist zum Scheitern verurteilt. Diese Überprüfungen sind leicht zu umgehen.
Einige häufig verwendete Dateien, nach denen gesucht werden muss:
/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
Die meisten suchen nach Cydia-bezogenen Dateien.
Ich würde vorschlagen, nach Dateien zu suchen, die auf einem "Vanille" iPhone nicht vorhanden sind. Alle Jailbreak-Kits, die ich gesehen habe, installieren ssh. Das könnte ein guter Indikator für ein Telefon mit Jailbreak sein.
Wir haben bereits einen RSS-Feed für die Kommunikation mit unseren Benutzern ( Stocks Live ). Wir haben eine Nachricht veröffentlicht, die ungefähr so lautet:
Einige Geräte mit Jailbreak haben Probleme bla bla bla. Wir haben einen Hack durchgeführt, um diese Probleme zu lösen. Wir müssen jedoch wissen, ob dies ein Gerät mit Jailbreak ist oder nicht. Klicken Sie hier, damit die App das Problem behebt. Wenn Sie jemals wieder normal werden, dh den Jailbreak entfernt haben, klicken Sie hier.
Dann verarbeiten Sie die Benutzerinteraktion und tun, was angemessen ist, wie sich anders zu verhalten usw.
Versuchen Sie, eine Datei zu finden, die von einem Gerät mit Cydia- oder Jailbreak erstellt wurde. Oder versuchen Sie, in eine Datei außerhalb der Blackbox der App zu schreiben. Wenn Ihnen dies gelingt, ist das Gerät kompromittiert / jailbroken :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Bitte verwenden Sie folgenden Code für Swift 4 und höher: Fügen Sie den folgenden Code in das Appdelegate ein:
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()
}
}
}
}
Hier sind meine Lösungen: Schritt 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
}
}
Schritt 2: Rufen Sie es in viewDidLoad()
Ihrem Startbildschirm-View-Controller auf (oder in welcher VC auch immer Sie zum ersten Mal aufrufen):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Versuchen Sie, auf /Application/Preferences.app/General.plist zuzugreifen. Sie sollten dies auf einem iPhone mit Jailbreak tun können. Auf einem Telefon ohne JB können Sie nicht darauf zugreifen