让我们谈谈 iOS 内核内省。Frida 获得 iOS 内核的基础内省支持已经有一段时间了,过去几个月里我们一直在改进它。今天发布的版本大幅扩充了 Kernel API,以便处理较新的 64 位内核。
内核基址
可以通过读取 Kernel.base 属性获得内核基址。有了基址,例如就能计算任何已经通过内核缓存静态分析得知的符号的滑动虚拟地址。
内核内存搜索
内存搜索 API 已移植到内核,因此可以像在用户空间使用 Memory.scan()(或 Memory.scanSync())一样使用 Kernel.scan()(或 Kernel.scanSync())。这是一项强大的基础能力,结合最近推出的位掩码功能,可以通过搜索 arm64 模式来创建自己的符号查找代码。
KEXT 和内存区间
现在可以通过 Kernel.enumerateModules()(或 Kernel.enumerateModulesSync())获得所有 KEXT 的名称和偏移量。
Kernel.enumerateModuleRanges()(或 Kernel.enumerateModuleRangesSync())用于枚举某个指定名称的模块中,由 Mach-O 节定义并按保护属性过滤的所有内存区间。结果与在用户空间调用 Module.enumerateRanges() 得到的结果类似,但还会包含节名。
最后说明
所有 Kernel API 都不依赖 NativePointer,因为它的大小取决于用户空间,而用户空间与内核空间的大小不一定相同。所有地址都改用 UInt64 对象表示。
这一切再加上现有的用于读取、写入和分配内核内存的 JavaScript 接口,可以为构建自己的内核分析或漏洞研究工具提供强大起点。
请注意,这些功能应被视为实验性功能,随意操作内核可能严重损坏你的设备,所以请多加小心,祝黑客愉快!
故障排查
问题:Kernel.available 为 false
满足以下两个条件时,Kernel API 可用:
- 设备已越狱
- Frida 能够获得内核任务的发送权,无论是通过传统的
task_for_pid (0),还是访问 host special port 4(现代越狱采用的方式)
实现后一个条件的推荐方式是附加到系统会话,即 PID 0,然后在其中加载脚本。
问题:我在 32 位内核上做不了多少事
是的,未来可以改进这方面,但如今 32 位 iOS 在优先级列表中的位置相当靠后。当然,我们非常欢迎你参与贡献并发送 PR。
问题:我尝试做 X,结果内核 panic 了
别担心,这很正常。你可以前往设备上的 /private/var/mobile/Library/Logs/CrashReporter 目录,或导航到“设置 -> 隐私 -> 分析 -> 分析数据”,找到 panic 日志,并弄清楚你(或 Frida)做错了什么。请记住:内核永远是对的!
问题:我使用 Frida Kernel API 对设备造成了无法恢复的损坏
听到这个消息很遗憾。如果损坏发生在硬件层面,而你又能投入足够的时间和金钱,或许可以按照 https://ifixit.com 上的教程自行修复。
mrmacete