WinDbg常用命令系列---显示数据类型dt/dtx

dt (Display Type)

dt命令显示有关局部变量、全局变量或数据类型的信息。这可以显示有关简单数据类型以及结构和联合的信息。

用户模式下:

dt [-DisplayOpts] [-SearchOpts] [module!]Name [[-SearchOpts] Field] [Address] [-l List] 
dt [-DisplayOpts] Address [-l List] 
dt -h 

内核模式下:

[Processor] dt [-DisplayOpts] [-SearchOpts] [module!]Name [[-SearchOpts] Field] [Address] [-l List] 
dt [-DisplayOpts] Address [-l List] 
dt -h 

参数:

  • Processor
    指定运行包含所需信息的进程的处理器。只能在内核模式下指定处理器。
  • DisplayOpts
    指定下表中给定的一个或多个选项。这些选项前面有连字符。
    Option描述

    -a[quantity]

    带有其索引的新行上显示每个数组元素。 总共数量将显示元素。 必须有之间没有空格并quantity如果-a后面不接数字,该数组中的所有项所都示。 -A[quantity] 开关应出现立即每个类型名称或字段名称的前您想在这种方式中显示。

    -b

    显示基块以递归方式。 如果显示的结构包含子结构,它是以递归方式展开到任意深度和完整显示。 仅当它们是不在子结构的原始结构中,指针会展开。

    -c

    压缩输出。 如有可能在同一行显示所有字段。 (与一起使用时-a交换机,每个数组元素都占用一行,而不是格式为多个行块。)

    -d

    与一起使用时名称的已结束,但一个星号,显示以开头的所有类型的详细输出名称如果名称不以星号结尾,则显示详细输出。

    -e

    强制dt枚举类型。 如果仅需要此选项dt错误地解释名称实例而不是一种类型的值。

    -i

    不缩进子类型。

    -o

    省略结构字段的偏移量的值。

    -p

    地址是一个物理地址,而不是虚拟的地址。

    -r[depth]

    以递归方式转储的子类型字段。 如果深度是,此递归将停止后深度级别。 深度都必须是介于 1 和 9 之间的数字和必须之间没有空格r深度-R[深度] 交换机应出现在立即之前地址。

    -s size

    仅这些中的类型的大小字节数等于的值枚举大小-S正在枚举类型时,选项才有用。 -s指定,则-e始终也暗示。

    -t

    枚举仅适用于类型。

    -v

    详细输出。 这样,例如总大小的结构和它的元素数的其他信息。 这用于时沿-y搜索选项,将显示所有符号,甚至包括那些没有关联的类型信息。


  • SearchOpts
    指定下表中给定的一个或多个选项。这些选项前面有连字符。
    Option描述

    -n

    这表示下一个参数是一个名称。 这应在下一项完全十六进制字符组成,因为它否则将执行作为一个地址。

    -y

    这指示下一个参数的名称,不一定是整个名称开头。 -y是包含,所有列出了匹配项,然后上列表中的第一个匹配项的详细信息。 如果-y是未包含,就会显示仅完全匹配项。

  • module
    指定定义此结构的模块的可选参数。如果存在与全局变量或类型同名的局部变量或类型,则应包含模块以指定您是指全局变量。否则,dt命令将显示局部变量,即使局部变量是不区分大小写的匹配,而全局变量是区分大小写的匹配。
  • Name

    指定类型或全局变量的名称。如果名称以星号(*)结尾,将显示所有匹配项的列表。因此,dt a*将列出以“a”开头的所有数据类型、全局和静态,但不会显示这些类型的实际实例。(如果同时使用-v display选项,则将显示所有符号,而不仅仅是具有相关类型信息的符号。)您还可以用句点(.)替换名称,以表示您要重复最近使用的名称值。如果名称包含空格,则应将其括在括号中。

  • Field
    指定要显示的字段。如果省略字段,则显示所有字段。如果字段后跟句点(),则也将显示此字段的第一级子字段。如果字段后面跟着一系列句点,子字段的显示深度将等于句点数。任何后跟句点的字段名都将被视为前缀匹配,就好像使用了-y搜索选项一样。如果字段后跟星号(*),则它仅被视为字段的开头,而不一定是整个字段,并且将显示所有匹配的字段。
  • Address
    指定要显示的结构的地址。如果省略了名称,则必须包含地址,并且必须指定全局变量的地址。除非另有说明,否则地址被视为虚拟地址。使用-p选项指定物理地址。使用“at”符号(@)指定寄存器(例如@eax)。
  • List
    指定链接链接列表的字段名。必须包含address参数。

dt命令输出将始终以10为基数显示有符号数字,以十六进制显示无符号数字。所有允许符号值的dt参数也允许字符串通配符。 --y和-n选项可以位于任何名称或字段之前。-y选项允许您指定类型或结构名称的开头。例如,dt-y allen将显示关于allentown类型的数据。但是,不能使用dt-y a显示allentown类型。相反,必须使用dt-ny a,因为a是有效的十六进制值,并且将被解释为不带-n选项的地址。如果名称表示结构,则将显示所有字段(例如,dt mystrut)。如果只需要一个特定字段,可以执行dt mystrut myfield。这将显示C将调用mystrut.myfield的成员。但是,请注意,命令dt mystrut myfield1 myfield2显示mystrut.myfield1和mystrut.myfield2。它不显示mystruct.myfield1.myfield2。如果结构名称或字段后跟下标,则指定数组的单个实例。例如,dt mystrut myfieldarray[3]将显示所讨论数组的第四个元素。但是,如果类型名后跟下标,则指定整个数组。例如,dt char[8]myptr将显示一个8个字符的字符串。不管当前的基数是多少,下标始终被视为十进制;一个0x前缀将导致错误。因为该命令使用来自.pdb文件的类型信息,所以它可以自由地用于调试任何CPU平台。dt使用的类型信息包括用typedef创建的所有类型名,包括所有Windows定义的类型。例如,无符号long和char不是有效的类型名,但ulong和char是。

由typedef在您自己的代码中创建的所有类型都将出现,只要它们已经在您的程序中实际使用。但是,在头文件中定义但从未实际使用的类型将不会存储在.pdb符号文件中,调试器将无法访问这些类型。要使此类类型对调试器可用,请将其用作typedef语句的输入。例如,如果代码中出现以下内容,则结构my_data将存储在.pdb符号文件中,并可以通过dt命令显示:

typedef struct _MY_DATA {
    . . .
    } MY_DATA;
typedef  MY_DATA *PMY_DATA; 

另一方面,以下代码还不够,因为MY_DATA和PMY_DATA都是由初始typedef定义的,因此,MY_DATA本身并没有被用作任何typedef语句的输入:

typedef struct _MY_DATA {
    . . .
    } MY_DATA, *PMY_DATA; 

在任何情况下,类型信息只包含在完整的符号文件中,而不是从所有私有符号信息中删除的符号文件。如果要显示Unicode字符串,需要先使用.enable_unicode (Enable Unicode Display)命令。您可以使用.enable_long_status (Enable Long Integer Display)命令控制长整型的显示。

在以下示例中,dt显示全局变量:

0:000> dt mt1 
   +0x000 a                : 10
   +0x004 b                : 98 'b'
   +0x006 c                : 0xdd
   +0x008 d                : 0xabcd
   +0x00c gn               : [6] 0x1
   +0x024 ex               : 0x0 

在以下示例中,dt显示数组字段gn:

0:000> dt mt1 -a gn 
   +0x00c gn : 
    [00] 0x1
    [01] 0x2
    [02] 0x3
    [03] 0x4
    [04] 0x5
    [05] 0x6 

以下命令将显示变量的某些子字段:

0:000> dt mcl1 m_t1 dpo 
   +0x010 dpo  : DEEP_ONE
   +0x070 m_t1 : MYTYPE1 

下面的命令显示的字段的子字段m_t1因为段会自动导致前缀匹配,这将显示子字段开头的任何字段的"m_t1":

0:000> dt mcl1 m_t1. 
   +0x070 m_t1  : 
      +0x000 a     : 0
      +0x004 b     : 0 '
      +0x006 c     : 0x0
      +0x008 d     : 0x0
      +0x00c gn    : [6] 0x0
      +0x024 ex    : 0x0 

无法为任何深度重复此步骤。 例如,命令dt mcl1...c。 将显示所有字段深度四个,以便第一个字段名称开头和第三个字段名称开头c

下面是可以显示子字段的方式的更详细的示例。 首先,显示Ldr字段:

0:000> dt nt!_PEB Ldr 7ffdf000 
   +0x00c Ldr : 0x00191ea0 

现在请展开指针类型字段:

0:000> dt nt!_PEB Ldr Ldr. 7ffdf000 
   +0x00c Ldr  : 0x00191ea0
      +0x000 Length : 0x28
      +0x004 Initialized : 0x1 '
      +0x008 SsHandle : (null)
      +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x191ee0 - 0x192848 ]
      +0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x191ee8 - 0x192850 ]
      +0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x191f58 - 0x192858 ]
      +0x024 EntryInProgress : (null) 

现在,显示CriticalSectionTimeout字段:

0:000> dt nt!_PEB CriticalSectionTimeout 7ffdf000 
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000 

现在展开CriticalSectionTimeout结构子字段一个层次深度:

0:000> dt nt!_PEB CriticalSectionTimeout. 7ffdf000 
   +0x070 CriticalSectionTimeout  :  0xffffe86d`079b8000
      +0x000 LowPart                 : 0x79b8000
      +0x004 HighPart                : -6035
      +0x000 u                       : __unnamed
      +0x000 QuadPart                : -25920000000000 

现在展开CriticalSectionTimeout结构深度的子字段两个级别:

0:000> dt nt!_PEB CriticalSectionTimeout.. 7ffdf000 
   +0x070 CriticalSectionTimeout   :  0xffffe86d`079b8000
      +0x000 LowPart                  : 0x79b8000
      +0x004 HighPart                 : -6035
      +0x000 u                        :
         +0x000 LowPart                  : 0x79b8000
         +0x004 HighPart                 : -6035
      +0x000 QuadPart                 : -25920000000000 

下面的命令显示数据类型位于地址 0x0100297C MYTYPE1 的实例:

0:000> dt 0x0100297c MYTYPE1 
   +0x000 a                : 22
   +0x004 b                : 43 '+'
   +0x006 c                : 0x0
   +0x008 d                : 0x0
   +0x00c gn               : [6] 0x0
   +0x024 ex               : 0x0 

 

下面的命令显示在地址 0x01002BE0 10 ULONGs 数组:

0:000> dt -ca10 ULONG 01002be0 
[0] 0x1001098
[1] 0x1
[2] 0xdead
[3] 0x7d0
[4] 0x1
[5] 0xcd
[6] 0x0
[7] 0x0
[8] 0x0
[9] 0x0 

以下命令在不同的地址处继续以前的显示。 请注意"ULONG"不需要重新输入:

0:000> dt -ca4 . 01002d00 
Using sym ULONG
[0] 0x12
[1] 0x4ac
[2] 0xbadfeed
[3] 0x2 

下面是类型显示的一些示例。 下面的命令的模块中显示所有类型和字符串"MY"开头的全局thismodule这些带有地址前缀是实际的实例;地址不是类型定义:

0:000> dt thismodule!MY* 
010029b8  thismodule!myglobal1
01002990  thismodule!myglobal2
          thismodule!MYCLASS1
          thismodule!MYCLASS2
          thismodule!MYCLASS3
          thismodule!MYTYPE3::u
          thismodule!MYTYPE1
          thismodule!MYTYPE3
          thismodule!MYTYPE3
          thismodule!MYFLAGS 

执行类型显示时 -v选项可用于显示每个项的大小。 -S 大小选项可用于仅枚举具有特定大小的项。 同样,这些前缀的地址是实际的实例;地址不是类型定义:

0:001> dt -s 2 -v thismodule!* 
Enumerating symbols matching thismodule!*, Size = 0x2
Address   Size Symbol
           002 thismodule!wchar_t
           002 thismodule!WORD
           002 thismodule!USHORT
           002 thismodule!SHORT
           002 thismodule!u_short
           002 thismodule!WCHAR
00427a34   002 thismodule!numberOfShips
00427a32   002 thismodule!numberOfPlanes
00427a30   002 thismodule!totalNumberOfItems 

下面是举例 -b选项。 展开结构和OwnerThreads展开数组结构中的,但Flink闪烁未遵循列表的指针:

 
kd> dt nt!_ERESOURCE -b 0x8154f040 
   +0x000 SystemResourcesList :  [ 0x815bb388 - 0x816cd478 ]
      +0x000 Flink            : 0x815bb388
      +0x004 Blink            : 0x816cd478
   +0x008 OwnerTable       : (null)
   +0x00c ActiveCount      : 1
   +0x00e Flag             : 8
   +0x010 SharedWaiters    : (null)
   +0x014 ExclusiveWaiters : (null)
   +0x018 OwnerThreads     :
    [00]
      +0x000 OwnerThread      : 0
      +0x004 OwnerCount       : 0
      +0x004 TableSize        : 0
    [01]
      +0x000 OwnerThread      : 0x8167f563
      +0x004 OwnerCount       : 1
      +0x004 TableSize        : 1
   +0x028 ContentionCount  : 0
   +0x02c NumberOfSharedWaiters : 0
   +0x02e NumberOfExclusiveWaiters : 0
   +0x030 Address          : (null)
   +0x030 CreatorBackTraceIndex : 0
   +0x034 SpinLock         : 0

下面是举例dt在内核模式下。 以下命令将生成输出结果类似于 ! process 0 0:

kd> dt nt!_EPROCESS -l ActiveProcessLinks.Flink -y Ima -yoi Uni 814856f0 
## ActiveProcessLinks.Flink at 0x814856f0

UniqueProcessId : 0x00000008
ImageFileName : [16] "System"

## ActiveProcessLinks.Flink at 0x8138a030

UniqueProcessId : 0x00000084
ImageFileName : [16] "smss.exe"

## ActiveProcessLinks.Flink at 0x81372368

UniqueProcessId : 0x000000a0
ImageFileName : [16] "csrss.exe"

## ActiveProcessLinks.Flink at 0x81369930

UniqueProcessId : 0x000000b4
ImageFileName : [16] "winlogon.exe"

.... 

dtx (Display Type - Extended Debugger Object Model Information)

dtx命令使用调试器对象模型显示扩展符号类型信息。dtx命令类似于dt(显示类型)命令。

dtx -DisplayOpts [Module!]Name Address

参数:

  • DisplayOpts

    使用以下可选标志更改输出的显示方式。

    -a 在新行中显示数组元素及其索引。

    -r [n] 递归地将子类型(字段)转储到n个级别。

    -h 显示命令行帮助。
  • Module!
    指定定义此结构的模块的可选参数,后跟感叹号。如果存在与全局变量或类型同名的局部变量或类型,则应包括模块名以指定全局变量。

  • Name
    类型名或全局符号。
  • Address
    包含类型的内存地址。

下面的示例演示如何使用dtx命令。

使用地址和名称显示扩展符号类型信息。

0: kd> dtx nt!_EPROCESS ffffb607560b56c0
(*((nt!_EPROCESS *)0xffffb607560b56c0))                 [Type: _EPROCESS]
    [+0x000] Pcb              [Type: _KPROCESS]
    [+0x2d8] ProcessLock      [Type: _EX_PUSH_LOCK]
    [+0x2e0] RundownProtect   [Type: _EX_RUNDOWN_REF]
    [+0x2e8] UniqueProcessId  : 0x4 [Type: void *]
    [+0x2f0] ActiveProcessLinks [Type: _LIST_ENTRY]

使用-r递归选项显示其他信息。

0: kd> dtx -r2 HdAudio!CAzMixertopoMiniport fffff806`d24992b8
(*((HdAudio!CAzMixertopoMiniport *)0xfffff806d24992b8))                 [Type: CAzMixertopoMiniport]
    [+0x018] m_lRefCount      : -766760880 [Type: long]
    [+0x020] m_pUnknownOuter  : 0xfffff806d24dbc40 [Type: IUnknown *]
    [+0x028] m_FilterDesc     [Type: PCFILTER_DESCRIPTOR]
        [+0x000] Version          : 0xd24c2890 [Type: unsigned long]
        [+0x008] AutomationTable  : 0xfffff806d24c2780 [Type: PCAUTOMATION_TABLE *]
            [+0x000] PropertyItemSize : 0x245c8948 [Type: unsigned long]
            [+0x004] PropertyCount    : 0x6c894808 [Type: unsigned long]
            [+0x008] Properties       : 0x5718247489481024 [Type: PCPROPERTY_ITEM *]
            [+0x010] MethodItemSize   : 0x55415441 [Type: unsigned long]
            [+0x014] MethodCount      : 0x57415641 [Type: unsigned long]
            [+0x018] Methods          : 0x4ce4334540ec8348 [Type: PCMETHOD_ITEM *]
            [+0x020] EventItemSize    : 0x8b41f18b [Type: unsigned long]
            [+0x024] EventCount       : 0xd8b48f4 [Type: unsigned long]
            [+0x028] Events           : 0x7d2d8d4cfffdf854 [Type: PCEVENT_ITEM *]
            [+0x030] Reserved         : 0x66fffd79 [Type: unsigned long]
        [+0x010] PinSize          : 0xd24aa9b0 [Type: unsigned long]
        [+0x014] PinCount         : 0xfffff806 [Type: unsigned long]
        [+0x018] Pins             : 0xfffff806d24aa740 [Type: PCPIN_DESCRIPTOR *]
            [+0x000] MaxGlobalInstanceCount : 0x57555340 [Type: unsigned long]
            [+0x004] MaxFilterInstanceCount : 0x83485741 [Type: unsigned long]
            [+0x008] MinFilterInstanceCount : 0x8b4848ec [Type: unsigned long]
            [+0x010] AutomationTable  : 0xa5158b48ed33c000 [Type: PCAUTOMATION_TABLE *]
            [+0x018] KsPinDescriptor  [Type: KSPIN_DESCRIPTOR]

使用x(检查符号)命令显示感兴趣项的地址。

0: kd> x /d HdAudio!CazMixertopoMiniport*
...
fffff806`d24992b8 HdAudio!CAzMixertopoMiniport::`vftable' = <no type information>

 

 





 

posted on 2019-09-04 11:43  活着的虫子  阅读(3041)  评论(0编辑  收藏  举报

导航