Debug macOS Kernel

0x00 : 环境配置

基本分为两种情况,虚拟机调试或者双机调试。

虚拟机 : vmfusion,`` KDK`

双机: 火线。 我这里用的是``mbp2017mbp2015,借了同事的线,连接为:mbp2017-typec-雷电2-火线-雷电2-mbp2015`。

0x01 : 虚拟机

下面是标准步骤

vm

  1. 关闭SIP,并且把想要加载的内核拷贝到 内核的目录

    sudo cp /Library/Developer/KDKs/KDK_YOUR_VERSION/System/Library/Kernels/kernel.development /System/Library/Kernels

  2. 安装当前版本系统的KDK,[Apple Develop KDK download](https://developer.apple.com/download/more/?q=Kernel Debug Kit)

  3. 设置启动参数

    sudo nvram boot-args="debug=0x14e kext-dev-mode=1 kcsuffix=development pmuflags=1 -v"

  4. 清理缓存

    sudo kextcache -invalidate /

  5. 记住当前vm的ip,然后重启

    sudo reboot

这里把development版本的内核拷贝到System/Library/Kernels里,指定启动时加载development版本的内核,当然也可以加载kasan版本的,看需求。

host

  1. 安装被调试机器的KDK

这种情况是靠网络调试。

但是根据之前的启动参数,开机时断不下来的,当然可以设置一个0x1来让他启动时断下来等调试器,但是经过测试,这个不好使(可能我环境有问题)。

如果按照上面的设置0x14e ,那么需要在虚拟机中按下 cmd + opt + ctrl + shitf+ esc触发中断,

随后lldb中 :

1
2
$ lldb /Library/Developer/KDKs/KDK_10.13.4_17E199.kdk/System/Library/Kernels/kernel.development
(lldb)kdp-remote you_vm_ip

之后就可以调试了。

0x02 : 双机调试

下面是标准步骤

被调试机

  1. 关SIP,拷贝KDK里的内核到/System/Library/Kernels

  2. 安装当前系统版本的KDK

  3. 设置启动参数

    sudo nvram boot-args="debug=0x14e kdp_match_name=firewire fwkdp=0x8000 kcsuffix=development"

  4. 清理缓存

    sudo kextcache -invalidate /

  5. 重启

    sudo reboot

这里必须说一下,火线的名称,ifconfig里看到的,默认是fw0,但是这个启动参数里必须是firewire

必须是firewire,必须是firewire

这个地方坑了我挺久,我一直以为用ifconfig里看到的那个名字 :-(

调试机

  1. 安装被调试机器的KDK

  2. LLDB加载目标内核

    1
    2
    $ lldb /Library/Developer/KDKs/KDK_10.13.4_17E199.kdk/System/Library/Kernels/kernel.development
    (lldb)
  3. 启动fwkdp

    fwkdp -v

  4. 被调试机按下cmd+opt+ctrl+shift+esc触发中断

  5. lldb 里连接

    (lldb) kdp-remote localhost

感觉过程就是fwkdp做了转发的工作,所以lldb直接kdp-remote就可以了。

0x03 : KDK是必须的吗?

并不是,kdk只是给你更多的内核中的符号,所以不用kdk也没事,就等于直接调试正式版的内核,少了内核符号而已,人肉对比着近期版本的源码其实影响没那么大。