Debug macOS Kernel
0x00 : 环境配置
基本分为两种情况,虚拟机调试或者双机调试。
虚拟机 : vmfusion
,`` KDK`
双机: 火线。 我这里用的是``mbp2017调
mbp2015,借了同事的线,连接为:
mbp2017-typec-雷电2-火线-雷电2-mbp2015`。
0x01 : 虚拟机
下面是标准步骤
vm
关闭SIP,并且把想要加载的内核拷贝到 内核的目录
sudo cp /Library/Developer/KDKs/KDK_YOUR_VERSION/System/Library/Kernels/kernel.development /System/Library/Kernels
安装当前版本系统的KDK,[Apple Develop KDK download](https://developer.apple.com/download/more/?q=Kernel Debug Kit)
设置启动参数
sudo nvram boot-args="debug=0x14e kext-dev-mode=1 kcsuffix=development pmuflags=1 -v"
清理缓存
sudo kextcache -invalidate /
记住当前vm的ip,然后重启
sudo reboot
这里把development
版本的内核拷贝到System/Library/Kernels
里,指定启动时加载development
版本的内核,当然也可以加载kasan
版本的,看需求。
host
- 安装被调试机器的KDK
这种情况是靠网络调试。
但是根据之前的启动参数,开机时断不下来的,当然可以设置一个0x1来让他启动时断下来等调试器,但是经过测试,这个不好使(可能我环境有问题)。
如果按照上面的设置0x14e
,那么需要在虚拟机中按下 cmd + opt + ctrl + shitf+ esc
触发中断,
随后lldb中 :
1 | $ lldb /Library/Developer/KDKs/KDK_10.13.4_17E199.kdk/System/Library/Kernels/kernel.development |
之后就可以调试了。
0x02 : 双机调试
下面是标准步骤
被调试机
关SIP,拷贝KDK里的内核到
/System/Library/Kernels
安装当前系统版本的KDK
设置启动参数
sudo nvram boot-args="debug=0x14e kdp_match_name=firewire fwkdp=0x8000 kcsuffix=development"
清理缓存
sudo kextcache -invalidate /
重启
sudo reboot
这里必须说一下,火线的名称,ifconfig
里看到的,默认是fw0
,但是这个启动参数里必须是firewire
,
必须是firewire
,必须是firewire
!
这个地方坑了我挺久,我一直以为用ifconfig
里看到的那个名字 :-(
调试机
安装被调试机器的KDK
LLDB加载目标内核
1
2$ lldb /Library/Developer/KDKs/KDK_10.13.4_17E199.kdk/System/Library/Kernels/kernel.development
(lldb)启动fwkdp
fwkdp -v
被调试机按下
cmd+opt+ctrl+shift+esc
触发中断lldb 里连接
(lldb) kdp-remote localhost
感觉过程就是fwkdp
做了转发的工作,所以lldb直接kdp-remote
就可以了。
0x03 : KDK是必须的吗?
并不是,kdk只是给你更多的内核中的符号,所以不用kdk也没事,就等于直接调试正式版的内核,少了内核符号而已,人肉对比着近期版本的源码其实影响没那么大。