Xcode
iOS
Swift

SwiftでiOS脱獄チェック

はじめに

チェック項目は以下記事を参考にしました。
iOS脱獄チェックメモ

自分も確認した感じこれだけ確認しておけば十分対処できるのではないかと思ったのでそのままSwiftに移植しました。

ソースコード

JailbreakCheck.swift
import Darwin.C

class JailbreakCheck {

    static var isJailbreak: Bool {
        #if !(TARGET_IPHONE_SIMULATOR)
            if FileManager.default.fileExists(atPath: "/Application/Cydia.app") {
                return true
            } else if FileManager.default.fileExists(atPath: "/Library/MobileSubstrate/MobileSubstrate.dylib") {
                return true
            } else if FileManager.default.fileExists(atPath: "/bin/bash") {
                return true
            } else if FileManager.default.fileExists(atPath: "/usr/sbin/sshd") {
                return true
            } else if FileManager.default.fileExists(atPath: "/etc/apt") {
                return true
            } else if FileManager.default.fileExists(atPath: "/private/var/lib/apt") {
                return true
            }

            let stringToBeWritten = "This is jailbreak test."
            var isWrote = false

            do {
                try stringToBeWritten.write(toFile: "/private/jailbreak.txt", atomically: true, encoding: String.Encoding.utf8)

                defer {
                    try! FileManager.default.removeItem(atPath: "/private/jailbreak.txt")
                    isWrote = true
                }
            } catch {}

            if isWrote {
                return true
            }

            if UIApplication.shared.canOpenURL(URL(string: "cydia://package/com.example.package")!) {
                return true
            }

            var isJailbreak = false
            var f: UnsafeMutablePointer<FILE>?

            let checkUrls: [String] = [
                "/bin/bash",
                "/bin/ssh",
                "/Application/Cydia.app",
                "/Library/MobileSubstrate/MobileSubstrate.dylib",
                "/usr/sbin/sshd",
                "/etc/apt"
            ]

            for url in checkUrls {
                do {
                    defer {
                        fclose(f)
                    }

                    f = try JailbreakCheck.fopen(path: url)

                    defer {
                        if f != nil {
                            isJailbreak = true
                        }
                    }
                } catch {}
            }

            return isJailbreak
        #else
            return false
        #endif
    }

    fileprivate class func fopen(path: String) throws -> UnsafeMutablePointer<FILE>? {
        let f = Darwin.fopen(path, "r")
        return f
    }
}

使い方

if JailbreakCheck.isJailbreak {
    something()
}

最後に

/private/jailbreak.txt を削除するところの処理がちょっと不安ですが、まぁいいことにしておきましょうw
Cの fopen を使ったところこれ間違えてるゾイ!っていうところあれば編集リクやコメントでご指摘いただければ幸いです。