Debugging macOS Kernel For Fun
字数 1222 2025-08-18 11:36:57
macOS内核调试指南
1. 准备工作
1.1 硬件要求
- 调试目标机(被调试机器):如iMac 2011
- 调试主机(运行调试器的机器):如MacBook Pro 2009
- 连接方式:Firewire电缆(或通过Thunderbolt适配器的Firewire)
1.2 软件准备
- 下载与目标机macOS版本匹配的内核调试工具包(KDK)
- 访问Apple Developer Portal Downloads
- 必须与目标机的macOS版本和构建编号完全匹配
1.3 确定系统版本
- 点击Apple logo > "About This Mac"查看版本号(如10.13.6)
- 获取构建编号:
输出示例:sw_vers | grep BuildVersionBuildVersion: 17G65
2. 配置调试目标机
2.1 安装KDK
- 挂载下载的DMG文件
- 安装kerneldebugkit.pkg
- 安装完成后,文件位于:
/Library/Developer/KDKs/kdk_<version>_<build>.kdk
2.2 替换内核
- 将
kernel.development复制到系统目录:cp /Library/Developer/KDKs/kdk_10.13.6_17G65.kdk/System/Library/Kernels/kernel.development /System/Library/Kernels/
2.3 禁用SIP
- 重启进入恢复模式(开机时按CMD+R)
- 在恢复终端中执行:
csrutil disable - 正常重启
2.4 设置引导参数
根据连接方式选择适当的boot-args:
物理FireWire端口:
sudo nvram boot-args="debug=0x8146 kdp_match_name=firewire fwdebug=0x40 pmuflags=1 -v"
Thunderbolt适配器的FireWire:
sudo nvram boot-args="debug=0x8146 kdp_match_name=firewire fwkdp=0x8000 fwdebug=0x40 pmuflags=1 -v"
参数说明:
debug=0x8146:启用调试,允许通过电源按钮触发NMIkdp_match_name=firewire:允许通过Firewire调试fwkdp=0x8000:使用Thunderbolt至FireWire适配器fwdebug=0x40:启用详细输出pmuflags=1:禁用看门狗定时器-v:启用详细启动模式
3. 配置调试主机
- 在调试主机上安装相同的KDK(不修改主机内核)
- 不需要设置引导参数
4. 开始调试会话
4.1 启动调试目标机
- 重启目标机,进入详细启动模式
- 看到"DSMOS has arrived!"消息后,按一次电源按钮触发NMI
4.2 在调试主机上操作
-
启动FireWire KDP工具:
fwkdp -v输出应显示"Ready"并监听连接
-
启动LLDB并加载开发版内核:
xcrun lldb /Library/Developer/KDKs/KDK_10.13.6_17G65.kdk/System/Library/Kernels/kernel.development -
在LLDB中加载调试脚本:
settings set target.load-script-from-symbol-file true -
连接到目标机:
kdp-remote localhost -
继续执行内核(按'c'键)
5. 调试操作示例
5.1 寄存器操作
-
读取所有寄存器:
register read --all -
写入寄存器:
register write r13 0x4141414141414141
5.2 修改内核版本信息
-
查找version常量地址:
print &(version) -
查看当前内容:
x <address> print version -
修改内存内容(示例修改为"GeoSn0w Kernel"):
memory write 0xffffff802f0f68f0 0x47 0x65 0x6f 0x53 0x6e 0x30 0x77 0x20 0x4b 0x65 0x72 0x6e 0x65 0x6c 0x20 0x56 memory write 0xffffff802f0f6900 0x65 0x72 0x73 0x69 0x6f 0x6e 0x20 0x36 0x39 0x2e 0x30 0x30 0x20 0x57 0x65 0x65 -
验证修改:
uname -a
6. 恢复原始配置
-
重置引导参数:
sudo nvram boot-args="" -
删除开发版内核:
rm /System/Library/Kernels/kernel.development -
使KextCache无效:
sudo touch /Library/Extensions sudo touch /System/Library/Extensions -
重新启用SIP(可选):
- 进入恢复模式
- 执行:
csrutil enable
附录:调试标志位定义
参考/osfmk/kern/debug.h中的定义:
#define DB_HALT 0x1
#define DB_NMI 0x4
#define DB_KPRT 0x8
#define DB_KDB 0x10
#define DB_ARP 0x40
#define DB_KDP_BP_DIS 0x80
#define DB_KDP_GETC_ENA 0x200
#define DB_KERN_DUMP_ON_PANIC 0x400
#define DB_KERN_DUMP_ON_NMI 0x800
#define DB_DBG_POST_CORE 0x1000
#define DB_PANICLOG_DUMP 0x2000
#define DB_REBOOT_POST_CORE 0x4000
#define DB_NMI_BTN_ENA 0x8000
#define DB_PRT_KDEBUG 0x10000
#define DB_DISABLE_LOCAL_CORE 0x20000
#define DB_DISABLE_GZIP_CORE 0x40000
#define DB_DISABLE_CROSS_PANIC 0x80000
#define DB_REBOOT_ALWAYS 0x100000
通过组合这些标志位可以设置不同的调试行为。