Se eu quiser que meu aplicativo se comporte de maneira diferente em um iPhone com jailbreak, como eu determinaria isso?
Se eu quiser que meu aplicativo se comporte de maneira diferente em um iPhone com jailbreak, como eu determinaria isso?
Respostas:
Depende do que você quer dizer com jailbreak. No caso simples, você poderá ver se o Cydia está instalado e seguir em frente - algo como
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
Para kernels hackeados, é um pouco (muito) mais envolvido.
fileExistsAtPath:
e fazê-lo retornar NO
para o caminho específico que você verifica.
Este é um código que combina algumas respostas que encontrei para essa necessidade e fornecerá uma taxa de sucesso muito maior:
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];
}
Verificar o caminho do arquivo /Applications/Cydia.app
não é permitido em um telefone normal? Nunca ouvi falar da Apple detectando isso e rejeitando um aplicativo, mas a Apple é imprevisível. O Cydia possui um esquema de URL cydia: // que pode ser verificado legalmente com o UIApplicationcanOpenURL:
Verificar se o kernel está quebrado não é MUITO mais envolvido.
O jailbreak faz com que a verificação de assinatura do kernel do código assinado sempre informe que o código foi assinado corretamente, os telefones não quebrados não podem executar o código com uma assinatura incorreta.
Portanto, inclua um executável separado no aplicativo com uma assinatura incorreta. Poderia ser apenas um programa de 3 linhas que possui main () e um valor de retorno. Compile o executável sem assinatura de código (desative-o em Configurações do Projeto-> Compilar) e assine-o com uma chave diferente usando o utilitário de linha de comando "codesign".
Faça com que seu aplicativo execute o executável separado. Se seu programa não pode obter o valor de retorno ao executar o executável separado com o sig ruim, ele definitivamente está preso. Se o executável separado retornar A-OK, o telefone será definitivamente desbloqueado.
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
}
Você pode detectar se um dispositivo é JailBroken ou não, verificando o seguinte:
Há uma biblioteca de código aberto que criei a partir de vários artigos e livros. Experimente no GitHub !
Reescrevi no Swift 2.3 a solução fornecida pelo @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
}
O método mais sofisticado que conheço é o uso da objc_copyImageNames()
função. Ele retorna uma lista de bibliotecas atualmente carregadas e, como a maioria das pessoas tem o MobileSubstrate em dispositivos jailbroken e a maioria das ferramentas de crack do iAP depende disso, pelo menos algumas bibliotecas do MobileSubstrate serão exibidas.
deb
arquivo do MobileSubstrate, descompactá-lo e colocar na lista negra (quase) tudo .dylib
o que está empacotado.
Não conheço nenhuma "API" existente para isso. Se houvesse, um produto de mascaramento de jailbreak os encobriria rapidamente.
Como muitas pessoas apontam, é um jogo de gato e rato. E depois que os dois jogadores se tornam especialistas, tudo se resume a quem recebe o primeiro lance. (Pessoa segurando o dispositivo.)
Encontrei muitas boas sugestões para detectar jailbreak no novo livro de Zdziarski, "Hacking and Proturing iOS Apps". (Pessoalmente, paguei mais pelo O'Reilly eBook porque eles permitem copiar e colar.)
Não, eu não sou afiliado aos editores. Mas achei um bom livro. Não gosto de publicar apenas os erros dos hackers para que eles possam corrigi-los, então pensei em apontar para o livro.
Tente executar código não assinado através do seu aplicativo.
Um dispositivo jailbroken geralmente possui as seguintes características:
Apenas verificar a existência de arquivos para detecção de jailbreak está fadado ao fracasso. Essas verificações são fáceis de ignorar.
Alguns arquivos comuns para verificar:
/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
A maioria verifica arquivos relacionados ao Cydia.
Eu sugiro procurar arquivos que não estão presentes em um iPhone "baunilha". Todos os kits de jailbreak que eu vi instalar o ssh. Esse pode ser um bom indicador de um telefone com jailbreak.
O que fizemos é que já temos um feed RSS para nos comunicar com nossos usuários ( Stocks Live ), colocamos uma notícia que diz algo como isto:
Alguns dispositivos jailbroken têm problemas bla bla bla, fizemos um hack para resolver esses problemas, mas precisamos saber se esse é um dispositivo jailbroken ou não, pressione aqui para que o aplicativo corrija o problema. Se você voltar ao normal, ou seja, removeu o jailbreak, pressione aqui.
Então você processa a interação do usuário e faz o que é apropriado, como se comportar de forma diferente, etc ...
Tente encontrar um arquivo que o cydia ou o dispositivo jailbroken criam. Ou tente escrever em um arquivo fora da caixa preta do aplicativo. Se você conseguir fazer isso, o dispositivo será comprometido / desbloqueado :)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Use o seguinte código para o Swift 4 e superior: Adicione o seguinte código no 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()
}
}
}
}
Aqui estão as minhas soluções: Etapa 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
}
}
Etapa 2: Ligue para viewDidLoad()
dentro do seu controlador de exibição da tela de inicialização (ou qualquer outro VC que você esteja chamando pela primeira vez):
// show a blank screen or some other view controller
let viewController = UIDevice.current.isJailBroken() ? JailBrokenViewController() : NextViewController()
self.navigationController?.present(viewController, animated: true, completion:nil)
Tente acessar /Application/Preferences.app/General.plist Você poderá fazê-lo em um iPhone com jailbreak No telefone não Jb, não poderá acessá-lo