回答:
それはあなたが脱獄とはどういう意味かによって異なります。単純なケースでは、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:// は、UIApplicationで合法的に確認できます。canOpenURL:
カーネルが壊れているかどうかを確認することは、それほど複雑ではありません。
ジェイルブレイキングは、カーネルの署名済みコードの署名チェックで常にコードが正しく署名されていることを報告します。壊れていない電話は不正な署名のあるコードを実行できません。
そのため、不正な署名のある別の実行可能ファイルをアプリに含めます。main()と戻り値を持つ3行のプログラムの場合もあります。コード署名なしで実行可能ファイルをコンパイルし(プロジェクト設定->ビルドでオフにします)、 "codesign"コマンドラインユーティリティを使用して別のキーで署名します。
アプリに個別の実行可能ファイルを実行してもらいます。不正なsigを使用して別の実行可能ファイルを実行するときにプログラムが戻り値を取得できない場合、それは間違いなく投獄されます。別の実行可能ファイルが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でお試しください!
@Yossiが提供するソリューションをSwift 2.3で作り直しました
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」については知りません。もしあれば、脱獄マスキング製品はすぐにそれらを覆い隠すでしょう。
多くの人が指摘するように、それは猫とマウスのゲームです。そして、両方のプレイヤーがエキスパートになった後、すべては最初の動きを誰が得るかにかかっています。(デバイスを持っている人。)
Zdziarskiの新しい本「iOSアプリのハッキングと保護」で脱獄を検出するための多くの良い提案を見つけました。(個人的には、コピーアンドペーストが許可されているため、O'ReillyのeBookにもっと支払った。)
いいえ、私は出版社と提携していません。しかし、私はそれが良い本だと思いました。ハッカーの過ちをただ公開して、彼らがそれを修正できるようにするのは好きではないので、私はこの本を指すと思いました。
アプリケーションを介して署名されていないコードを実行してみてください。
ジェイルブレイクされたデバイスには通常、次の特性があります。
ジェイルブレイク検出のためにファイルの存在を確認するだけでは失敗する運命にあります。これらのチェックは簡単に回避できます。
「バニラ」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()
起動画面のビューコントローラー(または最初に呼び出す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以外の電話ではアクセスできません