iOS 逆向
iOS 越狱检测机制与绕过原理全解析
0x
为什么 App 要检测越狱?
越狱后用户获得 root 权限,可以注入插件、篡改内存、绕过内购。对金融、风控、游戏类 App 而言,越狱设备是黑产的高发区,因此必须能识别出"环境不可信"并采取降级策略(禁用功能、强制退出、上报风控)。
常见的检测手段
1. 文件路径检测
越狱环境会在文件系统留下特征痕迹,最经典的检测方式就是检查这些路径是否存在:
NSArray *paths = @[
@"/Applications/Cydia.app",
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
@"/usr/sbin/sshd",
@"/bin/bash",
@"/var/cache/apt",
@"/etc/apt"];
for (NSString *p in paths) {
if ([[NSFileManager defaultManager] fileExistsAtPath:p]) {
return YES; // 检测到越狱
}
}
2. 动态库注入检测
越狱插件通过 DYLD_INSERT_LIBRARIES 或 MobileSubstrate 注入,App 可以遍历已加载的动态库:
BOOL hasSubstrate = NO;
uint32_t count = _dyld_image_count();
for (uint32_t i = 0; i < count; i++) {
const char *name = _dyld_get_image_name(i);
if (strstr(name, "MobileSubstrate") ||
strstr(name, "Substrate")) {
hasSubstrate = YES;
}
}
3. 行为与沙盒检测
- fork 检测:越狱环境下
fork()可以成功执行,正常沙盒会返回 -1 - 沙盒逃逸:尝试向沙盒外(如
/var/test)写入文件,成功即越狱 - URL Scheme:尝试打开
cydia://看是否可用 - 系统调用:调用
sysctl读取内核标志位
绕过思路:对症下药
检测的本质是"查询环境",绕过就是让查询返回"正常"的结果。最直接的方式是 Hook 掉检测函数:
%hook NSFileManager
- (BOOL)fileExistsAtPath:(NSString *)path {
NSArray *blacklist = @[@"/Applications/Cydia.app",
@"/bin/bash", @"/usr/sbin/sshd"];
if ([blacklist containsObject:path]) {
return NO; // 对特征路径一律说不存在
}
return %orig;
}
%end
更隐蔽的绕过会 Hook _dyld_image_count 和 _dyld_get_image_name,在遍历结果中过滤掉注入库。
反绕过:检测方的升级
绕过手段普及后,防御方也开始反制:
- 关键检测下沉到 C 层:把检测函数写成 C 函数甚至内联汇编,避开 OC 的 Runtime Hook
- 服务端校验:客户端只上报特征,由服务端综合判断,防止本地全被 Hook
- 完整性校验:对自身 Mach-O 做哈希比对,发现被修改即退出
- 反调试:检测
ptrace与调试器附加(sysctl P_TRACED)
写在最后
越狱检测与绕过是一场持续的军备竞赛。无论攻守,都请牢记:逆向分析仅限自有 App 或已授权的安全研究,未经授权的破解、绕过风控均属违法行为。
检测与绕过之间没有银弹,只有对系统机制理解深度的较量。