如何检测 iOS 应用程序正在越狱手机上运行?
题
如果我希望我的应用程序在越狱的 iPhone 上表现不同,我将如何确定这一点?
解决方案
这取决于越狱的意思。在简单的情况下,您应该能够看到Cydia是否已经安装并且通过它 - 比如
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
对于被黑客攻击的内核,它会涉及更多(很多)。
其他提示
+(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合法检查:
这是一个代码,它结合了我为此需求找到的一些答案,并将为您提供更高的成功率:
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;
}
检查内核是否损坏不是那么多了。
越狱使内核对签名代码的签名检查始终报告代码已正确签名,不间断的手机无法运行带有错误签名的代码。
因此,在应用程序中包含一个带有错误签名的单独可执行文件。它可能只是一个具有main()和返回值的3行程序。在没有代码签名的情况下编译可执行文件(在Project Settings-> Build中将其关闭),并使用“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
}
您可以通过检查以下内容来检测设备是否越狱:
- Cydia已安装
- 验证一些系统路径
- 执行沙箱完整性检查
- 执行符号链接验证
- 验证您是否在沙箱之外创建和写入文件
我根据各种文章和书籍创建了一个开源库。 在 GitHub 上尝试一下!
我在Swift 2.3中重写了@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
}
我所知道的最复杂的方法是使用 objc_copyImageNames()
函数。它返回一个当前加载的库列表,因为大多数人在越狱设备上都有MobileSubstrate,并且大多数iAP破解工具依赖它,至少会出现一些MobileSubstrate库。
我不知道任何“API”为此存在。如果有,那么越狱掩盖的产品会迅速掩盖它们。
很多人都指出,这是一场猫捉老鼠的比赛。在两位球员成为专家之后,这一切都取决于谁获得了第一步。 (拿着设备的人。)
我在Zdziarski的新书“Hacking and Securing iOS Apps”中发现了很多关于检测越狱的好建议。 (就个人而言,我为O'Reilly电子书支付了更多费用,因为它们允许复制和粘贴。)
不,我与发布商没有任何关系。但我确实觉得这本书很好。我不喜欢发布黑客的错误,所以他们可以解决它们,所以我想我会指向这本书。
尝试通过您的应用程序执行未签名的代码。
越狱设备通常具有以下特征:
- 运行未签名的代码
- 是否已安装 Cydia
- 有越狱文件
- 对整个文件系统的完全读/写访问
- 一些系统文件将被修改(内容和sha1与原始文件不匹配)
- 坚持特定版本(越狱版本)
仅仅检查文件是否存在来进行越狱检测注定会失败。这些检查很容易被绕过。
要检查的一些常见文件: <代码> /Library/MobileSubstrate/MobileSubstrate.dylib 代码>
<代码> /Applications/Cydia.app 代码>
<代码>的/ var /缓存/公寓代码>
<代码>的/ var / lib中/公寓代码>
<代码>的/ var / lib中/苹果蠹代码>
<代码>的/ var / log / syslog的代码>
<代码> /var/tmp/cydia.log 代码>
<代码> /斌/庆典代码>
<代码> / bin / sh的代码>
<代码> / usr / sbin目录/ sshd的代码>
<代码>的/ usr /的libexec / SSH-keysign成为代码>
<代码>的/ etc / SSH / sshd_config中代码>
<代码>的/ etc /公寓代码>
大多数检查Cydia相关文件。
我建议寻找“香草”上没有的文件。苹果手机。我见过的所有越狱套件都安装了ssh。这可能是越狱电话的一个很好的指标。
我们所做的是,我们已经有一个RSS提要与我们的用户沟通(股票直播),我们提出了一个类似这样的新闻:
一些越狱设备存在问题,我们做了一个黑客来解决这些问题,但我们需要知道这是否是一个越狱设备,请按此处,以便应用程序解决问题。如果你恢复正常,即取消越狱,请按此处。
然后你处理用户交互并做适当的事情,比如表现不同等......
尝试查找cydia或越狱设备创建的文件。或者尝试在应用程序的黑盒子外写一个文件。如果您成功执行此操作,设备将遭到入侵/越狱:)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
您将跟踪一个移动目标,但您可以尝试跟踪这些资源的进度,以了解您的技术有多有效:
继承我的解决方案:
extension UIDevice {
func isJailBroken() -> Bool {
var jailBroken = false
let cydiaPath = "/Applications/Cydia.app"
let aptPath = "/private/var/lib/apt/"
if FileManager.default.fileExists(atPath: cydiaPath) {
jailBroken = true
}
if FileManager.default.fileExists(atPath: aptPath) {
jailBroken = true
}
return jailBroken
}
}
并在启动屏幕视图控制器(或您第一次呼叫的任何VC)内的 viewDidLoad()
内调用它:
if UIDevice.current.isJailBroken() {
// show a blank screen or some other view controller
let jailbreakVC = JailBrokenViewController()
self.navigationController?.present(jailbreakVC, animated: true, completion:nil)
} else {
// continue executing your next View controller
let nextVC = NextViewController()
self.navigationController?.present(nextVC, animated: true, completion:nil)
}
尝试访问/Application/Preferences.app/General.plist 你应该能够在越狱的iPhone上这样做 在非Jb手机上你将无法访问它