LoginSignup
4
2

More than 1 year has passed since last update.

【Swift】脱獄を検知する

Last updated at Posted at 2022-06-01

はじめに

iOS端末は脱獄(JailBreak)するとappleからの制限を解除する事ができます。
制限が解除されるとアプリ開発者が触れて欲しくない値にもアクセスされる可能性があり、よろしくないです。
このような行為により、チートが発生します。

今回は脱獄端末を検知してみようと思います。
ただ、今回紹介する方法では脱獄検知回避ツールを使われてしまうと簡単に破られます笑

実装

Jailbreakというフラグを作って脱獄判定を行います

import SwiftUI

struct ContentView: View {
    @State var isDeviceJailBroken: Bool = false
    var body: some View {
        Text(isDeviceJailBroken ? "❌: 脱獄あり" : "✅: 脱獄なし")
    }
}

脱獄判定にはこちらの関数を使用します。

    // 脱獄判定
    func checkDeviceJailBroken() {
        if access("/Applications/Cydia.app", F_OK) != -1 ||
            access("/Applications/blackra1n.app", F_OK) != -1 ||
            access("/Applications/FakeCarrier.app", F_OK) != -1 ||
            access("/Applications/Icy.app", F_OK) != -1 ||
            access("/Applications/IntelliScreen.app", F_OK) != -1 ||
            access("/Applications/MxTube.app", F_OK) != -1 ||
            access("/Applications/RockApp.app", F_OK) != -1 ||
            access("/Applications/SBSettings.app", F_OK) != -1 ||
            access("/Applications/WinterBoard.app", F_OK) != -1 ||
            access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/Veency.plist", F_OK) != -1 ||
            access("/private/var/lib/apt", F_OK) != -1 ||
            access("/private/var/lib/cydia", F_OK) != -1 ||
            access("/private/var/mobile/Library/SBSettings/Themes", F_OK) != -1 ||
            access("/private/var/stash", F_OK) != -1 ||
            access("/private/var/tmp/cydia.log", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.ikey.bbot.plist", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", F_OK) != -1 ||
            access("/usr/bin/sshd", F_OK) != -1 ||
            access("/usr/libexec/sftp-server", F_OK) != -1 ||
            access("/usr/sbin/sshd", F_OK) != -1 ||
            access("/bin/bash", F_OK) != -1 ||
            access("/etc/apt", F_OK) != -1
        {
            isDeviceJailBroken = true
        } else if let url = URL(string: "cydia://package/com.example.package") {
            if UIApplication.shared.canOpenURL(url) {
                isDeviceJailBroken = true
            } else {
                isDeviceJailBroken = false
            }
        } else {
            isDeviceJailBroken = false
        }
    }

onAppearで表示時に判定します

import SwiftUI

struct ContentView: View {
    @State var isDeviceJailBroken: Bool = false
    var body: some View {
        Text(isDeviceJailBroken ? "❌: 脱獄あり" : "✅: 脱獄なし")
            .onAppear() {
                checkDeviceJailBroken()
            }
    }
    // 脱獄判定
    func checkDeviceJailBroken() {
        if access("/Applications/Cydia.app", F_OK) != -1 ||
            access("/Applications/blackra1n.app", F_OK) != -1 ||
            access("/Applications/FakeCarrier.app", F_OK) != -1 ||
            access("/Applications/Icy.app", F_OK) != -1 ||
            access("/Applications/IntelliScreen.app", F_OK) != -1 ||
            access("/Applications/MxTube.app", F_OK) != -1 ||
            access("/Applications/RockApp.app", F_OK) != -1 ||
            access("/Applications/SBSettings.app", F_OK) != -1 ||
            access("/Applications/WinterBoard.app", F_OK) != -1 ||
            access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/Veency.plist", F_OK) != -1 ||
            access("/private/var/lib/apt", F_OK) != -1 ||
            access("/private/var/lib/cydia", F_OK) != -1 ||
            access("/private/var/mobile/Library/SBSettings/Themes", F_OK) != -1 ||
            access("/private/var/stash", F_OK) != -1 ||
            access("/private/var/tmp/cydia.log", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.ikey.bbot.plist", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", F_OK) != -1 ||
            access("/usr/bin/sshd", F_OK) != -1 ||
            access("/usr/libexec/sftp-server", F_OK) != -1 ||
            access("/usr/sbin/sshd", F_OK) != -1 ||
            access("/bin/bash", F_OK) != -1 ||
            access("/etc/apt", F_OK) != -1
        {
            isDeviceJailBroken = true
        } else if let url = URL(string: "cydia://package/com.example.package") {
            if UIApplication.shared.canOpenURL(url) {
                isDeviceJailBroken = true
            } else {
                isDeviceJailBroken = false
            }
        } else {
            isDeviceJailBroken = false
        }
    }
}

これで完成のように思いますが、このままではシュミレーターで実行した際にも脱獄判定されてしまいます。

スクリーンショット 2022-08-08 20 22 37

シュミレーターで実行した際は脱獄判定を行わないように変更します。
シュミレーター判定はこんな感じでできます。

#if !targetEnvironment(simulator)
// 実機のみ実行されます
#endif

こちらをonAppearに追加します

完成

import SwiftUI

struct ContentView: View {
    @State var isDeviceJailBroken: Bool = false
    var body: some View {
        Text(isDeviceJailBroken ? "❌: 脱獄あり" : "✅: 脱獄なし")
            .onAppear() {
                #if !targetEnvironment(simulator)
                checkDeviceJailBroken()
                #endif
            }
    }
    // 脱獄判定
    func checkDeviceJailBroken() {
        if access("/Applications/Cydia.app", F_OK) != -1 ||
            access("/Applications/blackra1n.app", F_OK) != -1 ||
            access("/Applications/FakeCarrier.app", F_OK) != -1 ||
            access("/Applications/Icy.app", F_OK) != -1 ||
            access("/Applications/IntelliScreen.app", F_OK) != -1 ||
            access("/Applications/MxTube.app", F_OK) != -1 ||
            access("/Applications/RockApp.app", F_OK) != -1 ||
            access("/Applications/SBSettings.app", F_OK) != -1 ||
            access("/Applications/WinterBoard.app", F_OK) != -1 ||
            access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", F_OK) != -1 ||
            access("/Library/MobileSubstrate/DynamicLibraries/Veency.plist", F_OK) != -1 ||
            access("/private/var/lib/apt", F_OK) != -1 ||
            access("/private/var/lib/cydia", F_OK) != -1 ||
            access("/private/var/mobile/Library/SBSettings/Themes", F_OK) != -1 ||
            access("/private/var/stash", F_OK) != -1 ||
            access("/private/var/tmp/cydia.log", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.ikey.bbot.plist", F_OK) != -1 ||
            access("/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", F_OK) != -1 ||
            access("/usr/bin/sshd", F_OK) != -1 ||
            access("/usr/libexec/sftp-server", F_OK) != -1 ||
            access("/usr/sbin/sshd", F_OK) != -1 ||
            access("/bin/bash", F_OK) != -1 ||
            access("/etc/apt", F_OK) != -1
        {
            isDeviceJailBroken = true
        } else if let url = URL(string: "cydia://package/com.example.package") {
            if UIApplication.shared.canOpenURL(url) {
                isDeviceJailBroken = true
            } else {
                isDeviceJailBroken = false
            }
        } else {
            isDeviceJailBroken = false
        }
    }
}

追記(2022/08/17)

以下を設定しないとcanOpenURL(url)が常にfalseになる事みたいです
スクリーンショット 2022-08-17 16.46.23.png

Info.plist
	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>cydia</string>
	</array>

おわり

今回作成したプロジェクトです

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2