收藏 分享(赏)

kernel_debugging_tutorial.doc

上传人:hyngb9260 文档编号:6751183 上传时间:2019-04-22 格式:DOC 页数:44 大小:1.21MB
下载 相关 举报
kernel_debugging_tutorial.doc_第1页
第1页 / 共44页
kernel_debugging_tutorial.doc_第2页
第2页 / 共44页
kernel_debugging_tutorial.doc_第3页
第3页 / 共44页
kernel_debugging_tutorial.doc_第4页
第4页 / 共44页
kernel_debugging_tutorial.doc_第5页
第5页 / 共44页
点击查看更多>>
资源描述

1、Kernel Debugging Tutorial 2005 Microsoft Corporation 1使用 WinDbg 内核调试看雪学院,笨笨雄译安装程序基础挑选技术取得更多信息WINDOWS 调试工具很强大,但是学习使用它们并不容易。特别对于驱动开发者使用的 WinDbg 和 KD这两个内核调试器(CDB 和 NTSD 是用户态调试器)。本教程的目标是给予一个已经有其他调试工具使用经验的开发者足够信息,使其能通过参考 WINDOWS 调试工具的帮助文件进行内核调试。本文将假定开发者熟悉一般 WINDOWS 操作系统和进程的建立过程。本文的重点是集成内核模式和用户态模式的图形化调试器

2、WinDbg。KD 在脚本和自动化调试中更有用,并且在资深程序员中拥有一定地位,但是本教程将集中讨论 WinDbg,只会偶尔提到 KD。本文讨论的是 Windows NT 4.0,Windows 2000 或以后的版本,而且目标电脑的处理器基于 X86 架构。对于 64 位平台,将不会特别提及。总之,本教程由简单介绍调试器的安装开始,大体分成 2 部分,基础知识和选择技术。基础知识包括基本调试命令和常用调试命令。选择技术是其他命令和在很多情况下都有用的调查方法。后者并不是调查象deadlocks, memory corruption 或者 resource leaks 的唯一方法。第一次阅读本

3、教程,你可能会跳过选择技术。你可以停止阅读本教程而转向微软调试器讨论组,也可以通过调试器的反馈 e-mai 解决更多的问题。 安装程序取得最新版!取得最新版的调试器,并且有规律的更新它。这里并没有夸大最新版的价值,因为调试器会经常改进和修复错误。你将能在下面网址下载: http:/ null-modem cable 或者 1394 cable 连接两台电脑的安装方案 。本教程不分析单操作系统的本地调试(即在调试器运行的电脑上进行分析)。3 台电脑(目标电脑,调试服务器,调试客户端)的调试将会被简要的讨论。在主机调试软件(WinDbg 或者 KD)和目标操作系统之间,是一个协同处理的调试过程。每

4、一部分都必须做些什么。更明确地,WinDbg 不是作为一个“管理操作系统”,象客户和一个真正操作系统那样运行目标。WinDbg 是一个调试软件,象目标操作系统的合作伙伴那样知道它在调试过程中的角色。在这种关系中,WinDbg 从目标接收信息,并且向目标发送信息。这是一种有效的通信机制。Kernel Debugging Tutorial 2005 Microsoft Corporation2serial protocol 是调试器与目标系统之间可靠的通信机制。你能通过 null-modem cable 使用 COM 端口连接主机和目标机器。另一个可供选择的通信机制是 1394。在调试工具的帮助文

5、件中的“Configuring Software on the Target Computer.” 主题有关于它们的描述。 你的第一次 session假设你的主机使用 WIN2K 或以上的版本。主机的操作系统可以不同于目标电脑的操作系统。主机可以在你平常进行开发,维护或者故障诊断的地方。它应该与网络连接,如果你希望访问 symbol 和 source 服务器(请看 symbols 和 source)。从命令提示窗口中,改变当前的目录到 WINDOWS 调试工具的安装目录。这是 windbg.exe 和 kd.exe 所在的位置。输入 windbg,按下 Enter。你将会看到: Kernel

6、Debugging Tutorial 2005 Microsoft Corporation 3分屏在这里,你能重排你的窗口。下面的例子包括可移动的窗口。打开组合窗口并移到屏幕上方,单击“Command”标题栏并拖动它的窗口离开主框架。然后收缩主框架,你可以使用键击代替直接使用菜单或者按钮。然后使用 FileKernel Debug 以得到一个协议窗口,选择 1394 和 channel 1。到这里,你的桌面会象下图一样:Kernel Debugging Tutorial 2005 Microsoft Corporation4在 Kernel Debugging 窗口中,点 OK。激活连接现在你

7、已经准备好在主机和目标之间建立连接。在目标机器以其中一个调试入口启动 WINDOWS。立即回到主机系统,用鼠标激活 WinDbg 的命令窗口,按下 CTRL+BREAK 。不久之后,你会看到:现在不必担心关于 symbols 的信息。你已经将 WinDbg 连接到 WIN 2003。你现在很忙!你需要明白一件细小却至关重要的事:在命令窗口的底部显示“kd”提示符。这代表 WinDbg 已经准别好接受命令。如果没有提示符显示,这时 WinDbg 将不能处理命令,尽管你输入的任何命令都将会被保存在缓冲区域并尽可能快的运行。你必须等待“kd”出现,以确定 WinDbg 已经作好响应的准备。因为有时它

8、正在忙于做某些你看不见的事(例如从目标取得信息,该信息可能很庞大)。缺少“kd”是 WinDbg 处于繁忙状态的唯一线索。另一个可能是 WinDbg 试图解析 symbol 并且时间超过了你的预期。不幸地,WinDbg 偶尔会等待一个永远不会响应的目标连接(可能 boot.ini 配置得不好,或者选择了错误的选项)。在等待足够时间之后,你必须决定采取激烈的措施例如按下 CTRL+BREAK,或者停止 WinDbg 重新开始。Kernel Debugging Tutorial 2005 Microsoft Corporation 5查找 symbols 和 source现在你很可能渴望开始调试,

9、但仍然有一些东西你必须去做,因为它们将会很好的改善你的调试体验。首先确认 WinDbg 能找到你感兴趣模块的 symbols。Symbols 指出一个二进制命令与声明之间的联系和什么变量正在被转移。换句话说,就是 Symbols 表。如果你在建立模块的地方,那么你将拥有有效的symbols 和 source 文件。但是如果你需要单步调试其他很早以前建立代码呢?或者,在那种情况下,如果你的代码不在它被建立的地方呢?明确的设置 symbols 所在的地方,使用.sympath 命令。在命令窗口中中断(CTRL-BREAK)然后输入:.sympath SRV*http:/ WinDbg 在 Micr

10、osoft 公开的 symbols 服务器上查找 symbols。让 WinDbg 使用该服务以及在本地保存一份已下载的 symbols。例如,在 D:DebugSymbols,你应该这么做:.sympath SRV*d:DebugSymbols*http:/ symbols 服务器上获取 symbols 时遇到一些故障。在这个情况下,使用!sym noisy 命令以获得关于 WinDbg 尝试获取 symbols 的更多信息。然后使用 !lmi 查看 WinDbg 知道多少关于 ntoskrnl的信息。然后尝试取得 ntoskrnl 的 symbols,使用.reload /f。因而:kd

11、!sym noisynoisy mode - symbol prompts onkd !lmi ntLoaded Module Info: nt Module: ntoskrnlBase Address: 80a02000Image Name: ntoskrnl.exeMachine Type: 332 (I386)Time Stamp: 3e80048b Mon Mar 24 23:26:03 2003Size: 4d8000CheckSum: 3f6f03Characteristics: 10e Debug Data Dirs: Type Size VA PointerCODEVIEW 2

12、5, ee00, e600 RSDS - GUID: (0xec9b7590, 0xd1bb, 0x47a6, 0xa6, 0xd5, 0x38, 0x35, 0x38, 0xc2, 0xb3, 0x1a)Age: 1, Pdb: ntoskrnl.pdbImage Type: MEMORY - Image read successfully from loaded memory.Symbol Type: EXPORT - PDB not foundLoad Report: export symbols在 WINDOWS 调试工具帮助文件中,有关于这里使用的命令及其语法的描述。输出 symbo

13、ls 通常很大。WINDOWS 调试工具包括一个 symbol 服务器,以便连接到 Microsoft 的网络服务器保存这些公开的 symbol。添加这些到你的 symbol 路径,然后加载它们:kd .sympath SRV*d:DebugSymbols*http:/ Debugging Tutorial 2005 Microsoft Corporation6Symbol search path is: SRV*d: DebugSymbols *http:/ .reload /f ntSYMSRV: symbolssymbolsntoskrnl.pdbEC9B7590D1BB47A6A6D5

14、383538C2B31A1file.ptrSYMSRV: ntoskrnl.pdb from symbolssymbols: 9620480 bytes copied DBGHELP: nt - public symbols d:DebugSymbolsntoskrnl.pdbEC9B7590D1BB47A6A6D5383538C2B31A1ntoskrnl.pdbkd !lmi ntLoaded Module Info: nt Module: ntoskrnlBase Address: 80a02000Image Name: ntoskrnl.exeMachine Type: 332 (I3

15、86)Time Stamp: 3e80048b Mon Mar 24 23:26:03 2003Size: 4d8000CheckSum: 3f6f03Characteristics: 10e Debug Data Dirs: Type Size VA PointerCODEVIEW 25, ee00, e600 RSDS - GUID: (0xec9b7590, 0xd1bb, 0x47a6, 0xa6, 0xd5, 0x38, 0x35, 0x38, 0xc2, 0xb3, 0x1a)Age: 1, Pdb: ntoskrnl.pdbImage Type: MEMORY - Image r

16、ead successfully from loaded memory.Symbol Type: PDB - Symbols loaded successfully from symbol server.d:DebugSymbolsntoskrnl.pdbEC9B7590D1BB47A6A6D5383538C2B31A1ntoskrnl.pdbCompiler: C - front end 13.10 bld 2179 - back end 13.10 bld 2190Load Report: public symbols d:DebugSymbolsntoskrnl.pdbEC9B7590D

17、1BB47A6A6D5383538C2B31A1ntoskrnl.pdbsymbols 只会给你一些信息,而不会提供源代码。在最简单的情况下,在它们被建立的时候,source 文件便在同一个地方(该位置包括 2 进制文件和 symbol 文件)。但是在大多数情况下,你不能在那里找到它们(它们可能被移走了),你必须指定在哪里能找到它们。这时,你需要一个源路径,例如, .srcpath e:Win2003SP1它的意思是:想要 source 文件,请查看 e:Win2003SP1 目录。另一个解决方案是命名一个 source 服务器,如果你有:.srcpath MySrcServer如果你曾经在获

18、取 source 文件时遇到麻烦,使用 .srcnoisy 1 以取得更多关于调试器查找它们的信息。Kernel Debugging Tutorial 2005 Microsoft Corporation 7Workspaces目前你还不能开始调试,除非你已经准备好打很多字。很多设置都被保存在 workspace 中。所以你应该使用 FileSave 保存在 workspace 里面,例如,你将它保存为 kernel1394Win2003。在这之后,你希望以这个 workspace 的设置启动 WinDbg:windbg -W kernel1394Win2003 -k 1394:channel

19、=1W 指定一个 workspace,而k 给出通信方式(祥见 WINDOWS 调试工具帮助文件中的“WinDbg Command-Line Options”)。注意:在 WinDbg 或者 KD 中,你应该小心区分命令行可选项的大小写。为了让事情变得简单,你可以在桌面建立快捷方式,以使用特定的 workspace 启动 WinDbg,例如,使用 1394 连接:Kernel Debugging Tutorial 2005 Microsoft Corporation8上述文件中的内容:cd /d “d:Program FilesDebugging Tools for Windows“start

20、 windbg.exe -y SRV*d:DebugSymbols*http:/ -W kernel1394Win2003第一行将切换到 WINDOWS 调试工具的安装目录下面,确认调试器模块能在那里被找到。第二行启动WinDbg,指定 symbo 路径(-y)和 workspace (-W)。一个示例驱动使用示例驱动 IoCtl 练习,这将会帮助你熟悉 WinDbg。你能在 WINDDK 和它的后续产品,WDK 中找到。安装它,你便能在 srcgeneralIoctl 子目录下找到该驱动。IoCtl 的优点在于它是示例,而且是一个“legacy”驱动,由服务管理器(SCM)加载,而不是即插即

21、用的一部分(这里并不关心 PnP 的输入和输出)。你应该建立用户态程序(ioctlapp.exe) ,并在前者被加载之后建立内核态驱动程序(sioctl.sys)。这里有些重要的事需要明白。在优化代码方面,建立程序的处理十分灵巧,优化会导致代码移动(当然,原逻辑会被保留),并且将一些变量单独保存在寄存器中。为了确保更简单的调试体验,你应该在建立窗口或者源代码文件中使用这些编译指令建立一个调试版本:MSC_OPTIMIZATION=/Od(这是“Oh d”而不是“zero d.”)有时上述的情况会引起内部函数的一些问题,例如 memcmp。如果你碰上这个问题,尝试 :MSC_OPTIMIZATI

22、ON=/Odi请明白阻止优化对于生成正式版产品来说,并不是一个好选择。使用上述的指令,你将不能建立或者测试正式版。尽管如此,这对于测试未经优化的版本来说,是不错的练习。一旦你熟悉代码,排除简单的错误,正式产品便能得到提升。如果你需要处理已优化的代码,你将会在“处理优化代码”找到相关帮助。 Kernel Debugging Tutorial 2005 Microsoft Corporation 9开始调试示例驱动在 IoCtl 的 DriverEntry 设置断点。在启动驱动之前,中断在 WinDbg 的命令窗口,输入:bu sioctl!DriverEntrybu (“Breakpoint U

23、nresolved”)命令将会延迟断点的设置时间,直到该模块被加载;也就是说 WinDbg会探测“DriverEntry”。如果没有什么需要做,按下 F5(你也可以输入 g, “Go”)接下来,复制 ioctlapp.exe 和 sioctl.sys 到目标系统,例如 C:TempIOCTL,以管理员权限登陆系统,在命令窗口中,切换到 C:TempIOCTL 目录下。(你不需要在 WinDbg 中将此路径设置为 symbol 路径和 source 路径。)在同样的命令窗口,输入 ioctlapp 按下 Enter,在 WinDbg 中,你会看到: 如图,程序停在断点之后,!lmi 命令显示 W

24、inDbg 从 DDK 中取得 symbols。时间信息象你期望的一样,本地 symbol 文件也符合你的要求。 Kernel Debugging Tutorial 2005 Microsoft Corporation10依赖于你的排列方案,它并不明显,当前窗口能被其他窗口隐藏,但是你能在某个地方使用源代码窗口(按键顺序alt-Keypad * 不用按单引号 将会把窗口置前):Kernel Debugging Tutorial 2005 Microsoft Corporation 11断点被设置,即运行停止的地方会以粉红色标记(WINDOWS 调试工具帮助文件把它称为紫色)。当运行进 IoCr

25、eateDevice(运行控制 描述如何熟练运用):这里你能看到原始断点(高亮为红色,现在控制将停止在这里),你能看到当前声明被标记为深蓝色。Kernel Debugging Tutorial 2005 Microsoft Corporation12基础在调试 session 中,这是一个“测试驱动”。这是一些基本的调试操作。命令,扩展,等等。命令来自几个系列:简单的(未修饰的),一些从句号(“.”)开始,一些从惊叹号(“!”) 开始。WINDOWS调试工具帮助文件将它们分别描述为 commands, meta-commands and extension commands。以现在的效果来看,

26、这些系列非常接近。断点在运行中产生中断,是调试器的功能之一。这是一些实现方法。 在操作系统启动时中断为了在操作系统启动时尽早中断,请确认 WinDbg 已经连接,重新按 CTRL-ALT-K 直到你看到:在下次启动时,在 ntoskrnl 加载之后的一小段时间,这时所有驱动还没有被加载,操作系统将会挂起,而 WinDbg 将会取得控制权。在系统引导时间,你可能会希望为驱动程序定义断点,这就是时机。 Kernel Debugging Tutorial 2005 Microsoft Corporation 13 普通断点最简单的设置断点的方法就是通过 bp (“Breakpoint”)命令。例如:

27、bp MyDriver!xyzbp f89adeaa第一行,这个断点设在模块中的一个名字(!);第二行,它被设置在一个给出的地址。当运行到其中一个断点时,操作系统就会挂起,并且把控制权交给 WinDbg。(你可以在“寻找名字”看看如何为第二个命令取得地址。)注意:第一个命令的语法假定操作系统已经加载该模块,以及在 symbol 文件或者外部名定义有足够可用信息关于识别 xyz。如果不能在模块中找到 xyz,调试器会这么告诉你这些。 延迟断点说到驱动程序没有被加载,你最初的哪个断点,使用 bu(见上述 开始调试示例驱动)设置的是一个“可延迟的”断点。Bu 命令的参数是一个模块及它里面的名字,例如

28、:bu sioctl!SioctlDeviceControlSioctlDeviceControl 是一个入口点,或者其他在模块 sioctl.sys 中的名字。这个形式假定当模块被加载,足够有用的信息识别 SioctlDeviceControl 以便断点能够设置。(如果模块已经加载名字被找到,那么断点将会立即被设置)。如果操作系统找不到 SioctlDeviceControl,调试器会提示,另外将不会在 SioctlDeviceControl 处挂起。延迟断点的一个有用的特性便是它对 modules!names 操作。相比之下,一般断点对地址或者立即将 modules!names 解释为地址

29、。延迟断点的另一个特性便是在引导的过程中会被记住(这不会影响明确地址的断点)。然而,延迟断点的另外一个特性使得即使关联模块被卸载,它仍然会被保留。相同情况下,一般断点将会被移除。 另外一个设置一般断点的方法是通过 source 窗口。返回 sioctl.sys。当你中断于 DriverEntry,,你能向下滚动窗口到你希望停止地方,将光标移动到该行代码,按下 F9:红色的那一行便是通过 F9 设置的断点。 你可以使用 bl (“Breakpoint List”)查看所有已设置的断点:kd bl0 e d:winddk3790srcgeneralioctlsyssioctl.c 123 0001

30、 (0001) SIoctl!DriverEntry 1 e d:winddk3790srcgeneralioctlsyssioctl.c 338 0001 (0001) Sioctl!SioctlDeviceControl+0x103 注意两件事:每个断点都有一个号码并且显示出断点状态,“e”是“enabled”,而“d”是“disabled”。Kernel Debugging Tutorial 2005 Microsoft Corporation14 假设你希望临时停止使用某个断点。bd (“Disable Breakpoint”) 将会完成它。你只需指定断点号码:kd bd 1kd bl

31、0 e d:winddk3790srcgeneralioctlsyssioctl.c 123 0001 (0001) SIoctl!DriverEntry 1 d d:winddk3790srcgeneralioctlsyssioctl.c 338 0001 (0001) SIoctl!SioctlDeviceControl+0x103 相似的方法,永久移除断点号码,使用 bc 1 (“Clear Breakpoint”)。现在该断点将会从断点列表中消除。 然而,有时在操作系统或者驱动程序中,断点会被设置在一些频繁被激活的地方,你可能希望将它应用在一些环境或者条件操作,以便断点只在该情况下生效

32、。这是基本格式:bp SIoctl!SioctlDeviceControl+0x103 “j (Irp)=0xffb5c4f8) ; g“它的意思是:只有 Irp=地址 0xFFB5C4F8 时才中断;如果条件不符合,继续运行。更深入的探讨上述命令,并不是断点本身的状态。更准确的说,断点有一个操作项目(在双引号标记中);在该项目中,j (“Execute IF/ELSE”)命令是一个条件操作。J 的函数运行于TRUE|FALSE 项目(在单引号标记中)。如上述一样,TRUE 项目(第一)为空,以便当断点激活和符合 TRUE 的条件出现时,WinDbg 除了挂起程序之外不会做其他的事。如果符合

33、FALSE 的条件出现,由于使用了 g 命令,程序讲会继续运行。一个或者其他操作会被完成,这依赖于实际情况。思考这个比上述更详细的命令:bp SIoctl!SioctlDeviceControl+0x103 “j (Irp)=0xffb5c4f8) .echo Found the interesting IRP ; .echo Skipping an IRP of no interest; g “这里 TRUE 项目给出信息并停止。FALSE 项目给出信息并继续(这个信息很有用, WinDbg 计算出条件为 FALSE,并且默默地继续)。有时要注意:下面断点,EAX 被检测(你能在寄存器中找到

34、关于它们的处理方法),不会象你想的那样工作:bp SIoctl!SioctlDeviceControl+0x103 “j (eax=0xffb5c4f8) .echo Here! ; .echo Skipping; g “原因是可能会将寄存器的值扩充到 64 位再计算,例如,扩充到 0xFFFFFFFFFFB5C4F8,这将不会与 0x00000000FFB5C4F8 匹配。这导致只有 32 位的最高位为 1 和一些其他条件(例如,一个 32 位寄存器)才适用。在 WINDOWS 调试工具帮助文件中的 “Sign Extension”有更详尽的资料(也可以看看“Setting a Condit

35、ional Breakpoint”)。断点可能包含一些条件式,附带或不附带条件操作。其中一个条件是激发“one-shot”:断点只激活一次(激活之后便清除)。假如你只对第一次激活感兴趣,对于那些使用频繁的代码,这很便利。Kernel Debugging Tutorial 2005 Microsoft Corporation 15bp /1 SIoctl!SioctlDeviceControl+0x103另外一个有用的条件式测试一个进程或者线程:bp /p 0x81234000 SIoctl!SioctlDeviceControl+0x103bp /t 0xff234000 SIoctl!Sio

36、ctlDeviceControl+0x103它们分别代表,仅当进程块(EPROCESS)在 0x81234000,才在指定的地方停止,以及仅当线程块(ETHREAD)在 0xFF234000 时才在指定地方停止。该条件式能被组合为:bp /1 /C 4 /p 0x81234000 SIoctl!SioctlDeviceControl+0x103这代表,当 call stack 深度大于 4(这里的大写 C 很重要,因为 “c”代表“少于”)和进程块在0x81234000 时中断。 另外一种不同类型的断点,需要指定访问方式。例如:ba w4 0xffb5c4f8+0x18+0x4正如你所看到的,

37、这个地址来自 IRP,它的偏移 0x18+0x4 处即它的 IoStatus.Information 成员。所以当某程序企图更新 IRP 中 IoStatus.Information 的这 4 个字节时,断点会被激活。这种断点被称为数据断点(因为它们由数据访问触发)或者处理器断点(因为它们由处理器执行,而不是调试器自己)。表达式:MASM 与 C+在驱动程序之中使用变量提供参数,如进程地址。你或许同意那是很容易的一件事。然而,你需要理解一些调试器的表达式。调试器有两种评价表达式的方法,参考“MASM” (Microsoft Macro Assembler)和“C+”。引用WINDOWS 调试工

38、具帮助文件中的“MASM Expressions vs. C+ Expressions”:在 MASM 的表达式中,任何符号的数值都在内存地址中。在 C+表达式中,变量中的数值是它的真实数值,而不是它的地址。阅读再阅读这部分,这将会节省你更多的时间。一条表达式将会使用 MASM,或者 C+,或者它们的混合形式计算。简要说明:1. 默认表达式类型是 MASM.2. 你能使用.expr 改变默认类型(详见 WINDOWS 调试工具帮助文件) 。3. 某些命令总是使用 C+的方式求值。Kernel Debugging Tutorial 2005 Microsoft Corporation164. 一

39、个特殊的表达式(或表达式的一部分)的赋值能通过前缀“”改成与一般表达式相反的方向。 这个摘要相当棘手,你应该参考 WINDOWS 调试工具帮助文件中的“Evaluating Expressions”。现在,这里有一些例子,给你一些关于赋值是如何工作的概念。你之前已经停止在 Sioctl!SioctlDeviceControl+0x103,所以使用 dv 查看一个已知变量(查看 dv 命令以获得更多信息):kd dv IrpIrp = 0xff70fbc0该响应的意思是,Irp 变量包含 0xFF70FBC0。更多地,dv 解释 C+语法中的参数。该响应基于变量内容,而不是地址。你可以确认它:k

40、d ? Irpstruct _IRP * 0xff70fbc0? 总是以 C+ 为基础(详见 ?命令)。假如使用 MASM 类型的赋值,尝试? (详见 ? 命令) :kd ? IrpEvaluate expression: -141181880 = f795bc48这表示变量 Irp 位于 0XF795BC48。你可以通过使用 dd (详见 dd 命令)显示内存数据,确认该变量真的包含数据 0xFF70FBC0。 kd dd f795bc48 l1f795bc48 ff70fbc0以及内存指向这里:kd dd 0xff70fbc0ff70fbc0 00940006 00000000 00000

41、070 ff660c30ff70fbd0 ff70fbd0 ff70fbd0 00000000 00000000ff70fbe0 01010001 04000000 0006fdc0 00000000ff70fbf0 00000000 00000000 00000000 04008f20ff70fc00 00000000 00000000 00000000 00000000ff70fc10 ff73f4d8 00000000 00000000 00000000ff70fc20 ff70fc30 ffb05b90 00000000 00000000ff70fc30 0005000e 000000

42、64 0000003c 9c402408查看象 IRP 这样的变量,正如 dt 显示(详见 dt 命令),Type 和 Size 成员有一个似是而非的数据 :kd dt IrpLocal var 0xf795bc48 Type _IRP*0xff70fbc0 +0x000 Type : 6+0x002 Size : 0x94+0x004 MdlAddress : (null) +0x008 Flags : 0x70+0x00c AssociatedIrp : _unnamed+0x010 ThreadListEntry : _LIST_ENTRY 0xff70fbd0 - 0xff70fbd0

43、 +0x018 IoStatus : _IO_STATUS_BLOCK+0x020 RequestorMode : 1 +0x021 PendingReturned : 0 +0x022 StackCount : 1 +0x023 CurrentLocation : 1 +0x024 Cancel : 0 Kernel Debugging Tutorial 2005 Microsoft Corporation 17+0x025 CancelIrql : 0 +0x026 ApcEnvironment : 0 +0x027 AllocationFlags : 0x4 +0x028 UserIos

44、b : 0x0006fdc0 +0x02c UserEvent : (null) +0x030 Overlay : _unnamed+0x038 CancelRoutine : (null) +0x03c UserBuffer : 0x04008f20 +0x040 Tail : _unnamed有时,你会希望使用 C+ 赋值代替 MASM 表达式。“” 前缀会完成它。扩展命令总是使用象 MASM表达式一样的参数,当你使用扩展命令!irp (详见 IRPs),你能看到 的效果。kd !irp (Irp)Irp is active with 1 stacks 1 is current (= 0x

45、ff70fc30)No Mdl System buffer = ff660c30 Thread ff73f4d8: Irp stack trace. cmd flg cl Device File Completion-Context e, 0 5 0 82361348 ffb05b90 00000000-00000000 DriverSIoctlArgs: 00000064 0000003c 9c402408 00000000重复这个操作,不在上述的 Irp 变量中带 前缀,!irp 将会使用变量的地址,而不是变量的值。为了使这更加具体,如果变量位于 0xF795BC48,它包含的数据是 0x

46、FF70FBC0,使用!irp Irp 代替(Irp)将会请求 WinDbg 格式化位于 0xF795BC48 的 IRP stack。你需要进一步了解的是:前缀相当通用,正如它的正式意思,使用不同于当前表达式中正在使用的赋值方法。如果大部分表达式是 MASM,代表 C+,如果它是 C+,代表 MASM。最后一点建议:如果表达式不如你期望那样工作,考虑你是否在请求调试器理解 MASM 或者 C+语法。显示和设置内存,变量,寄存器等等有一些方法可以显示和改变它们。 在当前例程中显示一个变量(当前的“scope”),使用 dv (“Display Variables”)。例如,如果停止在 Sioc

47、tl!SioctlDeviceControl+0x103:kd dv DeviceObject = 0x82361348Irp = 0xff70fbc0outBufLength = 0x64buffer = 0x00000000 “irpSp = 0xff70fc30data = 0xf886b0c0 “This String is from Device Driver !“ntStatus = 0mdl = 0x00000000inBufLength = 0x3cdatalen = 0x26outBuf = 0x00000030 “inBuf = 0xff660c30 “This String is from User Application; using METHOD_BUFFERED“Kernel Debugging Tutorial 2005 Microsoft Corporation18这是一个参数变量列表以及一些在断点位置已知的变量。“已知”是一个重要的限定词。例如如果一个变量优化成一个寄存器,它将不会被显示,尽管可以反汇编它(View =Disassembly 打开反汇编窗口)并且检查寄存器。如果只关心一个变量,你可以:kd dv outBufLengt

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报