其他 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