7

我需要一种稳定的方法来尝试在 iOS 设备上运行未签名的可执行文件,以测试设备是否已越狱(即允许运行未签名的代码)。

我编写了一个基本上什么都不做的小型可执行文件。

int main(int argc, char *argv[]) {
    return 23;
}

我已经在 iOS 设备(越狱和未越狱)上成功编译并运行。

然后,我将此可执行文件添加到 App 捆绑包中,并将该应用程序部署到 iOS 设备。

这会导致设备上的可执行文件的只读版本。我试图 chmod 这个文件以赋予它执行权限,但是失败了,所以我将它复制到应用程序的 tmp 目录中,在那里我可以使用可执行权限进行 chmod。

其他问题建议使用 execve 调用可执行文件,但这会将正在运行的进程替换为新进程,这将杀死应用程序。Fork() 总是失败,所以这不是一个选项。System() 需要一个外壳程序,并且可以在没有外壳程序的情况下进行越狱,它仍然允许未签名的代码运行,所以它已经过时了。Popen() 分叉,所以这行不通。

有趣的是,据我发现,在普通设备上对我的可执行文件调用 execv 会导致“不允许操作”错误,而在越狱设备上调用它会导致“权限被拒绝”错误。仅此一项就可以进行越狱检测,除非在允许 execv 继续进行的越狱发生的情况下,应用程序将立即崩溃,因为它的进程将被替换。

据此 iBooks 执行越狱检测,但它似乎使用 fairplayd 二进制文件来执行它的 execve 调用。

有人对运行可执行文件或使用 fairplayd 有任何建议吗?

4

1 回答 1

3

您无法直接更改测试可执行文件的权限,因为在安装您的应用后无法修改应用资源。那将是一个安全漏洞。所以,这就是为什么您需要将它复制到 tmp/caches/documents 目录,然后使其可运行。

我不确定您的应用是否需要支持多任务处理,是否需要在第一次运行开始时检测越狱,或者是否可以等到应用关闭。但是,如果你可以关闭多任务,那么你可以实现这个方法(test这个例子中命名的小可执行文件):

- (void)applicationWillTerminate:(UIApplication *)application {
    NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent: @"test"];
    int result = execlp([path UTF8String], [path UTF8String], NULL);
    // if we got here, then the attempt to run the external process failed, so make a note of this:
    [[NSUserDefaults standardUserDefaults] setValue: [NSNumber numberWithBool: NO] forKey: @"is_jailbroken"];
    NSLog(@"test returns %d", result);
}

如果execlp()调用成功,那么是的,你的进程将被替换。但是,无论如何,该过程即将关闭。当我这样做时,我没有看到实际的崩溃日志,所以我不确定 Apple 是否会抱怨这一点。对用户来说没有崩溃的外观

如果您无法执行单独的流程,那么您的应用程序将继续执行允许您记录手机显然没有越狱的事实的代码行,这可以在您的应用程序下次启动时记录下来。

如果您确实需要支持多任务,那么您可以尝试将上述代码放入多任务回调中,例如applicationDidEnterBackground:. 如果手机正常,则 exec 调用失败(并返回),因此您的应用不会终止(退出)。我会假设(?)Apple 评论员不会在越狱手机上测试您的应用程序。对于那些手机越狱的人,您的应用程序将退出,而不是进入后台。也许这足以满足您的需求?

另外,仅供参考,还有其他方法可以测试越狱系统,这可能非常可靠(我不确定您是否希望能够 100% 检测越狱手机,或者检测标准越狱配置)

以编程方式确定 iPhone 是否越狱

如何检测 iOS 应用程序正在越狱手机上运行?

于 2012-09-01T08:38:02.117 回答