Se voglio che la mia app si comporti in modo diverso su un iPhone con jailbreak, come farei per determinarlo?
Se voglio che la mia app si comporti in modo diverso su un iPhone con jailbreak, come farei per determinarlo?
Risposte:
Dipende da cosa intendi per jailbreak. Nel caso semplice, dovresti essere in grado di vedere se Cydia è installato e andare avanti così - qualcosa del genere
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
Per i kernel compromessi, è un po '(molto) più coinvolto.
fileExistsAtPath:
e farlo tornare NO
per il percorso specifico che si controlla.
Questo è un codice che combina alcune risposte che ho trovato per questa esigenza e ti darà un tasso di successo molto più alto:
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];
}
Il controllo del percorso del file /Applications/Cydia.app
non è consentito su un telefono normale? Non ho mai sentito parlare di Apple che rileva questo e rifiuta un'app per esso, ma Apple è imprevedibile. Cydia ha uno schema URL cydia: // che può essere verificato legalmente con UIApplicationcanOpenURL:
Controllare se il kernel è rotto non è molto più coinvolto.
Il jailbreak fa in modo che il controllo della firma del kernel del codice firmato riferisca sempre che il codice è firmato correttamente, i telefoni ininterrotti non possono eseguire il codice con una firma errata.
Quindi, includere un eseguibile separato nell'app con una firma non valida. Potrebbe essere solo un programma a 3 righe con main () e un valore di ritorno. Compilare l'eseguibile senza la firma del codice (disattivarlo in Impostazioni progetto-> Crea) e firmarlo con una chiave diversa utilizzando l'utilità della riga di comando "codesign".
Chiedi alla tua app di eseguire l'eseguibile separato. Se il tuo programma non è in grado di ottenere il valore restituito durante l'esecuzione dell'eseguibile separato con il bad sign, è sicuramente imprigionato. Se l'eseguibile separato restituisce A-OK, il telefono è sicuramente 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
}
È possibile rilevare se un dispositivo è JailBroken o meno verificando quanto segue:
C'è una biblioteca open source che ho creato da vari articoli e libri. Provalo su GitHub !
Ho rielaborato in Swift 2.3 la soluzione fornita da @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
}
Il metodo più sofisticato che conosco sta usando la objc_copyImageNames()
funzione. Restituisce un elenco delle librerie attualmente caricate e poiché la maggior parte delle persone ha MobileSubstrate su dispositivi jailbroken e la maggior parte degli strumenti di crack iAP dipendono da esso, almeno alcune librerie MobileSubstrate verranno visualizzate.
deb
file di MobileSubstrate, decomprimerlo e inserire nella blacklist (quasi) tutto pronto .dylib
.
Non sono a conoscenza di alcuna "API" esistente per questo. Se ci fosse, allora un prodotto di mascheramento del jailbreak li coprirebbe rapidamente.
Come molte persone sottolineano, è un gioco gatto e topo. E dopo che entrambi i giocatori diventano esperti, tutto dipende da chi ottiene la prima mossa. (Persona che detiene il dispositivo.)
Ho trovato molti buoni suggerimenti per rilevare il jailbreak nel nuovo libro di Zdziarski "Hacking and Securing iOS Apps". (Personalmente, ho pagato di più per l'eBook O'Reilly perché mi permettono di copiare e incollare.)
No, non sono affiliato con gli editori. Ma l'ho trovato un buon libro. Non mi piace solo pubblicare gli errori degli hacker in modo che possano risolverli, quindi ho pensato di indicare il libro.
Prova a eseguire codice non firmato tramite l'applicazione.
Un dispositivo jailbroken di solito ha le seguenti caratteristiche:
Il solo controllo dell'esistenza del file per il rilevamento del jailbreak è destinato a fallire. Questi controlli sono facili da aggirare.
Alcuni file comuni da verificare per:
/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 maggior parte controlla i file correlati a Cydia.
Suggerirei di cercare file che non sono presenti su un iPhone "vaniglia". Tutti i kit di jailbreak che ho visto installare ssh. Potrebbe essere un buon indicatore di un telefono con jailbreak.
Quello che abbiamo fatto è che abbiamo già un feed RSS per comunicare con i nostri utenti ( Azioni in diretta ), abbiamo messo un articolo di notizie che afferma qualcosa del genere:
Alcuni dispositivi jailbroken hanno problemi bla bla bla, abbiamo fatto un hack per risolvere quei problemi ma dobbiamo sapere se si tratta di un dispositivo jailbreak o no, premi qui in modo che l'app risolva il problema. Se dovessi tornare alla normalità, ad esempio rimosso il jailbreak, premi qui.
Quindi elabori l'interazione dell'utente e fai ciò che è appropriato, come comportarti in modo diverso, ecc ...
Prova a trovare un file creato da Cydia o dispositivo jailbreak. Oppure prova a scrivere in un file esterno alla blackbox dell'app. Se riesci a farlo, il dispositivo è compromesso / jailbreak :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Utilizzare il codice seguente per Swift 4 e versioni successive: Aggiungere il codice seguente nel delegato dell'app:
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()
}
}
}
}
Ecco le mie soluzioni: passaggio 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
}
}
Passaggio 2: chiamalo viewDidLoad()
all'interno del controller di visualizzazione della schermata di avvio (o qualunque VC chiami per la prima volta):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Prova ad accedere /Application/Preferences.app/General.plist Dovresti essere in grado di farlo su un iPhone con jailbreak Su un telefono non Jb non sarai in grado di accedervi