其他 DBH 示例

下面是可在 DBH 提示符下发出的命令的其他示例。

显示私有符号和公共符号

如果目标是完整的符号文件,则每个公共符号都会在文件中出现两次:在公共符号表以及私有符号数据中。 公共符号表中的副本通常包含各种修饰(前缀和后缀)。 有关详细信息,请参阅公共符号和私有符号

DBH 可以从私有符号数据、公共符号表(不含修饰)以及带有修饰的公共符号表中显示有关此符号的信息。 下面是一个示例,每次使用命令 addr 414fe0 都会显示这三个。

此命令首次出现在此示例中时,DBH 使用默认符号选项,因此生成的信息来自私有符号数据。 请注意,此信息包括函数 fgets 的地址、大小和数据类型。 然后,使用命令 symopt +4000,该命令打开 SYMOPT_PUBLICS_ONLY 选项。 这会导致 DBH 忽略私有符号数据,因此当 addr 414fe0 命令第二次运行时,DBH 使用公共符号表,并且函数 fget 不显示大小或数据类型信息。 最后,使用命令 symopt -2 关闭 SYMOPT_UNDNAME 选项,并使 DBH 包含修饰。 当 addr 414fe0 最后一次运行时,将显示函数名称的修饰版本,_fgets

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 113
  flags : 0
   type : 7e
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 7d

pid:4308 mod:TimeTest[400000]: symopt +4000

Symbol Options: 0x10c13
Symbol Options: 0x14c13

pid:4308 mod:TimeTest[400000]: addr 414fe0

fgets
   name : fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f

pid:4308 mod:TimeTest[400000]: symopt -2

Symbol Options: 0x14c13
Symbol Options: 0x14c11

pid:4308 mod:TimeTest[400000]: addr 414fe0

_fgets
   name : _fgets
   addr :   414fe0
   size : 0
  flags : 0
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 7f 

如果使用了 -d 命令行选项,结果将从头开始显示修饰后的公共名称。

确定特定符号的修饰

DBH 可以确定特定符号上的修饰。 当与需要指定符号及其修饰的程序(如 PDBCopy)一起使用时,这非常有用。

例如,假设您知道符号文件 mysymbols.pdb 包含一个未修饰名为 MyFunction1 的符号。 若要查找修饰名,请按以下步骤操作。

首先,在没有 -d 命令行选项的情况下启动 DBH,然后使用 symopt +4000 命令使所有信息都来自公共符号表:

C:\> dbh c:\mydir\mysymbols.pdb

mysymbols [1000000]: symopt +4000

Symbol Options: 0x10c13
Symbol Options: 0x14c13 

接下来,使用 name 命令或 enum 命令显示所需符号的地址:

mysymbols [1000000]: enum myfunction1 

 index            address     name
   2ab            102cb4e :   MyFunction1

现在使用 symopt -2 使符号修饰可见,然后将 addr 命令与此符号的地址一起使用:

mysymbols [1000000]: symopt -2

Symbol Options: 0x14c13
Symbol Options: 0x14c11

mysymbols [1000000]: addr 102cb4e

_MyFunction1@4
   name : _InterlockedIncrement@4
   addr :  102cb4e
   size : 0
  flags : 0
   type : 0
modbase :  1000000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagPublicSymbol (a)
  index : 2ab  

这表明符号的修饰名称是 _MyFunction1@4

解码符号修饰

undec 命令可用于显示 C++ 符号修饰的含义。 在以下示例中,附加到 ??_C@_03GGCAPAJC@Sep?$AA@ 的修饰被解码以表明它是一个字符串:

dbh: undec ??_C@_03GGCAPAJC@Sep?$AA@

??_C@_03GGCAPAJC@Sep?$AA@ =
`string' 

以下示例对附加到三个函数名称的修饰进行解码,并显示其原型:

dbh: undec ?gcontext@@3_KA

?gcontext@@3_KA =
unsigned __int64 gcontext


dbh: undec ?pathcpy@@YGXPAGPBG1K@Z

?pathcpy@@YGXPAGPBG1K@Z =
void __stdcall pathcpy(unsigned short *,unsigned short const *,unsigned short const *,unsigned long)


dbh: undec ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z

?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z =
int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int) 

undec 命令不显示有关初始下划线、前缀__imp_或尾随“@address”修饰的信息,这些修饰通常附加到函数名称。

可以将 undec 命令与任何字符串一起使用,而不仅仅是当前加载模块中的符号名称。

按地址对符号列表进行排序

如果只是想获得按地址顺序排序的符号列表,可以在批处理模式下运行 DBH,并将结果通过管道传递给 sort 命令。 地址值通常在每行的第 18 列开始,因此以下命令按地址对结果进行排序:

dbh -p:4672 enum mymodule!* | sort /+18

显示源行信息

使用完整符号文件时,DBH 可以显示源行信息。 这不需要访问任何源文件,因为此信息存储在符号文件本身中。

此处,line 命令显示对应于指定源行的二进制指令的十六进制地址,并显示与该行关联的符号。 (在此示例中,没有与该行关联的符号。)

dbh [1000000]: line myprogram.cpp#767

   file : e:\mydirectory\src\myprogram.cpp
   line : 767
   addr :  1006191
    key : 0000000000000000
disp : 0

在这里, srclines 命令显示与指定源行关联的对象文件:

dbh [1000000]: srclines myprogram.cpp 767

0x1006191: e:\mydirectory\objchk\amd64\myprogram.obj
line 767 e:\mydirectory\src\myprogram.cpp

请注意,srclines 的输出类似于 ln(列表最近符号)调试器命令的输出。

显示数据类型

type 命令可用于显示有关数据类型的信息。 此处显示有关 CMDPROC 类型的数据:

dbh [1000000]: type CMDPROC

   name : CMDPROC
   addr :        0
   size : 8
  flags : 0
   type : c
modbase :  1000000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagTypedef (11)
  index : c

“tag”后面列出的值指定此数据类型的性质。 在这种情况下,SymTagTypedef 表示此类型是使用 typedef 语句定义的。

使用虚构符号

add 命令可以将虚构符号添加到加载的模块。 实际符号文件不会更改;只会更改 DBH 内存中该文件的映像。

如果您希望临时覆盖与给定地址范围关联的符号,则 add 命令非常有用。 在以下示例中,与 MyModule!main关联的地址范围的一部分被虚构符号 MyModule!magic 覆盖。

下面是在添加虚构符号之前模块的显示方式。 请注意,函数从 0x0042CC56 开始,大小为 0x42B。 因此,当 addr 命令与地址 0x0042CD10 一起使用时,它将此地址识别为位于函数边界内的地址:

pid:6040 mod:MyModule[400000]: enum timetest!ma*

 index            address     name
     1             42cc56 :   main
     3             415810 :   malloc
     5             415450 :   mainCRTStartup

pid:6040 mod:MyModule[400000]: addr 42cc56

main
   name : main
   addr :   42cc56
   size : 42b
  flags : 0
   type : 2
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 1

pid:6040 mod:MyModule[400000]: addr 42cd10

main+ba
   name : main
   addr :   42cc56
   size : 42b
  flags : 0
   type : 2
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 1 

现在,符号 magic 被添加到地址 0x0042CD00,大小为 0x10字节。 使用 enum命令时,将设置索引中的高位,表明这是虚构符号:

pid:6040 mod:MyModule[400000]: add magic 42cd00 10


pid:6040 mod:MyModule[400000]: enum timetest!ma*

 index            address     name
     1             42cc56 :   main
     3             415810 :   malloc
     5             415450 :   mainCRTStartup
  80000001             42cd00 :   magic 

使用 addr 命令时,它会查找其范围包括指定地址的任何符号。 由于此搜索以指定地址开头并向后运行,因此地址 0x004CD10 现在与 magic 相关联。 另一方面,地址 0x004CD40 仍然与main 地址相关联,因为它位于 magic 符号的范围之外。 另请注意,标记 SymTagCustom 表示虚构符号:

pid:6040 mod:MyModule[400000]: addr 42cd10

magic+10
   name : magic
   addr :   42cd00
   size : 10
  flags : 1000
   type : 0
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagCustom (1a)
  index : 80000001

pid:6040 mod:MyModule[400000]: addr 42cd40

main+ea
   name : main
   addr :   42cc56
   size : 42b
  flags : 0
   type : 2
modbase :   400000
  value :        0
    reg : 0
  scope : SymTagNull (0)
    tag : SymTagFunction (5)
  index : 1 

最后,del 命令可以删除符号 magic,将所有符号返回到其原始范围:

pid:6040 mod:MyModule[400000]: del magic


pid:6040 mod:MyModule[400000]: enum timetest!ma*

 index            address     name
     1             42cc56 :   main
     3             415810 :   malloc
     5             415450 :   mainCRTStartup