macOS 内核扩展编程初探
什么是 macOS 内核扩展(KEXT)?macOS 内核扩展是一种动态链接库(通常后缀为 .kext),用于扩展 XNU 内核的功能。KEXT 可被用于编写驱动程序、系统安全模块、文件系统支持等底层功能。
在 macOS Catalina(10.15)之后,Apple 推出 System Extensions 和 DriverKit,逐步替代传统 KEXT,但 KEXT 仍广泛用于底层研究和安全相关开发。
开发环境准备要在 macOS 上开发内核扩展,你需要以下工具和配置:
内核签名的苹果开发者账号
禁用 SIP(System Integrity Protection)
进入恢复模式 执行 csrutil disable
在自己的实验机器上加载不签名禁用 SIP 也能运行
启用开发者 KEXT 加载权限:
进入恢复模式禁用安全策略
创建第一个 KEXT 工程
打开 Xcode
选择 File > New > New Project。弹出新建工程面板
选择 macOS > Generic Kernel Extension。创建内核扩展工程
输入“HelloKext”作为内核扩展名称,输入Bundle ID,点击继续。
HelloKext.cpp12345678910111213141516#include
在编写内核扩展时,只能使用Kernel.framework中包含的头文件。应用其它Framework可能会导致扩展无法加载或执行失败
使用 IOLog 打印信息,可以通过 Console.app 或 log show 查看
编译内核扩展
和编译普通 Xcode 工程一样,Command+B 快捷键编译就完成了。
打开 Terminal,进入到新编译的内核扩展所在目录。
执行命令 kextlibs -xml HelloKext.kext, 把返回的结果填入内核扩展的Info.plist中。12345
加载内核扩展
修改 root:wheel 用户 1sudo chown -R 0:0 HelloKext.kext
加载前可以用命令 kextutil -print-diagnostics HelloKext.kext 检查一遍扩展, 第一次加载 · 需要在系统便好设置中审批扩展启动,并重启
执行命令 log show --predicate 'senderImagePath contains "HelloKext"' --info 查看日志
执行命令 sudo kextload HelloKext.kext,加载内核,发现日志HelloKext loaded.打印了出来。
执行命令 kextstat | grep -v com.apple, 可以看到自己的内核模块的确加载成功了。
执行命令 sudo kextunload HelloKext.kext ,卸载内核,发现日志HelloKext unloaded.打印了出来。
/Library/Extensions 目录下会开机自动加载
注意事项与后续替代由于 Apple 加强了系统安全策略,从 macOS 11 Big Sur 起,传统 KEXT 开发受限。建议:
新驱动程序使用 DriverKit;
安全模块迁移到 System Extensions;
不推荐在主力机器上加载未签名 KEXT。
参考资料
Implementation of a Kernel Extension (KEXT)