Window XP驱动开发(十九) windows内核高级调试技巧(双机调试)

转载来源于:http://blog.csdn.net/chenyujing1234/article/details/7739129


欢迎大家拍砖!

在驱动程序的开发中,经常会遇到系统崩溃一情况,我们很难想像用VC的调试器那样单步调试程序。但还是有一些高级驱动程序调试技巧

可以帮助找出驱动程序中的Bug。另外,利用一些第三方工具软件,也可以帮助程序员找到驱动程序中的漏洞,从而提高开发效率。

1、一般性调试

一般性调试技巧包括打印调试信息、查看dump文件等。这些方法在调试驱动中比较常见。

1、1 打印调试信息

1、2 存储dump信息

打印调试信息,可以满足大部分的调试需要,然而有时驱动程序员经常遇到蓝屏死机的困扰,这样即便打印了信息,系统崩溃或重启了,驱动程序员也无未能看到。

这时程序员需要设置Dump信息。所谓Dump信息就是在系统崩溃之前,操作系统会将当前的调用的堆栈记录成一个dump文件,这个文件对于以后的分析极为有用。

右键单击“我的电脑”,选择“属性”,弹出“系统属性”对话框。在对话框中,单击“高级”选项卡,然后单击“设置”按钮,弹出一个对话七一,设置写入调试信息。

如下图:

可以选择“小内存转储”或者“完全内存转储”。其中小内存转储只存储64KB的存储信息,信息量少,而“完全内存转储”则将整个4GB的虚拟内存全部存储下来,

这样虽然信息完整,但耗时。

引起蓝屏死机现象可能有多种情况,引起系统蓝屏,最简单的办法就是在程序代码中加入一行ASSERT(0),从而产生一个断言,继而会产生一个异常。

可以说所有蓝屏都是由各类异常引起的,最常见的是读写空指针、读写不可操作的内存区域等

eg:   在程序中加入一行ASSERT(0),它在check版本中等效于调用RtlAssert函数,而在Free版本中不做任何操作,因此check版本的ASSERT(0) 会引起蓝屏死机.

[cpp]  view plain copy
  1. #pragma PAGEDCODE  
  2. NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,  
  3.                            IN PDEVICE_OBJECT PhysicalDeviceObject)  
  4. {   
  5.     PAGED_CODE();  
  6.     KdPrint(("Enter HelloWDMAddDevice\n"));  
  7.   
  8.     ASSERT(0);  


1、3 使用WinDbg调试工具

(1)

Windbg下载地址:http://dl.dbank.com/c0ypf5ytrh

安装后可能找不到Windbg.exe在哪里?后来发现因为我之前安装了DDK驱动开发文件,在DDK的安装下找到了它。

 (2)也可以用系统默认的自带工具:

Dump信息,必须用专用的工具软件查看,如WinDbg等工具,在使用WinDbg工具时,最好下载系统的符号表。系统的DLL、EXE、SYS、AX等文件,都会有一个

相应的PDB文件,这就是符号表文件,这个PDB是微软在编译Windows时产生的符号表文件,有了这些信息,就可以知道某段代码属于哪个系统文件中的函数了。

首先,在系统环境变量中设置_NT_SYMBOL_PATH环境变量,内容可以设置为:

SRV *d:\symcache*http://msdl.microsoft.com/download/symbols

其含义是以  http://msdl.microsoft.com/download/symbols作为符号表服务器,一旦需要就可以去这个网站下载符号表,下载后将其存储在d:sysmcache目录中。

其次,安装WinDbg软件,该软件可以调试内核程序,同时还可以观察蓝屏后Dump显示出来的信息

 

第一次使用WinDbg调试Dump文件,会等待很长时间,这主要是因为软件会自动到微软网站去下载符号表,即一些PDB文件。

如ntrnlpa.exe就会有对应文件nlknlpa.pdb。程序员自己编写的驱动程序是无法到微软网站下载符号表的,这就需要程序员自己提供了。

参考<<Win7 下分析蓝屏原因的方法>>

 

 

2、高级内核调试技巧

高级内核调试技巧一般用WinDbg进行双机调试,一台作为主机,一台作为目标机。

如果使用虚拟软件,如VMWare或Virtual PC等,可以在计算机中模拟出目标机,这样一台计算机就可以进行内核调试。

2、1 安装VMWare

想像Ring3层的程序一样单步执行,在断点时候观察变量,修改内存,完全知道程序的运行情况,需要费一些周折,

为驱动程序运行在Ring0层程序,调试软件不可能是Ring3层的程序,这与无法在二维空间观察三维空间是一样的。

WinDbg软件,它可以调试应用软件(Ring3层程序)、驱动程序(Ring0层程序)和蓝屏存储文件,但是在调试驱动程序时,WinDbg需要两台计算机调试,

一台作为主机(HOST),一台作为目标机(TARGET),用一根串口线或一条1394的电缆将两台计算机连接起来。

要安装尽量高版本的VMWare,首先在VMWare中安装一个虚拟的Windows,我们以安装Windows XP SP2为例。

安装方法请参考我的另一篇文章:<>

由于是虚拟的PC,并且调试需要一个串口,因此利用虚拟机的虚拟特性,定制一个虚拟串口。

 闭虚拟机,来到VMWare之后选择对应的虚拟机,对齐进行设置。

注意:如虚拟机中在添加新的串口前已经存在串口了,那么要把原有的串口Remove掉(特别是有些打印会占用串口),否则会导致windbg.exe与虚拟机连接不上。

 

使用“虚拟串口”使其建立一条虚拟的串口,一端是虚拟PC的串口COM1,另一端是Window上的管道

另外,在虚拟机中找到启动配置文件boot.ini,去掉这个文件的只读属性,用记事本打开Boot.ini。

在我的虚拟系统中C盘下找不到boot.ini文件,后来从网上得到了解决。解决方法是:

打开电脑属性——高级——启动与故障恢复——在系统启动栏目下选择手动编辑,就打开boot.ini了。

注意:\WINDOWS的前面没有空格,否则启动会出现下面错误:

boot.ini大概的内容如下:

[plain]  view plain copy
  1. [boot loader]  
  2. timeout=10  
  3. default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS  
  4. [operating systems]  
  5. multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect  

上面的Timeout选项为等待时间,可以改短一点,如10,表示等待10秒钟。
在文件的最后增加这样一行内容:

[plain]  view plain copy
  1. multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="XP Debug"  /fastdetect /debug /debugport=com1 /buadrate=115200  

如果要设置默认进入Debug模式,可以把上面这一行内容加到[operating systems]下面:

[plain]  view plain copy
  1.  [boot loader]  
  2. timeout=10  
  3. default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS  
  4. [operating systems]  
  5. multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="XP Debug"  /fastdetect /debug /debugport=com1 /buadrate=115200  
  6. multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect   

之后保存即可。

2、1、1  VMWare对于驱动程序开发除了调用外的其他作用

我们在真的XP环境下开发驱动,经常会遇到蓝屏的现象,这给开发带来很大的痛苦,但是如果将驱动放到虚拟机上运行,如果出现死机就是重启虚拟机,

不会让真机重启,这大大节省了开发难度

 

2、2  Windbg设置

给Windbg创建一个快捷方式,设置一下这个快捷方式的属性:在快捷方式的目标后面增加一些命令,我这里是:

[plain]  view plain copy
  1. "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe" -b -k com:port=\\.\pipe\com_1,baud=115200,pipe  

 

前面的字符串是Windbg的路径,加上后面的命令就可以了。(加入命令  -b 的作用是:在Windbg连接上时就暂停,如果不想马上处于暂停,那么可以把-b去掉。)

之后,最好给Windbg设置一下符号表。打开Windbg,选择菜单项的“File”->“Symbol File Path”,然后填下:

[plain]  view plain copy
  1. srv*c:\Symbols*http://msdl.microsoft.com/download/symbols  

如上图如果我们勾选了Reload,那么相当于输入了.reload命令,这时开始下载:

表示从网上下载系统对应的符号表到C盘的symbols目录下,只有需要的时候才会下载;对于已经下载的以后就直接用这个文件夹里面的符号表了。

当然实际调试驱动时还要加上自己驱动对应的符号表。当然也可以把系统的Symbols从微软的网站上一次性打包下载下来再解压到C盘的Symbols文件夹。从http://msdn.microsoft.com/en-us/windows/hardware/gg463028可以下载到系统对应的符号表(注意是和虚拟机对应的系统版本)
之后关闭Windbg,会提示是否保存,点击是,保存。

不知为何,符号文件下不下来???????

=========================================================================================================================

 现在我们假设你的驱动代码放在D:\mydriver目录中;

系统级Symbol文件存放在C:\WINDOWS\Symbols目录中,这些Symbol文件是从微软的网站上http://msdl.microsoft.com/download/symbols下载而来,这个网址是不可以用IE直接打开的,WinDbgà Fileà Symbol File Path...界面中选择Reload,WinDbg会自动帮你下载;

驱动生成的Symbol文件存放在D:\mydriver\objchk_wxp_x86\i386目录中。

a)     设置驱动Symbol路径,WinDbg->File-> Symbol File Path...为

SRV*C:\WINDOWS\Symbols*http://msdl.microsoft.com/download/symbols; D:\mydriver\objchk_wxp_x86\i386

b)     设置驱动源文件路径,WinDbg->File-> Source File Path…为D:\mydriver

c)     为了保险起见,我们同时设置系统变量。

My Computer -> Properties-> Advanced Tab-> Enviroment Variables-> 

Add._NT_DEBUG_BAUD_RATE=115200

_NT_SYMBOL_PATH=SRV*C:\WINDOWS\Symbols*http://msdl.microsoft.com/download/symbols

_NT_ALT_SYMBOL_PATH = D:\mydriver\objchk_wxp_x86\i386
_NT_SOURCE_PATH = D:\mydriver

14.  启动VMware,将主机目录C:\WINDOWS\Symbols下的拷贝到虚拟机的相同位置。同时请把驱动编译后生成在D:\mydriver\objchk_wxp_x86\i386目录下的*.pdb、*.sys、*.map、*.exp、*.lib文件一并拷贝到两个系统的C:\WINDOWS\Symbols目录中。

=================================================================================================================================

 2、3 测试双机调试环境

先打开虚拟机,开启对应的系统进入调试模式(过了菜单选择时间,进入Debug后会停留几秒钟),

 

选择XP Debug模式, 然后快速双击设置好的Windbg,就会自动连接到虚拟机了,如果Windbg出现如下的提示,那么就OK了:

 调试器显示: Connected to Windows XP 2600 x86 compatible target at (Fri Jul 13 09:32:45.090 2012 (GMT+8)), ptr64 FALSE

,此时代表连接目标成功,处于中断状态

[plain]  view plain copy
  1. Microsoft (R) Windows Debugger Version 6.11.0001.402 X86  
  2. Copyright (c) Microsoft Corporation. All rights reserved.  
  3.   
  4. Opened \\.\pipe\com_1  
  5. Waiting to reconnect...  
  6. Connected to Windows XP 2600 x86 compatible target at (Thu Jul 12 17:06:33.750 2012 (GMT+8)), ptr64 FALSE  
  7. Kernel Debugger connection established.  (Initial Breakpoint requested)  
  8. Symbol search path is: srv*c:\Symbols*http://msdl.microsoft.com/download/symbols;SRV*d:\symcache*http://msdl.microsoft.com/download/symbols  
  9. Executable search path is:   
  10. Windows XP Kernel Version 2600 UP Free x86 compatible  
  11. Built by: 2600.xpsp_sp2_rtm.040803-2158  
  12. Machine Name:  
  13. Kernel base = 0x804d8000 PsLoadedModuleList = 0x805541a0  
  14. System Uptime: not available  
  15. Break instruction exception - code 80000003 (first chance)  
  16. *******************************************************************************  
  17. *                                                                             *  
  18. *   You are seeing this message because you pressed either                    *  
  19. *       CTRL+C (if you run kd.exe) or,                                        *  
  20. *       CTRL+BREAK (if you run WinDBG),                                       *  
  21. *   on your debugger machine's keyboard.                                      *  
  22. *                                                                             *  
  23. *                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *  
  24. *                                                                             *  
  25. * If you did not intend to break into the debugger, press the "g" key, then   *  
  26. * press the "Enter" key now.  This message might immediately reappear.  If it *  
  27. * does, press "g" and "Enter" again.                                          *  
  28. *                                                                             *  
  29. *******************************************************************************  
  30. nt!RtlpBreakWithStatusInstruction:  
  31. 80527da8 cc              int     3  


 

2、4 在虚拟机上加载驱动程序

在进行了上述设置后,就可以进行程序调试了。

2、3、1 首先运行VMWare中的虚拟机软件,然后启动新建立的WinDbg快捷方式,不过WinDbg很快就会停止运行,整个虚拟机也会停止下来,这里需要让虚拟机中的

Windows暂停下来,以便可以用Step in,Step out等方式调试。由于此时在Windows的内核下,且没有Windows源代码,所以看到的都是汇编命令,如下图所示:

 


时候按F5键或者在命令行中输入g,或者单击“运行”图标,都可以让系统运行起来,这里的操作类似于VC的调试界面。

2、3、2  下一步的事情就是把以上编译的驱动程序放到虚拟机上运行。

这里需要首先解决是的如何将文件复制到虚拟机上,为此VMWare为用户提供了一个工具,叫做VMWare Tools,在VMWare上选择菜单“Install VMWare Tool”,

虚拟机会自动安装一个配套的软件插件。

遇到的问题:

我在选择“Install VMWare Tool”时提示

解决方法:

你先把虚拟机关上,然后下载个VMWARE tools6.iso安装文件,直接搜就行了下载完了之后,在虚拟机设置那儿光驱那里选择ISO镜像(如下图),进去之后,

再次选择“Install VMWare Tool”,安装成功了。

 

 

然后在VMWare的工程中,选择“属性”菜单,单击“选项”对话框,选择“共享文件夹”然后选择“Add"按钮,可以为虚拟机设置一个“网络共享”,如下图所示:

 

当为虚拟机设置好共享后,就可以在虚拟机上使用了;

在虚拟机里的资源管理器中输入\\.host\,就可以找到共享目录,这样就可以将PC中的文件复制到虚拟机的里。

 
2、4  VMWare和WinDbg联合调试驱动程序

 这里先了解一下WinDbg的简单使用方法。WinDbg大部分调试都通过命令行方式,即通过输入命令实现。

(1)断点设置:对于设置的一般断点用bp,后面接函数名或者地址名。如bp HelloWDM!

DriveEntry或者bp 0x12345678。对于清除断点用bc。例如,bc * 代表清除所有断点,bc 1代表第1号清除断点。

对于没有加载符号表的驱动程序,可以使用延迟设置断点,用bu;查看断点用bl

例如,bu HelloWDM!DriveEntry。

此时若通过设备管理把设备卸载的话会有以下的信息:

 

(2)符号表设置:如果符号表设置成功,就不需要再设置了,但是符号表有时需要手动设置一下。重新加载符号表使用.reload命令。

使用“lm”显示加载的模块,

“lm v”为每个模块提供更详细的信息,“

!lm ”显示一个详细的模块信息,

“lmo”显示已经加载的模块,

“lml”显示已经加载符号文件的模块,

“lme”显示有符号问题的模块,

“lm m *”显示以一个char过滤的模块(若是M,则为路径过滤)。

手动加载符号表使用.ld命令。

 (3)显示驱动对象的相关信息

(3、1)我们以高度CYUSB.sys以例。首先把我们用到的驱动文件及CyConsole工具拷到虚拟机内。

(3、2)插入我们的CY7C68 USB设备,此时虚拟机会提示是否要把此设备连接到虚拟机上,我们点是。

(3、3)因为是虚拟机第一次接受此USB连接,所以提示需要驱动安装;指定目录让驱动安装。

(3、4)在虚拟机中动行我们的工具CyConsole.exe;

(3、5)在CyConsle.exe运行后马上在真机中的WinDbg中按Ctrl+Break让Target中断下来;因为CyConsole.exe会调用cyusb.sys,所以在Command窗口中输入:

!drvobj cyusb 2  

!drvobj命令类似于SoftICE中的driver命令,用于显示驱动对象的相关信息

这样我们将得到 cyusb.sys 驱动的Dispatch routines信息:

(3、6)知道了卸载例程DriverUnload的入口在0xb2237916,于是我们在0xb2237916处设下断点,在Command窗口中输入:

bp 0xb2237916

输入g,让Target继续跑起来,此时我们把USB拨掉。

此时WinDBG把Target中断了下来,中断之处正是我们刚才设置的例程处00xb2237916:

(3、7)从上图可以看出没有为cyusb.sys加载符号文件,下面我们来加载它的符号

 

 

将A软件安装在虚拟机中,安装完成后,运行A软件,进入注册界面,此时我们在WinDBG中再次按Ctrl+Break,让Target中断下来,A软件的注册算法在驱动程序snbus.sys中DeviceControl例程中(为什么在snbus中的DeviceControl例程中,请自行跟踪应用程序并查看DDK的相关文档就知道了,这里的重点不是Crack软件,而是讲内核驱动的调试),在Command窗口中输入:
!drvobj snbus 2

!drvobj命令类似于SoftICE中的driver命令,用于显示驱动对象的相关信息,具体的用法请参看WinDBG的帮助文档,当我们输入!drvobj snbus 2时,我们将得到这个驱动的Dispatch routines信息:

 

 (4)添加源文件调试的方法

在windbg.exe停下来时:

[plain]  view plain copy
  1. *******************************************************************************  
  2. nt!RtlpBreakWithStatusInstruction:  
  3. 8052c5dc cc              int     3  


 

 

 

现在添加 源文件 和 符号文件 目录

 

File -> Symbol Search Path -> Browse

 

"D:/Test7/NT_Driver/objchk_wxp_x86/i386" 把 Reload 勾上

File -> Open Source File ->Driver.cpp

现在以 DriverEntry 和 HelloDDKUnload 函数为例,设置断点,在 command 中输入 " bu HelloDDK!DriverEntry "

bu HelloDDK!HelloDDKUnload

 

好了,现在输入 g 回车,让操作系统加载起来。

现在在虚拟操作系统里面运行 DriverMonitor ,选择编译好的 sys 文件

 

 

点击 Go 按钮,这时候 真实机器 的 WinDbg 收到消息,转到 DriverEntry 入口函数停止下来。注意粉红色的标记

 

command 窗口显示函数信息:

 

--GetMcast: 6501a8c0 81f29e00
Breakpoint 0 hit
helloddk!DriverEntry:
f8bb2e90 8bff            mov     edi,edi

 

这个时候就可以 按 F10 一步一步执行函数,或按 F11 跳进函数内部查看执行过程。或者按 F5 直接执行到下一个断点处


你可能感兴趣的:(windows驱动,windows,驱动,windows,debug,windbg)