内核调试入门
内核程序运行在内核态,因此不能像对用户态应用程序那样来调试。关于内核调试方面的知识请参考《软件调试》这本书。目前内核调试主要有以下三种方法。
一是使用硬件调试器,它通过特定的接口(如 JTAG)与 CPU 建立连接并读取它的状态,例如 ITP 调试器。
二是在内核中插入专门用于调试的中断处理函数和驱动程序。当操作系统内核被中断时,这些中断处理函数和驱动程序接管系统的硬件,营造一个可以供调试器运行的简单环境,并用自己的驱动程序来处理用户输入、输出,例如 SoftICE 和 Syser 等调试器。
三是在系统内核中加入调试支持,当需要中断到调试器中时,只保留这部分支持调试的代码还在运行,因为正常的内核服务都已经停止,所以调试器程序是不可能运行在同一个系统中的,因此这种方法需要调试器运行在另一个系统中,二者通过通信电缆交流信息。
Windows操作系统推荐的内核调试方式是第三种,这种方法需要在被调试系统和调试系统之间建立连接,迄今为止共有三种连接方式:串行口、1394 和 USB2.0。
起初,内核调试大多通过双机调试进行。随着虚拟机技术的广泛使用,双机调试逐渐被虚拟机调试所取代。本节介绍一种非常方便的虚拟机内核调试方法—— "利用命名管道(Named Pipe)模拟串行端口"。具体地说,就是在虚拟机中虚拟一个串行端口,并且把这个串口映射到宿主机的命名管道上。这样一来,虚拟机中所有对该串口的读写操作都会被虚拟机管理软件转换为对宿主系统中的命名管道的读写,运行在宿主系统中的调试器便可以通过这个命名管道来与虚拟机中的内核调试引擎进行通信。
这种虚拟机调试内核的方法实现了单机调试,其优点是简单方便,但也存在一些缺点,一是难以调试硬件相关的驱动程序;二是当对某些涉及底层操作(中断、异常或者 I/O)的函数或指令设置断点时,可能导致虚拟机意外重启;三是当将目标系统中断到调试器中时,目前的虚拟机管理软件会占用非常高的 CPU,超过 90%。不过总的来说,这种调试方法足以调试目前公布的内核漏洞了。
下面我们来介绍一下,如何使用 WinDbg 和 VMware 来实现这种方法的调试。VMware Support 中提到,自 4.0.18.0 版本之后的 WinDbg 都支持了通过 pipe 来进行调试。