Якщо я хочу, щоб мій додаток поводився по-різному на iPhone, що не має зламу, як би я вирішив це визначити?
Якщо я хочу, щоб мій додаток поводився по-різному на iPhone, що не має зламу, як би я вирішив це визначити?
Відповіді:
Це залежить від того, що ви маєте на увазі під в'язницею. У простому випадку ви повинні мати змогу побачити, чи встановлена Cydia та йти далі - щось подібне
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
Для зламаних ядер це трохи (набагато) більше.
fileExistsAtPath:
і змусити його повернутися NO
для певного шляху, який ви перевіряєте.
Це код, який поєднує в собі декілька відповідей, які я знайшов на цю потребу, і дасть вам значно вищий рівень успішності:
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];
}
Перевірка шляху файлу /Applications/Cydia.app
заборонена на звичайному телефоні? Я ніколи не чув, щоб Apple виявляла це і відхиляла додаток для цього, але Apple непередбачувана. Cydia має URL-схему cydia: //, яку можна юридично перевірити за допомогою UIApplicationcanOpenURL:
Перевірка, чи не зламано ядро, НЕ ЧОГО більше задіяне.
Jailbreaking змушує перевірку підпису ядра підписаного коду завжди повідомляти, що код підписаний правильно, нерозривні телефони не можуть запускати код із поганою підписом.
Отже, включіть у програму окремий виконуваний файл із неправильним підписом. Це може бути просто 3-рядова програма, яка має main () і повернене значення. Скомпілюйте виконуваний файл без підписання коду (вимкніть його в Налаштуваннях проекту-> Збірка) та підпишіть його іншим ключем за допомогою утиліти командного рядка «codeign».
Запропонуйте вашій програмі виконати окремий виконуваний файл. Якщо ваша програма не може отримати повернене значення під час запуску окремого виконуваного файлу з неправильним знаком, воно, безумовно, знаходиться у в'язниці. Якщо окремий виконуваний файл поверне A-OK, телефон, безумовно, знаходиться в безвідмовному режимі.
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
}
Ви можете визначити, чи є пристрій JailBroken чи ні, перевіривши наступне:
Є бібліотека з відкритим кодом, яку я створив з різних статей та книг. Спробуйте це на GitHub !
Я переробив у Swift 2.3 рішення, яке надає @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
}
Найбільш складний метод, який я знаю, - це використання objc_copyImageNames()
функції. Він повертає список завантажених в даний час бібліотек, і оскільки більшість людей мають MobileSubstrate на пристроях з розширеним змістом, і від цього залежить більшість інструментів тріщини, принаймні деякі бібліотеки MobileSubstrate з'являться.
deb
файл MobileSubstrate, розпаковувати його та чорний список (майже) все .dylib
це запаковано.
Я не знаю жодних "API" для цього. Якби вони були, то виріб, який маскує втечу, швидко прикривав би їх.
Як зазначають багато людей, це гра котів і мишей. І після того, як обидва гравці стають експертом, все зводиться до того, хто отримує перший хід. (Особа, яка тримає пристрій.)
Я знайшов багато хороших пропозицій щодо виявлення втечі з в'язниці у новій книзі Здзярського "Злом та безпека додатків iOS". (Особисто я заплатив більше за електронну книгу O'Reilly, оскільки вони дозволяють копіювати та вставляти.)
Ні, я не пов’язаний з видавцями. Але я знайшов це гарною книгою. Мені не подобається публікувати помилки хакерів, щоб вони могли їх виправити, тому я подумав, що я вкажу на книгу.
Спробуйте виконати безпідписаний код через свою програму.
Пристрої, що перебувають у в'язниці, зазвичай мають такі характеристики:
Просто перевірка наявності файлу на виявлення втечі від джейлбрейка приречена на збій. Ці чеки легко обійти.
Деякі поширені файли для перевірки:
/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
Більшість перевіряє наявність файлів, пов'язаних із Cydia.
Я б запропонував шукати файли, яких немає на iPhone з "ваніллю". Усі набори, які я бачив, встановлюють ssh. Це може бути хорошим індикатором розбитого телефону.
Що ми зробили, це те, що у нас вже є RSS-канал для спілкування з нашими користувачами ( Запаси в прямому ефірі ), ми розміщуємо новину, де йдеться про щось подібне:
Деякі пристрої з джейлбрейками мають проблеми з бла-бла-бла, ми зробили хак для вирішення цих проблем, але нам потрібно знати, чи це пристрій з джейлбрейком чи ні, натисніть тут, щоб програма усунула цю проблему. Якщо ви коли-небудь повернетесь до нормального стану, тобто зняли втечу з в'язниці, натисніть тут.
Тоді ви обробляєте взаємодію з користувачем і робите все, що підходить, наприклад, поводяться різні тощо.
Спробуйте знайти файл, який створюють пристрої cydia або jailbroken. Або спробуйте написати у файлі, який знаходиться за межами програми blackbox. Якщо вам це вдасться, пристрій зламано / збито з розбиття :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Будь ласка, використовуйте наступний код для Swift 4 і вище: Додайте такий код у додаток:
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 (_ додаток: 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()
}
}
}
}
Ось мої рішення: Крок 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
}
}
Крок 2: Зателефонуйте всередину viewDidLoad()
всередину контролера перегляду екрана запуску (або будь-якого VC, який ви телефонуєте вперше):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Спробуйте отримати доступ до /Application/Preferences.app/General.plist Ви повинні мати змогу зробити це на iPhone, що не працює в розвороті. На телефоні, що не є Jb, ви не зможете отримати доступ до нього