现在的位置: 首页 > 综合 > 正文

《Undocumented Windows 2000 Secrets》翻译 — 第一章(2)

2013年08月28日 ⁄ 综合 ⁄ 共 4549字 ⁄ 字号 评论关闭

第一章  Windows 2000对调试技术的支持

翻译:Kendiv(fcczj@263.net)

更新:Friday, January 18, 2005


声明:转载请注明出处,并保证文章的完整性,本人保留译文的所有权利。

 

内核调试器的命令

尽管调试器的命令已经注意了易记性,但有时总是难以回忆起它们。因此,我把它们都整理到了附录A中。表A-1是其快速参考。这个表是调试器的help信息(使用?命令)的整理版。命令所需参数的类型汇总在表A-2

 

前面提到过,内核调试器执行扩展命令时需要一个!号作为开始。只要命令前有个!号,调试器就会到已加载的扩展DLL的导出列表中进行查找。如果发现匹配的,就会跳转到相应的DLL中。1-7显示了内核调试器加载了kdextx86.dlluserkdx.dlldbghelp.dll扩展DLL。最后一个和i386kd.exe位于同一目录;前两个共有四个版本:针对Windows NT 4.0freechecked版本(对应子目录为:nt4frnt4chk),针对Windows 2000freechecked版本。通常,调试器在搜寻扩展命令是会采用一个默认的搜索顺序。然而,你可以改变这个默认设置,只需要在命令前指定模块名称即可,采用.符号作为分隔符。例如,kedxtx86.dlluserkdx.dll都导出了help命令,键入!help,在默认情况下,你会得到kdextx86.dll的帮助信息。要执行userdkx.dllhelp命令,你必须输入!userkdx.help(或者!userkdx.help –V如果你想得到更详细的帮助信息的话)。按照此方法,只要你知道规则,你也可以编写自己的扩展命令。在The NT InsiderOpen Systems Resources 1999a)中你能找到很棒的how-to文章。不过其针对的是WinDbg.exe而不是i386kd.exe,但两者使用相同的扩展DLL,大多数信息对于i386kd.exe也是有效的。

 

附录A中的表A-3A-4分别列出了kdextx86.dlluserkdx.dllhelp命令的输出信息。为了便于阅读作了些修改和整编。你会发现这些表中列出的命令多于Microsoft  DDK文档中的,其中有些命令明显有DDK文档未提到的附加参数。

 

10大调试命令

A-1A-4列出了内核调试器及其标准扩展DLL提供的巨多的命令。因此,我将讨论其中一些常用命令的细节。

 

u:  反编译机器码

在检查crash dump是否正确时,你已经用过了此命令,u命令有三种格式:

1u <from> 从地址<from>开始反编译8个机器码。

2u <from>  <to> 反编译<from><to>之间的所有机器码。

3u  不提供任何参数时,从上次u命令停止的位置开始反编译。

 

当然,反编译打段代码是十分厌烦的,但如果你只想知道在特定地址发生的事情,那这是最便捷的方法。或许u命令最令人感兴趣的特性是它可以解析代码引用到的符号----即使是目标模块没有导出的符号。不过,使用本书光盘中的Multi-Format Visual Disassembler反编译完整的Windows 2000可执行体将是十分有趣的。在随后章节中,会有关该产品的更多信息。

 

dbdwddDump Memory BYTEsWORDsDWORDs

    如果你当前感兴趣的内存数据是二进制的,那么调试器的16进制转储命令将能完成此任务。根据你对源地址(source address)数据类型的判断,来选择dd(针对BYTES)、dw(针对WORDS)、dd(针对DWORDS)。

l         db 将指定内存范围里的数据显示为两个部分:左边是16进制表示(每28 bit一组),右边是对应的ASCI码。

l         dw 仅按照16进制显示(16 bit一组)

l         dw 仅按照16进制显示(32 bit一组)

此组命令可以使用与u命令相同的参数。注意,<to>所指示的地址内容,也会被显示出来。如果没有任何参数,将显示接下来的128个字节。

 

x检查符号

x命令非常重要。它可以根据已安装的符号文件创建一个列表。典型的使用方式如下:

1x *!* 显示所有可用符号的模块。在启动后,默认只有ntoskrnl.exe的符号是可用的。其他模块的符号可以使用.reload命令来加载。

2x <module>!<filter>  显示模块<module>的符号文件中的符号名称,<filter>可以包括通配符?*<module>必须属于x *!*列出的模块名。例如,x nt!*将列出在内核符号文件ntoskrnl.dbg中找到的所有符号,x win32k!*将列出win32k.dbg提供的符号。如果调试器报告说“Couldn’t resolve ‘X….’”,尝试用.reload再次加载所有的符号文件。

 

3x <filter> 显示所有可用符号的一个子集,该子集不匹配<filter>表达式。本质上,这是x <module>!<filter>的一个变形,在这里<module>!被省略了。

 

随符号名一起显示的,还有与其相关的虚拟地址。对于函数名,与其对应的就是函数的入口地址。对于变量,就是改变量的基地址。该命令值得的注意的地方是,它可以输出很多内部符号(internal symbols),这些在可执行文件的导出表中都是找不到的。

 

ln列出最近的符号

ln是我最喜欢的一个命令。因为它可以快速且简单的访问已安装的符号文件。算是x命令的理想补充。不过后者适用于列出所有系统符号的地址。Ln命令则用于按照地址或名称查找符号。

l         ln <address> 显示<address>指示的地址以及和其前后相邻的地址的符号信息。

l         ln <symbol> 将符号名解析为与其对应的虚拟地址。其过程与ln <address>类似。

 

x命令一样,调试器知道所有导出的以及一些内部的符号。因此,对于想弄清楚出现在反编译列表或16进制转储中的不明指针的确切含义的人有着非常大的帮助。注意,udbdwdd也会使用符号文件。

 

!processfield列出EPROCESS的成员

该命令前的!号,意味着它来自于调试器的扩展模块—kdextx86.dll。该命令可显示内核用来代表一个进程的EPROCESS结构(该结构并没有正式的说明文档)的成员及其偏移量。

 

尽管该命令仅列出了成员的偏移量,但你也能很容易的猜出其正确的类型。例如,LockEvent位于0x70处,其下一个成员的偏移量为0x80。则该成员占用了16个字节,这与KEVENT结构非常类似。如果你不知道什么是KEVENT,不要担心,我在第7章将会讨论之。

 

!threadfields列出ETHREAD成员

    这是kdextx86.dll提供的另一个强大的选项。和!processfields类似,它列出未文档化的ETHREAD结构的成员及其偏移量。内核使用它表示一个线程。参见示例1-2


 

!drivers列出已加载的Drivers

    kdextx86.dll真是太棒了。!drivers列出了当前运行的内核和文件系统模块的详细信息。如果检查crash dump,该命令会列出系统崩溃那一刻的系统状态。示例1-3是我机器上输出的摘要。注意,在输出的最后一行,导致Windows 2000崩溃的Driver的地址为0xBECC2000,这显然是w2k_kill.sys引发蓝屏后显示的地址。

译注:

在新的i386kd.exever: 6.3.0017.0)中,!driver命令已不被支持。取而代之的是lm命令。该命令的一般用法是:lm t n

 

!sel检查Selector的值

如果没有争议的话,!sel实现于kdextx86.dll。它用来显示16个连续的memory selector(按地址升序排列)。你可以反复的使用此命令直到出现“Selector is invalid”。在第4章将讨论Memory Selector,到时我会提供一个示列代码来演示如何在你的程序中crack selectors

译注:

在新的调试器中,该命令已不被支持,取而代之的是:dg命令。其一般性用法为:dg.注意末尾的.符号。dg命令最多可列出256Selector。调试器的Online Help中有详细说明

 

关闭调试器

你可以通过简单的关闭控制台窗口来关闭内核调试器。当然,更好的关闭办法是使用q命令,这儿“q”代表着quit

 

更多的调试工具

在本书的光盘中,你可以找到两个由我的e-friends贡献的非常有价值的调试工具。我很高兴他们允许我将完整版本放入我的光盘中。 Wayne J. Radburn PE and COFF文件浏览器(PEView)是本书读者的一个特殊免费工具。Jean-Louis SeigneMulti-Format Visual DisassemblerMFVDasm)一个限时版本。本节将简单介绍这两个工具。

 

MFVDASM:可视化多格式反编译器

MFVDasm不仅仅是个汇编列表生成器。事实上,它比汇编代码浏览器增加了多个很不错的导航特性。如图1-8所示,那是我使用MFVDasm察看Windows 2000 I/O管理函数IoDetachDevice()的截图。图中并没有显示出屏幕上的颜色。例如,所有的函数表以及特定地址的jumpscalls都被显示为红色。针对其余地址(没有相关导出符号的地址)的jumpscalls显示为蓝色。引用了从其他模块动态导出的符号的显示为紫色。所有可到达的目标地址(reachable destinations)都加上了下划线,这意味着你可以通过单击他们来滚动代码窗口到达其地址。使用工具栏上的BackForward按钮,你能回顾看过的东东。这很像在IE中察看浏览过的网页。

在右边,你可以随意选择你想跳到的符号或目标地址。当然,通过单击列头你可以进行排序。在最底层,MFVDasm提供了Tab页来分别显示符号、16进制转储(HexDump)和重定位(Relocations)。对包含嵌入字符串的代码段进行反编译时16进制转储视图会显得很有用。在分析很大的文件如ntoskrnl.exe时,MFVDasm不会阻塞住,和其他流行的反编译工具一样,得到的汇编代码可以保存到文本文件中。

 

PEView --- PECOFF文件察看器

尽管MFVDasm展示了PEPortable Executable)文件的很多内部结构的细节,但其侧重于代码的查看。另一方面,PEView虽然不能展示比代码段的16进制码更进一步的细节,但它能非常详细的显示文件结构的细节。如图1-9所示。这是我用PEView察看ntoskrnl.exe的截图。可以看出PEView采用三种形式来显示ntoskrnl.exe的多个部分。如果你单击左边的一个叶结点,在右面就会显示与该项相关的所有信息。在图1-9种,我选择了IMAGE_OPTIONAL_HEADER结构,该结构是IMAGE_NT_HEADERS结构的成员之一。

抱歉!评论已关闭.