Если я хочу, чтобы мое приложение по-разному работало на взломанном 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 заставляет ядро проверять подпись подписанного кода всегда, сообщая, что код подписан правильно, не сломанные телефоны не могут выполнять код с плохой подписью.
Итак, включите в приложение отдельный исполняемый файл с неверной подписью. Это может быть просто трехстрочная программа, которая имеет main () и возвращаемое значение. Скомпилируйте исполняемый файл без подписи кода (отключите его в Project Settings-> Build) и подпишите его другим ключом с помощью утилиты командной строки "codesign".
Сделайте так, чтобы ваше приложение исполняло отдельный исполняемый файл. Если ваша программа не может получить возвращаемое значение при запуске отдельного исполняемого файла с плохим сигналом, она определенно заключена в тюрьму. Если отдельный исполняемый файл возвращает 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 на взломанных устройствах, и большинство инструментов взлома iAP зависят от него, по крайней мере, некоторые библиотеки 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-канал для общения с нашими пользователями ( Stocks Live ), мы разместили новость, в которой говорится что-то вроде этого:
Некоторые взломанные устройства имеют проблемы, бла-бла-бла, мы взломали, чтобы решить эти проблемы, но нам нужно знать, является ли это взломанным устройством или нет, нажмите здесь, чтобы приложение исправило проблему. Если вы когда-нибудь вернетесь в нормальное состояние, т.е. удалили джейлбрейк, нажмите здесь.
Затем вы обрабатываете взаимодействие с пользователем и делаете то, что нужно, например, ведете себя по-другому и т. Д.
Попробуйте найти файл, созданный cydia или взломанным устройством. Или попробуйте записать файл вне черного ящика приложения. Если вам это удастся, устройство взломано / взломано :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Пожалуйста, используйте следующий код для Swift 4 и выше: Добавьте следующий код в 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()
}
}
}
}
Вот мои решения: Шаг 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()
вашего контроллера экрана запуска (или любого другого виртуального канала, который вы вызываете в первый раз):
// 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 вы не сможете получить к нему доступ.