Jeśli chcę, aby moja aplikacja zachowywała się inaczej na iPhonie po jailbreaku, jak mam to ustalić?
Jeśli chcę, aby moja aplikacja zachowywała się inaczej na iPhonie po jailbreaku, jak mam to ustalić?
Odpowiedzi:
To zależy, co masz na myśli mówiąc o jailbreak. W prostym przypadku powinieneś być w stanie sprawdzić, czy Cydia jest zainstalowana i przejść przez to - coś w stylu
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
W przypadku zhakowanych jąder jest to trochę (dużo) bardziej skomplikowane.
fileExistsAtPath:
i sprawić, że wróci NO
na określoną ścieżkę, którą sprawdzasz.
To jest kod, który łączy kilka odpowiedzi, które znalazłem na tę potrzebę, i zapewni znacznie wyższy wskaźnik sukcesu:
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];
}
Sprawdzanie ścieżki pliku /Applications/Cydia.app
nie jest dozwolone na zwykłym telefonie? Nigdy nie słyszałem, aby Apple to wykrył i odrzucił aplikację, ale Apple jest nieprzewidywalny. Cydia ma schemat adresu URL cydia: //, który można legalnie sprawdzić za pomocą aplikacji UIApplicationcanOpenURL:
Sprawdzenie, czy jądro jest zepsute, nie jest TAKIE dużo bardziej skomplikowane.
Jailbreaking sprawia, że jądro sprawdza podpis podpisanego kodu zawsze raportuje, że kod jest podpisany poprawnie, a nieprzerwane telefony nie mogą uruchamiać kodu ze złym podpisem.
Dlatego dołącz do aplikacji oddzielny plik wykonywalny ze złym podpisem. Może to być po prostu program składający się z trzech wierszy, który ma funkcję main () i wartość zwracaną. Skompiluj plik wykonywalny bez podpisywania kodu (wyłącz go w Ustawieniach projektu-> Kompiluj) i podpisz go innym kluczem, używając narzędzia wiersza poleceń „Codesign”.
Niech Twoja aplikacja wykonuje oddzielny plik wykonywalny. Jeśli twój program nie może uzyskać wartości zwracanej podczas uruchamiania oddzielnego pliku wykonywalnego z błędnym sig, z pewnością jest więziony. Jeśli oddzielny plik wykonywalny zwraca A-OK, telefon jest zdecydowanie 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
}
Możesz wykryć, czy urządzenie jest JailBroken, czy nie, sprawdzając następujące elementy:
Istnieje biblioteka open source, którą stworzyłem z różnych artykułów i książek. Wypróbuj na GitHub !
W Swift 2.3 przerobiłem rozwiązanie dostarczone przez @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
}
Najbardziej zaawansowaną metodą, jaką znam, jest użycie objc_copyImageNames()
funkcji. Zwraca listę aktualnie załadowanych bibliotek, a ponieważ większość ludzi ma MobileSubstrate na urządzeniach po jailbreaku i większość narzędzi do łamania iAP jest od niej zależna, pojawią się przynajmniej niektóre biblioteki MobileSubstrate.
deb
pliku MobileSubstrate, rozpakować go i umieścić na czarnej liście (prawie) wszystko .dylib
to jest spakowane.
Nie znam żadnych „interfejsów API”, które istnieją w tym celu. Gdyby tak było, produkt maskujący jailbreak szybko je zakrył.
Jak wiele osób zwraca uwagę, jest to gra w kotka i myszkę. A kiedy obaj gracze stają się ekspertami, wszystko sprowadza się do tego, kto wykona pierwszy ruch. (Osoba trzymająca urządzenie.)
Znalazłem wiele dobrych sugestii dotyczących wykrywania jailbreaków w nowej książce Zdziarskiego „Hacking and Securing iOS Apps”. (Osobiście zapłaciłem więcej za eBook O'Reilly, ponieważ pozwalają na kopiowanie i wklejanie).
Nie, nie jestem powiązany z wydawcami. Ale uważam, że to dobra książka. Nie lubię po prostu publikować błędów hakerów, aby mogli je naprawić, więc pomyślałem, że wskażę książkę.
Spróbuj wykonać w aplikacji niepodpisany kod.
Urządzenia po jailbreaku mają zwykle następujące cechy:
Samo sprawdzenie istnienia pliku w celu wykrycia jailbreak jest skazane na niepowodzenie. Te kontrole są łatwe do ominięcia.
Niektóre typowe pliki do sprawdzenia:
/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
Większość sprawdza pliki związane z Cydią.
Proponuję poszukać plików, których nie ma na „waniliowym” iPhonie. Wszystkie zestawy jailbreak, które widziałem, instalują ssh. To może być dobry wskaźnik telefonu po jailbreaku.
To, co zrobiliśmy, to to, że mamy już kanał RSS do komunikacji z naszymi użytkownikami ( Stocks Live ), umieściliśmy wiadomość, która brzmi mniej więcej tak:
Niektóre urządzenia po jailbreaku mają problemy bla bla bla, zrobiliśmy hack, aby rozwiązać te problemy, ale musimy wiedzieć, czy jest to urządzenie po jailbreaku, czy nie, naciśnij tutaj, aby aplikacja rozwiązała problem. Jeśli kiedykolwiek wrócisz do normalności, tj. Usunąłeś jailbreak, naciśnij tutaj.
Następnie przetwarzasz interakcję użytkownika i robisz to, co jest właściwe, np. Zachowujesz się inaczej itp.
Spróbuj znaleźć plik, który tworzy Cydia lub urządzenie po jailbreaku. Lub spróbuj pisać w pliku poza czarną skrzynką aplikacji. Jeśli ci się to uda, urządzenie jest przejęte / po jailbreaku :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Użyj następującego kodu dla Swift 4 i nowszych wersji: Dodaj następujący kod w 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()
}
}
}
}
Oto moje rozwiązania: Krok 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
}
}
Krok 2: Wywołaj to w viewDidLoad()
kontrolerze widoku ekranu startowego (lub jakimkolwiek VC, do którego dzwonisz po raz pierwszy):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Spróbuj uzyskać dostęp do /Application/Preferences.app/General.plist Powinieneś być w stanie to zrobić na iPhonie z jailbreakiem Na telefonie innym niż Jb nie będziesz mógł uzyskać do niego dostępu