如何判断设备是否越狱?

如何判断设备是否越狱?

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

iPhone 越狱已经不是什么新鲜事,但是越狱之后意味着已经拿到了系统的所有权限,继续在越狱的设备上运行你的程序也就意味着不再安全,因此目前很多主流的 App 都是禁止运行在此类设备上的。

但是怎么判断一个设备是否为越狱的机器呢?今天就来讲讲我所知道的一些方法。

方法一

检查手机上是否安装了 Cydia ,玩越狱的同学肯定都清楚,这个 app 堪称是越狱系统的 App Store,上边可以安装各种正规 App Store 安装不到的软件。Cydia 上除了独立的应用程序之外,更多的包是 iOS 本身和应用程序的扩展、修改和主题。

因此可以说只要是越狱的设备,都会安装这个应用,那我们只需要检测这个应用存不存在就行了。

这里主要用到的方法是用 canOpenURL 是否能打开 cydia:// 这个 URL Scheme。

csharp

复制代码

func isJailBreak() -> Bool {

return UIApplication.shared.canOpenURL(URL(string: "cydia://")!)

}

这里记得把 cydia 加入到 info.plist 中的 LSApplicationQueriesSchemes 字段里才能正常检测应用是否安装

这种方式简单粗暴,不过不建议用,因为准确度可能不高,一方面 cydia 可能把这个 URL Scheme 改掉防止你检测。另一方面正常手机也可能会有一个 app 的 URL Scheme 叫这个名字,造成误判。

方法二

检测是否存在 MobileSubstrate 动态库,这个库是 cydia 的基石,越狱环境下安装绝大部分插件,必须要有 MobileSubstrate,因此我们只需要判断是否存在这个动态库即可。

我在网上找了一个 c 语言的实现:

arduino

复制代码

bool

isJailBreak(void)

{

const char *const imageName = "MobileSubstrate";

if (imageName != NULL) {

const uint32_t imageCount = _dyld_image_count();

for (uint32_t iImg = 0; iImg < imageCount; iImg++) {

const char *name = _dyld_get_image_name(iImg);

if (strstr(name, imageName) != NULL) {

return true;

}

}

}

return false;

}

方法三

还是检测文件,如果越狱的话,设备会创建许多文件,可以使用 FileManager 来检测这些文件是否存在:

csharp

复制代码

func isJailBreak() -> Bool {

#if targetEnvironment(simulator)

return false

#else

let files = [

"/private/var/lib/apt",

"/Applications/Cydia.app",

"/Applications/RockApp.app",

"/Applications/Icy.app",

"/Applications/WinterBoard.app",

"/Applications/SBSetttings.app",

"/Applications/blackra1n.app",

"/Applications/IntelliScreen.app",

"/Applications/Snoop-itConfig.app",

"/bin/sh",

"/usr/libexec/sftp-server",

"/usr/libexec/ssh-keysign /Library/MobileSubstrate/MobileSubstrate.dylib",

"/bin/bash",

"/usr/sbin/sshd",

"/etc/apt /System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",

"/System/Library/LaunchDaemons/com.ikey.bbot.plist",

"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",

"/Library/MobileSubstrate/DynamicLibraries/Veency.plist"

]

return files.contains(where: {

return FileManager.default.fileExists(atPath: $0)

})

#endif

}

这里有个条件编译,在模拟器下是不需要检查的。

方法四

越狱之后所有 App 都被授予 root 权限,并且可以修改沙箱之外的文件。利用这个特点,如果我们的 App 可以写入其沙箱之外的文件,则证明该设备已越狱:

php

复制代码

func isJailBreak() -> Bool {

let string = "iOS 新知"

do {

try string.write(to: URL(filePath: "/private/myfile.txt"), atomically: true, encoding: .utf8)

return true

} catch {

return false

}

}

方法五

越狱之后也就意味着 App 可以随意调用系统 API 了,因此我们可以尝试调用系统 API,来查看是否能得到正确结果,以此来判断是否越狱:

swift

复制代码

func isJailBreak() -> Bool {

let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)

let forkPtr = dlsym(RTLD_DEFAULT, "fork")

typealias ForkType = @convention(c) () -> Int32

let fork = unsafeBitCast(forkPtr, to: ForkType.self)

return fork() != -1

}

建议以上五种方法结合使用,提高检测的准确率。

检测到越狱设备,禁止使用

如果检测到当前运行环境为越狱设备,可以强制退出 App,以确保安全。强制退出 app 的方法就很多了,可以使用 exit(-1),也可以人为做个数组越界之类的:

scss

复制代码

// 检测到越狱设备

if isJailBreak() {

// 退出 app

exit(-1)

// 或者数组越界 crash

// [0][1]

}

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐

京东运费险怎么赔付?
365bet线上娱乐

京东运费险怎么赔付?

⌛ 08-30 👁️ 7615
什么共享汽车免押金?
365bet规则

什么共享汽车免押金?

⌛ 10-31 👁️ 839
守望先锋国王行动用什么英雄
365bet线上娱乐

守望先锋国王行动用什么英雄

⌛ 09-13 👁️ 6996