经过了好几天的挣扎,终于把VMware+WinDbg双机联合调试Windows驱动的环境,和调试方法搞通了。为了以后使用方便,特意单独写一篇文档。分以下步骤来搭建环境:
1.试验的环境
系统是XP,sp3。Vista的环境没有试验过。
笔记本,没有串口。
该实验是建立在早期报告基础之上的,默认你的系统已经安装了WDK(DDK),DriverStudio和相应的工具软件。如果你没有安装,请参考早期的报告。
2.需要的软件
dbg_x86_6.11.1.402.msi这个可以再微软的官方网站上下载。是windbg的一个版本,免费的(http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.11.1.402.msi)。
WindowsXP-KB936929-SP3-x86-symbols-update-ENU.exe这个是符号链接库
可以到微软的官方网站上下载。(http://msdl.microsoft.com/download/symbols/packages/windowsxp/WindowsXP-KB936929-SP3-x86-symbols-update-ENU.exe)
VMware6.5.1 build-126130,更高的版本应该也是兼容的。这个网上随处可以下载。安装和使用不再本文讨论范围之内。
一个Windows XP的ISO文件,以备安装虚拟机使用。
3.软件的安装
安装VMware。
用VMware安装一个Windows XP的虚拟机。在虚拟机中安装VC6和DriverStudio3.2。暂时可以不用安装WDK,以后如果需要安装,需要把DriverStudio卸载之后再安装WDK,然后再把DriverStudio装上。
把Windbg软件包安装到C:/Program Files下,以便和以后的讨论相一致。
把符号链接库的软件包安装到默认目录下,应该是C:/WINDOWS/Symbols
4.设置虚拟机
修改boot.ini文件。如果在C盘中找不到这个文件还有一种方法找到。在虚拟中右击我的电脑->属性->高级->启动和故障恢复->设置->编辑。这样就会用记事本打开这个boot.ini文件了。
在里面[operating systems]节中新加入一行,不删除原来那一行。
"multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Microsoft Windows XP Professional Debug" /fastdetect/debugport=com1 /baudrate=115200 /noguiboot"
(添加时把引号去掉)
随后关闭虚拟机系统。配制虚拟机的硬件。在Vmware菜单上点击 "VM ",选择settings。再选择ADD,添加一个Serial Port,选择"Output to named pipe",然后下一步,
第一框里保持默认的 "//./pipe/com_1"
第二框里选"This end is the server."
第三框里选"The other end is an application."
选中 "Connect at power on"
选中 "Yield CPU on poll"。保存退出。
好了,以上就是虚拟机系统要做的全部事情。
5.修改真实系统
右击我的电脑,管理,设备管理器,端口。然后再属性页中修改他的速率为115200。
上面是有串口的机子的设置,我的笔记本没有串口,一开始想用软件虚拟一个串口,但是后来发现,不用管真实系统的com1,也可以完成相同的任务。
创建一个WinDbg的快捷方式。快捷方式的命令行为
"C:/Program Files/Debugging Tools for Windows (x86)/windbg.exe" -y C:/Windows/Symbols/ -b -k com:port=//./pipe/com_1,baud=115200,pipe
创建方法是:在桌面空白处右击,新建,快捷方式,在”浏览”前面的空白处把上面的文字复制进去。如果软甲的安装路径不同,自行调整。
6.初次运行
运行前面的XP虚拟机,会看到两个系统,其中一个是调试用系统,按一下上下键,使得读秒停止。进入调试系统,不等系统启动,在真实系统中打开Windbg快捷方式。这时会看到类似下图的信息。
:
此时,你可以看到虚拟机已经停止了,进入了调试状态。在Windbg的command窗口的最下面的编辑框中输入:g然后按下Enter键。这样虚拟机就在此运行了。(可能会启动的很慢,不要着急)
如果想让虚拟机再次停止,可以按下Windbg的菜单上的Debug的Break命令(Ctrl+Break)。这样你就可以控制虚拟的停止和继续运行了。
7.单步调试一个HelloWDM.sys驱动程序
准备一个名字为”1”的文件夹放在D盘下,作为工程所在的文件夹,编写一个驱动程序,并且编译出HelloWDM.sys,编译的具体方法参考前期的文档。如果你是用build命令编译的,正好符合本次的实验。如果你是用VC编译的,要做一些工作。也就是用DDK sources to vcproj Converter工具把.dsw文件或者.dsp文件转化为SOURCES文件,MakeFile文件所有的驱动都是基本一样的,随便考一份就行。这样保证你的”1”文件夹中有.cpp,.h,MakeFile,SOURCE,有了这些文件之后就可以用Windows XP Checked Build Environment工具编译出.sys文件和
“objchk_wxp_x86”问价夹,.sys和.pdb文件就在这个文件夹中。其中.pdb文件是调试时需要的链接库。
现在修改WinDbg的参数,如果直接用之前建立的快捷方式来打开WinDbg会产生一个错误。需要先打开虚拟机,选择虚拟机的调试模式来启动,在虚拟机黑屏还未启动时,打开WinDbg。这时会看到步骤6中图片的信息。表示真实主机已经和虚拟机连接成功。连接成功后,虚拟机停止运行,进入类似死机的状态。等到Windbg的conmmand窗口的最下边编辑框的状态非”BUSY”,出现”kd>”时,键入”g”再按下”Enter”确认。虚拟机会继续运行。这时可以修改Windbg的参数了。
选择Windbg的File->Symbol File Path通过编辑或者Browse把内容改为以下:
C:/Windows/Symbols/;C:/MyLocalSymbols;SRV*C:/MyLocalSymbols*http://msdl.microsoft.com/download/symbols;D:/1/objchk_wxp_x86/i386
选择”OK”,确认更改。请再次打开上面的内容,确认已经修改为上面的内容。因为我在修改时,虽然”Ok”了,但是再次打开仍然没有变。多试几次就行了。
用菜单命令或者”Ctrl+Break”把虚拟机停止,然后在command中键入
“.reload”(不包括引号)。等待把符号链接加载完毕,一些库需要从微软的网站下载(你的机子要能够上网才行),需要很多的时间,慢慢等待。等到加载完后,键入”lm”命令看看是不是大部分pdb文件已经加载完毕,如果不是,再次用”.reload”命令多加载几次。我的机子最终还是会出现几个Error,不过没有关系(现在还不知道怎样改,以后如果真正用到,在想办法,如果解决了,会在以后的文档中提到)。我加载完毕后”lm”后出现下面的画面:
选择Windbg中的File->Source file Path把内容改为:
D:/1
即你的工程所在的文件夹。然后用Windbg的File->Open Source File打开
1文件夹的HelloWDM.cpp文件。
如果conmmand窗口的下面的编辑框有”kd>”,键入命令:
”bu HelloWDM!DriverEntry”(所有的命令都不包括引号) 就是在入口函数处设置一个断点。
在conmmand窗口中键入命令:”g”使得虚拟机继续运行。把D盘中的”1”文件夹拖拽到虚拟机的桌面上,也就是复制到虚拟机中一个副本。用虚拟机中DriverStudio自带的DriverMonitor工具打开HelloWDM.sys,start这个驱动。
这时会发现,虚拟机停止运行了。查看Windbg中的信息,可以看到之前打开的HelloWDM.cpp文件的窗口有一行红色加亮了,表明驱动运行到这一行停止了。这时可以用F10,F11的常用的命令来调试你的驱动程序了。并且可以用Watch窗口产看变量的信息了。
8.总结
本文参考了一些网上和书上的介绍,综合了《Windows驱动技术开发详解》、《寒江独钓-Windows内核安全编程》、CSDN博客等众多的资料最终调试成功。本文使用的HelloWDM.cpp及工程是《Windows驱动技术开发详解》书上的的第一章chapter01/WDM_Driver/1的工程。
感谢前辈们想出如此精妙的调试方法(据说是从国外的某网站论坛最先继承而来的)。