首页
社区
课程
招聘
[翻译]用 VirtualBox 调试 macOS 内核
发表于: 2017-4-14 14:57 5146

[翻译]用 VirtualBox 调试 macOS 内核

2017-4-14 14:57
5146


更新:awalton 在 Hacker News 上的讨论中提到:VMWare 里可以设置 CPUID 标志来禁用 SMAP,只需要在 vmx 文件中加上cpuid.7.ebx = "-----------0--------------------".

-----------------------------------------------------

上年,我给我的老 MBP 升级了2016年的 Skylake Intel 处理器。我在调试一个内核漏洞时,发现我的 VMWare 开启了“SMAP”(防止超级用户访问)机制。我找不到怎么关闭 SMAP,还好 VirtualBox 目前好像不支持 SMAP?

这篇文章会手把手教你如何用 VirtualBox 进行 macOS 内核的源码级调试。虽然这些步骤都是在 VirtualBox上进行的,但在 VMWare 上也是通用的,甚至更简单。


安装 VirtualBox 和 Sierra

如果你还没在 VirtualBox 上安装 macOS 镜像,你可以复用 VMWare 的 vmdk,也可以装个新的。重新安装系统需要 ISO 镜像,下面的命令可以将从 Mac app store下载的 Sierra 转成 ISO。


网络设置

如果你用了桥接,可以跳过这部分。

如果用的是 NAT,需要为 KDP 开启端口转发。点击“网络”,选择“高级” -> “端口转发”,将 localhost 41139/UDP 转发到虚拟机的 41139/UDP,就能够访问到虚拟机的 41139 端口了。


安装 XCode

在你的主机上安装 XCode,通过 App store 安装最简单。 可以直接打开 XCode,也可以执行 sudo xcodebuild -license accept 接受 XCode license。


安装内核调试组件(KDK)

根据我们要调试的 macOS 版本从 Apple 开发者中心安装 KDK ,这里我的是10.12 build 16A323.

KDK 的安装目录是 /Library/Developer/KDKs ,提供的内核版本、符号、内核扩展都有 RELEASE、DEVELOPMENT、DEBUG 三种版本。不同之处在于 DEVELOPMENT 和 DEBUG 版比 RELEASE 版多了些断言和错误检查,DEBUG 版的最丰富。

注意:被调试的系统不需要安装 KDK。


修改 nvram boot-args

为了能够调试虚拟机,需要设置虚拟机上 nvram 中的 debug 项。除了 debug 的值外其他值也能被我们所用。下面是一些因垂斯挺的选项:

- -v:以 verbose 模式启动系统。

- kcsuffix:填写后缀以指定启动的内核。

- pmuflags:貌似大家都推荐把这项值设为1。然而 Apple's Kernel Programming Guide 已经明确指出管理电源的看门狗定时器“只在台式机、笔记本的 G4 版本和台式机的 G5 版本及之前有作用”,其他的看门狗定时器“只在 OS X Server 中启用”。所以,虽然设置了也不影响,但这个选项真没什么卵用。

- debug:允许远程内核调试。 Apple docs 里有列出可用的标志。我常用的是`DB_LOG_PI_SCRN | DB_ARP | DB_NMI`。另外,`control + option + command + shift + escape` 可以触发不可屏蔽中断(NMI),继而引发调试器中断,超级方便。这对组合键跟 host key 的组合键冲突的时候用起来很难受,所以我把 host key 重新绑定成`command + right`了。

修改 nvram

在 VMware 里,可用这样修改 nvram:

在 virtualbox 里没那么简单,因为一重启修改的值就没了。还好从 virtualbox 手册的 3.13.2 看到了希望:

不能在运行的虚拟机内部操作 EFI 变量了(如:在Mac OS X 虚拟机里运行 nvram 来设置“boot-args”不管用了)。不过,可以通过给虚拟机发送附加数据"VBoxInternal2/EfiBootArgs" 来设置“boot-args”。...

因此,我们需要关闭虚拟机,在主机上运行命令:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//