系统开不了机,内核调试器怎么塞进去
做驱动开发那些年,最难受的不是代码写不出来,是出了问题找不到现场。
驱动只在用户那边复现,自己机器上怎么跑都正常。等你把系统要回来,它已经开不了机了 —— 一进系统就蓝屏。
任何蓝屏,只有能挂上调试器,才有解决的可能。
因为蓝屏代码本身几乎不给你信息:7B、7E、D1、50…… 它只把你导向一个分类,网上关于这个分类能搜到一堆说法,但你真正需要的那三件事 —— 是谁、在哪一步、为什么 —— 它一个字都不提。
而系统已经起不来了,调试器挂不上去。
于是三方锁死:
- 要调试 → 得先装内核调试工具
- 要装工具 → 得先能进系统
- 能进系统 → 但一进系统就蓝屏
网上能搜到的手动安装方法,都要求系统还能正常启动(用 bcdedit 敲命令)。系统已经进不来的情况下,那条路走不通。
下面这个做法是我自己摸出来的,XP 到 Win7 都用过很多次。
一、先搞清楚安装程序到底做了什么
virtualKD 的安装程序,本质就干两件事:
- 往系统引导配置里加一个启动项,让系统在启动早期挂起、等调试器连上
- 把调试传输的 DLL(
kdbazis.dll)放进windows\system32
所以它并不神秘 —— 把这两件事手工做一遍,就等于装了它。系统能不能起来,反而无所谓。
二、XP:改 boot.ini
XP 的引导配置就是 boot.ini,直接加一行:
[boot loader]
timeout=5
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="[VKD-Redux]" /DEBUG /DEBUGPORT=bazis /fastdetect /noexecute=optin
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
关键是新加那行的 /DEBUG /DEBUGPORT=bazis —— 它让内核在启动时就打开调试端口、等调试器。
原来那行留着别动,调完还能正常进系统。
三、Win7 及以上:在 PE 里手工改 BCD
从 Vista 开始引导配置换成了 BCD,boot.ini 不再起作用。
进不去的机器就用 PE 启动,拿 BOOTICE 挂上目标系统的 BCD 文件来编辑。
具体加什么?找一个装过 virtualKD 的正常系统,对比一下 BCD 就能看出来 —— 安装程序加出来的那条,关键就是这几个值:
| Element | Value | 作用 |
|---|---|---|
| Description | Disable Signature Enforcement Manually!!! (Press F8) [VKD-Redux] |
启动菜单显示名,带标记方便认 |
| ApplicationPath | \Windows\system32\winload.exe |
走的还是正常加载器 |
| DbgTransportPath | kdbazis.dll |
调试传输用的 DLL,这项指错了就挂不上 |
| KernelDebuggerEnabled | True |
打开内核调试 |
| AllowPrereleaseSignatures | True |
Win7 起必须 —— 不设它,未签名的调试驱动加载会失败 |
| NxPolicy | OptIn |
跟原系统保持一致 |
AllowPrereleaseSignatures=True 这行最容易漏,漏了的表现是引导项在、但调试器死活连不上。
照着这些值,在原来那条启动项旁边新增一条(别改原来那条)。
四、别忘了 DLL
改完引导配置,还要把对应架构的 kdbazis.dll(64 位系统放 64 位的)复制到 windows\system32。
这一步漏了,前面全白做。
五、怎么确认挂上了
启动虚拟机,引导菜单里应该多出一项带 [VKD-Redux] 的。
选它启动,系统会停在启动早期等调试器连接 —— 注意这不是卡死,是在等你。
然后在宿主机上起 vmmon(vmmon64.exe),列表里那台虚拟机的 OS 列应该显示 yes,说明调试传输加载上了。这时候用 windbg 连上去。
如果 OS 列不是 yes,回去查两件事:DbgTransportPath 指对没有、kdbazis.dll 放对位置没有。
六、挂上之后,视角完全变了
这是这套东西真正的价值所在。
挂上之前,你面对的是一个错误码,只能对着它猜:是不是存储驱动?是不是 HAL 不对?网上说的那几种可能性,一个个试。
挂上之后,你面对的是现场:
- 出错时的调用栈 —— 是谁在什么路径上崩的
- 崩在哪个驱动 —— 一眼能看出是三方驱动还是系统自己的
- 启动阶段的问题 —— 设备树、加载了哪些驱动、卡在哪一步,都能翻
我这几年遇到的蓝屏,大部分都能在调试器里直接看出问题,很快就有方向。
也有少部分特别麻烦 —— 内核栈被踩坏了,调用栈整个不可信,栈回溯出来的东西没法直接用。这种就得换路子:从崩溃点附近的代码、寄存器和内存状态往回推。
但即便是这种,你也已经站在现场了 —— 比对着一个错误码猜,确定得多。
"能调试"和"不能调试",就是"有解"和"只能试"的区别。
七、调完记得清掉
调试完把那个引导项删掉,kdbazis.dll 也可以删。
不然每次开机都停在"等待调试器",系统等于半残。
下一篇是这套能力的一次实际应用:一次真实的 7B 蓝屏 —— 挂上调试器之后,我是怎么找到那个设备的。