什么是 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.cpp
1 |
|
在编写内核扩展时,只能使用Kernel.framework中包含的头文件。应用其它Framework可能会导致扩展无法加载或执行失败
使用 IOLog 打印信息,可以通过 Console.app 或 log show 查看
编译内核扩展
- 和编译普通
Xcode
工程一样,Command+B
快捷键编译就完成了。 - 打开
Terminal
,进入到新编译的内核扩展所在目录。 - 执行命令
kextlibs -xml HelloKext.kext
, 把返回的结果填入内核扩展的Info.plist
中。1
2
3
4
5<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.iokit</key>
<string>21.6</string>
</dict>
加载内核扩展
- 修改
root:wheel
用户1
sudo 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
。