iOS逆向 - 微信的越狱检测分析
嘿嘿,不要搞坏事
微信一启动会对当前的设备做N多的检测。比如
检测 bundleID,发现不是 "com.tencent.xin" 有可能报非法客户端。
检测 uuid,多个客户端有相同的 uuid,可能报非法多开。
检测 jailbroken,越狱机上有些功能不开放的。
还有下面这段信息会上传到后台。
+ (id) [KSSystemInfo systemInfo] 方法的返回值
{
CFBundleExecutable = WeChat;
CFBundleExecutablePath = "/var/mobile/Containers/Bundle/Application/DE497A13-E76F-42B8-B476-A9934B486EF4/WeChat.app/WeChat";
CFBundleIdentifier = "com.tencent.xin";
CFBundleName = WeChat;
"app_uuid" = "AAAAA633-1E42-32DE-B943-2C16A47C7A3E";
"cpu_arch" = arm64;
"device_app_hash" = 9eb422144a96af8f91XXXXxxxxxdaf0d4742321b;
jailbroken = 0;
machine = "iPhone6,2";
memory = { size = 1048576000; };
"system_name" = "iPhone OS";
"system_version" = "9.2.1";
...
后面省略一千个字段
...
}
一启动微信会上传一堆当前运行环境的信息上去,判断你是不是多开了,非法了,越狱了等等。
微信怎么检测是否越狱
打开 hopper,全局搜 jail(越狱的单词前半段),找到这段代码
adrp 取了虚拟内存地址 #0x102da2000 的绝对地址,又加上了 #0xd61,hopper 告诉我们这个地址里面放了 "MobileSubstrate" 字符串常量。
"MobileSubstrate" 一看就是越狱后用来注入代码的一个库。
把字符串地址放到 x0 寄存器中,调用了 sub_100436a20。
sub_ 开头的一看就是 c 语言的函数。进去里面看看
这段代码大概就是一启动的时候,调用 _dyld_image_count() 获得加载的动态库的数量,_dyld_get_image_name() 获得名字,然后遍历他们的名字,看看有没有 “MobileSubstrate” 关键字,有的话就是越狱的了,像这样。
#import <mach-o/dyld.h>
int count = _dyld_image_count();
for (int i=0; i<count; i++) {
printf("%s", _dyld_get_image_name(i));
// 如果 _dyld_get_image_name() 里面包含 MobileSubstrate 就是越狱了
}
微信是调用 + [KSSystemInfo isJailbroken] 来判断是否越狱的,那怎么绕过越狱检测就很简单了。
然而!
我发现微信里面还有一个 JailBreakHelper 类,看名字就是越狱检测助手,难道微信有2套检测机制?
继续往下看 - [JailBreakHelper IsJailBreak] 方法的代码,还原里面一个数组的代码大概是
NSArray *paths = @[
@"/etc/ssh/sshd_config",
@"/usr/libexec/ssh-keysign",
@"/usr/sbin/sshd",
@"/bin/sh",
@"/bin/bash",
@"/etc/apt",
@"/Applications/Cydia.app/",
@"/Library/MobileSubstrate/MobileSubstrate.dylib"];
然后检测手机里是否有 paths 里面的路径,有的话就是越狱了。
怎么绕过的话,你懂的,嘿嘿。
参考文献:支付宝大神的 iOS安全攻防(二十):越狱检测的攻与防