使用别名

别名 是自动替换为其他字符串的字符串。 可以在调试器命令中使用它们,并避免重新设置某些常见短语的tyty。

别名由 一个别名 和一个等效的 别名组成。 使用别名作为调试器命令的一部分时,该名称将自动替换为等效的别名。 在分析或执行命令之前,将立即进行此替换。

调试器支持三种类型的别名:

  • 可以设置和命名 用户命名别名

  • 可以设置 固定名称别名,但它们命名为 $u 0$u 1、... $u 9

  • 调试器设置并命名 自动别名

定义 User-Named 别名

定义用户命名别名时,可以选择别名和等效的别名:

  • 别名可以是不包含空格的任何字符串。

  • 别名等效项可以是任何字符串。 如果在键盘上输入,别名等效项不能包含前导空格或回车符。 或者,可以将它设置为等于内存中的字符串、数值表达式的值、文件的内容、环境变量的值或一个或多个调试器命令的输出。

别名和别名等效项都区分大小写。

若要定义或重新定义用户命名的别名,请使用 作为 (Set Alias) aS (Set Alias) 命令。

若要删除别名,请使用 ad (Delete Alias) 命令。

若要列出所有当前用户命名的别名,请使用 al (List Aliases) 命令。

定义 Fixed-Name 别名

有 10 个固定名称别名。 其别名为 $u 0$u 1、... $u 9。 其别名等效项可以是不包含 ENTER 击键的任何字符串。

使用 r (Registers) 命令定义固定名称别名的等效别名。 定义固定名称别名时,必须在字母“u”之前插入一个句点 (.) 。 等号 (=) 后面的文本是等效的别名。 别名等效项可以包含空格或分号,但前导空格和尾随空格将被忽略。 除非要在结果) 中加上引号,否则不应将别名等效项括在引号 (中。

注意 不要对固定名称别名使用 r (Registers) 命令混淆。 这些别名不是寄存器或伪寄存器,即使你使用 r 命令设置它们的别名等效项。 无需在这些别名之前添加 at (@) 符号,并且不能使用 r 命令 显示 这些别名之一的值。

默认情况下,如果未定义固定名称别名,则它是空字符串。

自动别名

调试器设置以下自动别名。

别名名称 等效别名

$ntnsym

计算机本机体系结构上 NT 符号的最合适的模块。 此别名可以等于 ntdllnt

$ntwsym

在使用 WOW64 的 32 位调试过程中,最适合 NT 符号的模块。 此别名可以是 ntdll32 或其他 32 位版本的 Ntdll.dll。

$ntsym

与当前计算机模式匹配的 NT 符号的最合适的模块。 在本机模式下调试时,此别名与 $ntnsym 相同。 在非本机模式下调试时,调试器会尝试查找与此模式匹配的模块。 (例如,在使用 WOW64 的 32 位调试期间,此别名与 $ntwsym.)

$CurrentDumpFile

调试器加载的最后一个转储文件的名称。

$CurrentDumpPath

调试器加载的最后一个转储文件的目录路径。

$CurrentDumpArchiveFile

调试器加载的上一个转储存档文件 (CAB 文件) 的名称。

$CurrentDumpArchivePath

调试器加载的最后一个转储存档文件 (CAB 文件的目录路径) 。

自动别名类似于 自动伪寄存器,不同之处在于,可以将自动别名与别名相关的令牌 ((如 ${ }) )一起使用,而不能对这些令牌使用伪寄存器。

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

定义别名后,可以在任何命令条目中使用它。 别名会自动替换为等效的别名。 因此,可以将别名用作表达式或宏。

即使别名用引号引起来,它也会正确展开。 由于别名等效项可以包含任意数量的引号或分号,因此别名等效项可以表示多个命令。

仅当名称与其他字符之间用空格分隔时,才会识别用户命名别名。 其别名的第一个字符必须以行开头或后跟空格、分号或引号。 其别名的最后一个字符必须以行尾或后跟空格、分号或引号。

注意“调试器命令”窗口中 输入以“as”、“aS”、“ad”或“al”开头的任何文本都不会收到别名替换。 此限制可防止别名命令呈现为不可操作。 但是,此限制还意味着,在行上跟随 adal 的命令不会替换其别名。 如果希望在以这些字符串之一开头的行中替换别名,请在别名前面添加分号。

但是,可以使用 ${ } 令牌扩展用户命名别名,即使它位于其他文本旁边也是如此。 还可以将此令牌与某些开关一起使用,以防止扩展别名或显示某些与别名相关的值。 有关这些情况的详细信息,请参阅 ${ } (别名解释器)

固定名称别名从行中的任何点正确展开,无论它如何嵌入到行的文本中。

不能使用仅在 WinDbg (.open 中可用的命令, .write_cmd_hist (写入命令历史记录) .lsrcpath.lsrcfix) 以及一些其他命令 (.hh.cls.wtitle.remote、kernel-mode .restart 和带有别名的用户模式 .restart) 。

在脚本文件中使用别名

在脚本文件中使用别名时,必须特别小心,确保别名在正确的时间扩展。 请考虑以下脚本:

.foreach (value {dd 610000 L4})
{
   as /x ${/v:myAlias} value + 1
   .echo value myAlias
}

ad myAlias

第一次通过 循环时 , as, aS (Set Alias) 命令将值分配给 myAlias。 分配给 myAlias 的值为 1 加 610000, (dd 命令) 的第一个输出。 但是,执行 .echo (Echo Comment) 命令时,myAlias 尚未展开,因此,我们不会看到610001,而是看到文本“myAlias”。

0:001> $$>< c:\Script02.txt
00610000 myAlias
00905a4d 0x610001
00000003 0x905a4e
00000004 0x4
0000ffff 0x5

问题是,在输入新的代码块之前,myAlias 不会展开。 循环的下一个条目是一个新块,因此 myAlias 会扩展到610001。 但为时已晚:我们应该看到610001第一次通过循环,而不是第二次。可以通过将 .echo (Echo Comment) 命令包含在新块中来解决此问题,如以下脚本所示。

.foreach (value {dd 610000 L4}) 
{
   as /x ${/v:myAlias} value + 1
   .block{.echo value myAlias}
}

ad myAlias

使用更改后的脚本,我们得到以下正确的输出。

0:001> $$>< c:\Script01.txt
00610000 0x610001
00905a4d 0x905a4e
00000003 0x4
00000004 0x5
0000ffff 0x10000

有关详细信息,请参阅 .block${ } (别名解释器)

在别名中使用 .foreach 令牌

在别名的定义中使用 .foreach 令牌时,必须特别小心,以确保扩展令牌。 请考虑以下命令序列。

r $t0 = 5
ad myAlias
.foreach /pS 2 /ps 2 (Token {?@$t0}) {as myAlias Token}
al

第一个命令将 $t 0 伪寄存器的值设置为 5。 第二个命令删除以前可能已分配给 myAlias 的任何值。 第三个命令采用 ?@$t 0 命令的第三个标记,并尝试将该令牌的值分配给 myAlias。 第四个命令列出所有别名及其值。 我们预期 myAlias 的值为 5,但该值为单词“Token”。

   Alias            Value  
 -------          ------- 
 myAlias          Token 

问题是 as 命令 位于 .foreach 循环正文中行的开头。 当行以 as 命令开头时,不会展开该行中的别名和标记。 如果在 as 命令之前放置分号或空格,则会展开任何已具有值的别名或标记。 在此示例中,myAlias 未展开,因为它还没有值。 令牌已展开,因为它的值为 5。 下面是相同的命令序列,在 作为 命令之前添加分号。

r $t0 = 5
ad myAlias
.foreach /pS 2 /ps 2 (Token {?@$t0}) {;as myAlias Token}
al

现在,我们得到了预期的输出。

  Alias            Value  
 -------          ------- 
 myAlias          5 

递归别名

可以在任何别名的定义中使用固定名称别名。 还可以在固定名称别名的定义中使用用户命名别名。 但是,若要在另一个用户命名别名的定义中使用用户命名别名,必须在 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

别名示例

可以使用别名,这样就不必键入长符号名称或复杂符号名称,如以下示例所示。

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

以下示例类似于前面的示例,但它使用固定名称别名。

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

可以将别名用作频繁使用的命令的宏。 以下示例将 eaxebx 寄存器递增两次。

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"

Tools.ini 文件

在 CDB (和 NTSD) 中,可以在 tools.ini 文件中预定义固定名称别名。 若要预定义固定名称别名,请将所需的 $u 字段添加到 [NTSD] 条目,如以下示例所示。

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

不能在 Tools.ini 文件中设置用户命名别名。

Fixed-Name 别名与 User-Named 别名

与固定命名别名相比,用户名别名更易于使用。 其定义语法更简单,可以使用 al (List Aliases) 命令列出它们。

如果固定命名的别名在其他文本旁边使用,则会替换它们。 若要在用户命名别名位于其他文本旁边时替换该别名,请将它括在 ${ } (别名解释器) 令牌中。

固定名称别名替换发生在用户命名别名替换之前。