Windows内核开发-5-(2)-内核模式调试
Windows内核开发-5-(2)-内核模式调试
Windows内核开发-5-(2)-内核模式调试
普通用户模式的调试,采取的是给进程添加一个线程来挂起断点,作为一个调试器的线程在进程中使用。照这样来类推,对操作系统调试相当于添加一个进程来限制操作系统,所以操作系统是会被冻结的。这样的话就不能直接在本机电脑上进行调试了,不然电脑就卡住了。而且还容易出现问题。最好的办法是创建一个虚拟机,用一台主力机给一台专门用来测试的计算机调试。
测试机和主力机必须通过一种方式来连接,选择有很多,最好的选择是通过网络连接,但是网络连接要求target和host至少是Win8以上,Win7就很尴尬了,但是由于这个很多搞安全的要求兼容,就会很麻烦。以至于很多采用串口连接,这里我们将如何建立串口连接。
还有需要注意的就是这个操作系统的版本和位数。你要开发什么样子的就用什么样子的操作系统。比如说:你要开发一个在Win10 64位计算机上用的东西,你就装一个Win10 64位虚拟机。虽然大部分都有兼容的效果,比如在64位上能跑32位的程序,但是还是建议采用对应的操作系统版本。
搭建内核模式调试环境
这里我采用的是Win10 32位虚拟机,和Win10 64位本机,采用串口连接。
下载操作系统
这个在msdn上下载你需要的对应版本的操作系统就好:
https://msdn.itellyou.cn/,安装虚拟机如果不清楚就自行百度一下。
添加启动引导
给测试机添加启动引导,需要使用管理员模式启动命令行:
cmd管理员身份运行bcdedit
bcdedit /copy {current} /d Sna1lGo//这里的Sna1lGo是引导名称,自己随意设置。

bcdedit /displayorder {xxxxx-xxxx-xxx} /addlast //这里的xxx是你在设置了引导名称后的一长条字符串
//这里的addlast是引导的位置,last表示是最后
bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 //设置调试端口波特率
bcdedit /debug {xxxxx-xxxx-xxx} ON//对新加的启动项增加调试功能
bcdedit /timeout 20//选择等待时长
设置完成后,再开机就有系统启动引导了。
虚拟机设置:
添加串行端口:(如果你的虚拟机里面有打印机,打印机默认会占用一个名为//./pipe/com_1的串行端口)
命名随意,只要是//./pipe/xxx就行,这里我采用的是把打印机移除掉,然后命名为//./pipe/com_1。
WinDbg配置
给WinDbg配置当启动的时候自动连接到测试机。首先根据测试机的位数选择同样的WinDbg,这里我选择32位的WinDbg,然后弄了一个快捷方式在桌面。
快捷方式这里有一个目标,在这个目标的后面添加参数:
-k com:port=//./pipe/com_1,baud=115200,pipe
这里的参数是和前面一一对应的,如果有问题就自己找找前面的定义。然后就可以直接运行WinDbg来调试Windows了。
给WinDbg配置符号
符号就是说函数名称的配置,如果不配置函数名称不完整,大概可以先这样理解。
在WinDbg中选择Symbol Search Path(快捷键Ctrl+S):
然后输入:
srv*D:\symbol*;srv*D:\symbol*http://msdl.microsoft.com/download/symbols
这段指令的意思是,会在D:\symbol中存储符号表,如果没有就到后面那个http:地址下载,然后存放到前面那个地址,这个存放的地址可以自己选择。然后就完美了,大功告成。
开始内核调试:
这里采用之前在第四章写的简单完整驱动来调试。
然后将生成的sys和pdb文件一起复制到虚拟机里面,然后安装驱动但是不加载驱动。参考该博客来安装驱动:
进入WinDbg后,给我们自己写的入口函数打一个断点:
bu prioritybooster!driverentry
这里采用的是bu断点:bu 命令是针对某个符号下断点。 比如 bu MyApp!SomeFunction 。 在代码被修改之后, 该断点可以随着函数地址改变而自动更新到最新位置。 而且bu 断点会保存在WinDbg工作空间中, 下次启动 Windbg 的时候该断点会自动设置上去。另外,在模块没有被加载的时候,bp 断点会失败(因为函数地址不存在),而bu 断点则可以成功。 新版的WinDBG中 bp失败后会自动被转成bu 。
打下断点后,我们在WinDbg命令行中输入g,让系统跑起来,然后再在系统中去加载该驱动。
如果一切顺利的话会出现下面这样:
就可以像一些平常的调试器一样来调试东西了。
输入k指令来查看堆栈:
1: kd> k
# ChildEBP RetAddr
00 8985fad8 81dac709 PriorityBooster!DriverEntry [D:\ProjectSum\Driver\PriorityBooster\PriorityBooster.cpp @ 14]
01 8985fbc8 81e3552c nt!IopLoadDriver+0x443
02 8985fbe8 81aefa6a nt!IopLoadUnloadDriver+0x42
03 8985fc38 81abe0f0 nt!ExpWorkerThread+0xea
04 8985fc70 81b9a18d nt!PspSystemThreadStartup+0x4a
05 8985fc7c 00000000 nt!KiThreadStartup+0x15
如果断点似乎无法设置,则可能是符号问题。 执行 .reload 命令重新加载符号来查看问题是否已解决。 在用户空间设置断点也是可能的,但首先执行 .reload /user 来解决这个问题。
还可以在命令中添加-p来限制给某某进程打断点,总之WinDbg非常强大,好好学习吧。
总结: