iOS 10下Hook IOKit框架修改序列号失败问题咨询
我来帮你梳理下可能导致Hook后仍显示真实序列号的几个常见原因,以及对应的解决思路:
1. Hook的函数实现不完整或符号匹配错误
从你给出的代码片段来看,只定义了原函数的指针orig_registry...,但没有完整实现替换函数,也没完成Hook绑定。首先要确保你正确Hook了IORegistryEntryCreateCFProperty的完整符号,并且在替换函数里针对序列号的键做了拦截。
示例完整的Hook逻辑应该是这样的:
#import <substrate.h> #import <IOKit/IOKitLib.h> // 保存原函数指针 static CFTypeRef (*orig_IORegistryEntryCreateCFProperty)(io_registry_entry_t entry, CFStringRef key, CFAllocatorRef allocator, IOOptionBits options); // 自定义Hook函数 CFTypeRef hook_IORegistryEntryCreateCFProperty(io_registry_entry_t entry, CFStringRef key, CFAllocatorRef allocator, IOOptionBits options) { // 检查是否是读取序列号的请求(键为"serial-number") if (CFStringCompare(key, CFSTR("serial-number"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { // 返回你想要伪造的序列号 return CFStringCreateCopy(allocator, CFSTR("MY-FAKE-SERIAL-1234")); } // 其他属性请求调用原函数 return orig_IORegistryEntryCreateCFProperty(entry, key, allocator, options); } // 构造函数,初始化Hook %ctor { // 绑定原函数和Hook函数 MSHookFunction((void*)&IORegistryEntryCreateCFProperty, (void*)&hook_IORegistryEntryCreateCFProperty, (void**)&orig_IORegistryEntryCreateCFProperty); }
另外要注意:iOS 10的IOKit中,这个函数的符号是否是_IORegistryEntryCreateCFProperty?有时候私有框架的符号可能有前缀,需要确认符号表(可以用nm命令查看IOKit.dylib的符号)。
2. Hook的注入时机或进程范围不够
序列号可能被多个系统进程和应用读取,比如SpringBoard、launchd,甚至第三方APP。如果你的tweak只注入到SpringBoard,那其他进程读取序列号时还是会拿到真实值。
- 确保你的
tweak.plist里的Filter设置为注入到所有进程,或者至少覆盖所有可能读取序列号的进程:
<key>Filter</key> <dict> <key>Executables</key> <array> <string>SpringBoard</string> <string>MobileSafari</string> <!-- 添加其他需要注入的进程 --> <string>*</string> <!-- 注入所有进程,测试时可用,但正式版建议按需添加 --> </array> </dict>
- 另外,有些系统进程启动很早,你的tweak如果注入时机太晚(比如SpringBoard启动后才加载),这些进程已经缓存了序列号,需要重启设备才能让Hook生效。
3. 序列号的读取路径不止IOKit
很多应用(包括系统应用)不会直接调用IOKit的函数读取序列号,而是通过libMobileGestalt.dylib的API,比如MGCopyAnswer来获取kMGSerialNumber对应的 value。所以只Hook IOKit是不够的,需要同时Hook这些Gestalt的API:
示例Hook MGCopyAnswer的代码:
#import <substrate.h> #import <MobileGestalt/MobileGestalt.h> static CFStringRef (*orig_MGCopyAnswer)(CFStringRef key); CFStringRef hook_MGCopyAnswer(CFStringRef key) { if (CFStringCompare(key, kMGSerialNumber, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { return CFStringCreateCopy(NULL, CFSTR("MY-FAKE-SERIAL-1234")); } return orig_MGCopyAnswer(key); } %ctor { MSHookFunction((void*)&MGCopyAnswer, (void*)&hook_MGCopyAnswer, (void**)&orig_MGCopyAnswer); // 同时Hook IOKit的函数... }
4. 权限或签名问题
iOS 10的越狱环境中,你的tweak需要正确签名(用ldid或者codesign),并且拥有足够的权限来Hook系统框架。如果签名不正确,tweak可能无法注入到系统进程,自然无法生效。
可以尝试重新签名你的tweak,或者确保越狱工具(比如Cydia Substrate)正常工作。
5. 系统缓存问题
部分系统组件会缓存序列号的值,比如SpringBoard启动时就会读取并缓存。所以即使Hook成功,也需要重启SpringBoard(用killall SpringBoard命令)或者重启设备,才能让伪造的序列号生效。
内容的提问来源于stack exchange,提问作者Tien Minh

