Debugging Tools for Windows

使用别名

别名是用来自动被其他字符串替换的字符串。可以在调试器命令中使用它们来避免重复输入特定的字符串。

别名由别名(alias name)和别名等价字符串(alias equivalent)组成。当使用 别名作为调试器命令的一部分时,会被自动替换为等价字符串。这种替换是在命令被解析或执行之前进行的。

调试器支持以下三种别名:

定义自定义别名

定义自定义别名时,可以选择别名和等价字符串:

别名和等价字符串都是大小写敏感的。

使用as (Set Alias)aS (Set Alias)命令来定义或修改自定义别名。

使用ad (Delete Alias)命令删除别名。

列举当前所有自定义别明,使用al (List Aliases)命令。

定义固定别名

有10个固定别名。他们是$u0, $u1, ..., $u9。他们的等价字符串可以是不包含ENTER键的任意字符串。

使用r (Registers)命令为固定别明指定等价字符串。定义固定别名时,必须在字母"u"之前插入点号(.)。等号(=)之后的文本是等价字符串。等价字符串可以包含空格或分号,但是头部和尾部的空格被忽略掉。不能用引号将等价字符串括起来(除非希望替代结果中包含引号)。

注意 r (Registers)命令设置固定别名容易混淆。这些别明不是寄存器或伪寄存器,即使使用了r命令来设置了他们的等价字符串。这些别名前不需要添加at符号(@),也不能使用r命令来显示这些别明的值。

默认情况下,如果没有定义固定别名,他们是空字符串。

自动别名

调试器预设了下面一些自动别名

别名 等价字符串
$ntnsym 当前系统架构NT符号的最适合的模块。该别名可能等于ntdllnt
$ntwsym 使用WOW64的32位调试最适合的NT符号的模块名。该别名可以是ntdll32Ntdll.dll的其他32位版本。
$ntsym 当前机器模式最适合的NT符号的模块名。以本地模式调试时,该别名和$ntnsym一样。当在非本地模式调试时,调试器会尝试找到适合这个模式的模块名。(例如,在使用WOW64的32位调试时,该别名和$ntwsym相同。)
$CurrentDumpFile 调试器上一次加载的dump文件名字。
$CurrentDumpPath 调试器上一次加载的dump文件所在的目录。
$CurrentDumpArchiveFile 调试器上一次加载的dump存档文件(CAB文件)名字。
$CurrentDumpArchivePath 调试器上一次加载的dump存档文件(CAB文件)所在目录。

除了可以使用别名相关的字符(例如${ })而伪寄存器不可以使用之外,自动别名和自动伪寄存器类似。

在调试器命令窗口使用别名

定义了别名之后,可以在任何命令入口中使用。别名会自动被等价字符串替代。因此,可以将别名作为表达式或者宏使用。

即使被引号括起来,别名仍然可以被正确展开。因为等价字符串可以包含任意数量的引号和分号,等价字符串可以代表多个命令。

自定义别名和其他字符之间必须使用空白字符隔开才能被识别。别名的第一个字符之前和最末一个字符之后必须是空格、分号或者引号。

注意调试器命令窗口输入的以"as", "aS", "ad", 或者 "al" 开头的文本不会进行别名替换。该限制避免不合适的别名替换。但是,这也意味着一行中跟在adal 之后的命令的别名不会被替换掉。如果想在以这些字符串开头的行中使用别名替换,可以在别名前加上分号。

也可以使用${ }符号来展开和其他文本连在一起的自定义别名。也可以和特定的开关一起使用该符号来避免别名被展开,或者显示特定别名的值。关于这些情况的更多信息,查看${ }  (Alias Interpreter)

不管在文本中嵌入得多深,自定义别名可以在一行的任意位置展开。

只在WinDbg中支持的命令(.open, .write_cmd_hist (Write Command History), .lsrcpath, and .lsrcfix)和少数辅助命令 (.hh, .cls, .wtitle, .remote, 内核模式.restart, 和用户模式.restart)) 不能使用别名。

示例

如下例,可以使用别名来避免输入很长的或很复杂的符号。

0:000> as Short usersrv!NameTooLongToWantToType
0:000> dw Short +8

这个例子和上一个类似,但是使用固定别名。

0:000> r $.u0=usersrv!NameTooLongToWantToType
0:000> dw $u0+8

可以为经常使用的命令定义别名作为宏。下面的示例将eaxebx增加2次。

0:000> as GoUp r eax=eax+1; r ebx=ebx+1
0:000> GoUp
0:000> GoUp

下例使用别名简化命令输入。

0:000> as Cmd "dd esp 14; g"
0:000> bp MyApi Cmd 

下例和上面的示例类似,但是使用固定别名。

0:000> r $.u5="dd esp 14; g"
0:000> bp MyApi $u5 

前面两个示例实际上是下面的命令。

0:000> bp MyApi "dd esp 14; g"

递归的别名

在任何别名的定义中都可以使用固定别名。也可以在固定别名定义中使用自定义别名。但是,要在自定义别名的定义中使用自定义别名,必须在asaS命令前加上分号,否则该行不会进行别名替换。

在这种情况下使用递归别名,每个别名都在使用的地方马上被替换。例如,下面的显示是3,不是7

0:000> r $.u2=2 
0:000> r $.u1=1+$u2 
0:000> r $.u2=6 
0:000> ? $u1 
Evaluate expression: 3 = 00000003

类似的,下例的显示是3,不是7

0:000> as fred 2 
0:000> r $.u1= 1 + fred 
0:000> as fred 6 
0:000> ? $u1 
Evaluate expression: 3 = 00000003

下面的例子也是正确的,并且显示为9

0:000> r $.u0=2 
0:000> r $.u0=7+$u0 
0:000> ? $u0
Evaluate expression: 9 = 00000009

Tools.ini文件

在 CDB (和NTSD)中,可以在tools.ini文件中预定义固定别名。 与定义固定别名如下例,在[NTSD]入口中添加需要的$u 字段。

[NTSD]
$u1:_ntdll!_RtlRaiseException
$u2:"dd esp 14;g"
$u9:$u1 + 42

不能在Tools.ini文件中设置自定义别名。

固定别名和自定义别名对比

自定义别名比固定别名要更加容易使用。他们的定义更简单,并且可以使用al (List Aliases)命令列举出来。

固定别名即使和其他文本连在一起也能被替换掉。而将和其他文本连接在一起的自定义别名替换掉需要使用${ }  (Alias Interpreter)标记。

固定别名的替换会在自定义别名替换之前进行。

Build machine: CAPEBUILD