2023年1月

本文介绍使用调试器命令必须遵循的语法规则。使用Windbg调试时,应遵守以下一般语法规则:

  • 您可以在命令和参数中使用大小写字母的任意组合,除非在本节的主题中特别指出。
  • 可以用一个或多个空格或逗号(,)分隔多个命令参数。
  • 通常可以省略命令与其第一个参数之间的空格。如果这种省略不会造成任何歧义,则可以经常省略其他空格。

阅读本文中的命令引用注意以下事项:

  • 粗体字体的字符表示必须逐字键入的项目。
  • 斜体字体的字符表示参考主题“参数”部分中解释的参数。
  • 括号([xxx])中的参数是可选的。带有竖线([XXX|YYY])的括号表示可以使用一个或无一个封闭参数。
  • 带竖线(XXX|YYY)的大括号表示必须仅使用其中一个封闭参数。

二、字符串通配符语法

一些调试器命令具有接受各种通配符的字符串参数。这些类型的参数支持以下语法功能:

  •  星号(*)表示零个或多个字符。
  • 问号(?)表示任何单个字符。
  • 包含字符列表的括号([])表示列表中的任何单个字符。列表中只有一个字符匹配。在这些括号中,可以使用连字符(-)指定范围。例如,prog[er-t7]am匹配“progeam”、“program”、“progsam”、“progtam”和“prog7am”。
  • 数字符号(#)表示前面零个或多个字符。例如,lo#p与“lp”、“lop”、“loop”、“loop”等匹配。您还可以将数字符号与括号组合,因此m[ia]#n与“mn”、“min”、“man”、“maan”、“main”、“mian”、“miin”、“miain”等匹配。
  • 加号(+)表示前面的一个或多个字符。例如,lo+p与lo p相同,只是lo+p与“lp”不匹配。同样,m[ia]+n与m[ia]n相同,只是m[ia]+n与“mn”不匹配。A?+B和A*B一样,除了A?+B与“AB”不匹配。
  • 如果必须指定文字数字符号(#),问号(?),左括号([),右括号(]),星号(*)或加号(+)字符,必须在字符前面添加反斜杠(\)。如果不将连字符括在括号中,则连字符始终是文字。但不能在带括号的列表中指定文字连字符。

五、源文件行语法

可以将源文件行号指定为MASM表达式的全部或部分。这些数字计算出与该源代码行对应的可执行代码的偏移量。不能使用源代码行作为C++表达式的一部分。必须用重音符(`)将源文件和行号表达式括起来。以下示例显示源文件行号的完整格式。

`[[Module!]Filename][:LineNumber]`

命令脚本,就是将完成某个特定任务的相关命令组合在一起,保存在脚本文件里,加载到Windbg里执行,达到我们的目的。你可以理解为脚本就是一种语言,就像c或者汇编,但是他不需要编译器将其编译为可执行文件,而是由解释器将其内容翻译为对应的动作。而Windbg的脚本就是利用Windbg作为解释器,将脚本内容翻译为实际的动作。
既然可以作为一种语言,那么它就具有一般语言通常包含的要素:数据类型、变量、表达式、语句、函数等,下面我们分别简单讲一下。


一、数据类型
关于数据类型,Windbg的帮助里没有明确列举,但是,在使用时一般会遇到,数值和字符串这两种。

  • 数值
    数值没有太多需要解释的,和所有编程语言里的整数含义一样,在表示的时候有进制之分。
    代码:

    2进制  0b
    8进制  0n
    10进制  0t
    16进制  0x
  • 字符串
    字符串用一对 ” 括起来。比如上面的 ”hello windbg”。

二、变量
在windbg中变量的定义很特别,实际上,它并没有变量这个概念,所以,在学习的时候会觉得很别扭。不过,我们换个思路就容易了,变量实际上就是为了保存临时结果, 如果只想保存一些数值,那么伪寄存器(参考Windbg命令的语法规则系列)应该是比较好的选择,windbg提供了20个伪寄存器$t0-$t19,供命令保存临时数值变量。称他们为伪寄存器是有原因的,首先对他们的操作和寄存器一样,都是使用r命令,在C++表达式里都前面需要加@符,但是他们又不是真正的寄存器,只是windbg定义的名字而已。使用这些伪寄存器也是很方便的:

代码:

0:000> r $t0=0x123
0:000> r $t0
$t0=00000123

0:000> r eax
eax=004c1b89

0:000> r $t0=@eax
0:000> r $t0
$t0=004c1b89

Windbg命令脚本一文里,我们介绍了命令脚本语言的的组成要素,在本文里将对语句进行展开的讲解。这些语句主要是流程控制的语句,比如我们常见的条件分子和循环语句等。

; (命令分隔符)

分号(;)字符用于在一行中分隔多个命令。

Command1 ; Command2 [; Command3 ...]