Windbg命令的语法规则系列(二)

二、字符串通配符语法

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

  • 星号(*)表示零个或多个字符。
  • 问号(?)表示任何单个字符。
  • 包含字符列表的括号([])表示列表中的任何单个字符。列表中只有一个字符匹配。在这些括号中,可以使用连字符(-)指定范围。例如,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”不匹配。
  • 如果必须指定文字数字符号(#),问号(?),左括号([),右括号(]),星号(*)或加号(+)字符,必须在字符前面添加反斜杠(\)。如果不将连字符括在括号中,则连字符始终是文字。但不能在带括号的列表中指定文字连字符。

指定符号的参数还支持一些附加功能。除了标准字符串通配符之外,还可以在用于指定符号的文本表达式之前使用下划线(_)。将此表达式与符号匹配时,调试器将下划线视为任何数量的下划线,甚至为零。此功能仅在匹配符号时适用。它一般不适用于字符串通配符表达式。

三、寄存器语法

调试器可以控制寄存器和浮点寄存器。在表达式中使用寄存器时,应在寄存器之前添加at符号(@)。这个at符号告诉调试器以下文本是寄存器的名称。如果您使用的是masm表达式语法,则可以省略某些非常常见的寄存器的at符号。在基于x86的系统上,可以省略eax、ebx、ecx、edx、esi、edi、ebp、eip和efl寄存器的at符号。但是,如果指定一个不带at符号的不太常见的寄存器,调试器首先尝试将文本解释为十六进制数字。如果文本包含非十六进制字符,调试器接下来将文本解释为符号。最后,如果调试器找不到匹配的符号,则调试器将文本解释为寄存器。如果使用C++表达式语法,则总是需要AT-符号。

r(registers)命令是此规则的一个例外。调试器总是将其第一个参数解释为寄存器。(不需要或不允许使用at符号。)如果R命令有第二个参数,则根据默认表达式语法进行解释。如果默认表达式语法是C++,则必须使用以下命令将EBX寄存器复制到EAX寄存器中。

0:000> r eax = @ebx

基于x86的处理器上的标志

基于x86的处理器也使用多个1位寄存器,称为标志。

寄存器和线程

每个线程都有自己的寄存器值。这些值在线程执行时存储在CPU寄存器中,在另一个线程执行时存储在内存中。在用户模式下,对寄存器的任何引用都被解释为与当前线程关联的寄存器。有关当前线程的更多信息,请参阅控制进程和线程。在内核模式中,对寄存器的任何引用都被解释为与当前寄存器上下文关联的寄存器。可以设置寄存器上下文以匹配特定线程、上下文记录或陷阱帧。您只能为指定的寄存器上下文显示最重要的寄存器,并且不能更改它们的值。

四、伪寄存器语法

调试器支持保存某些值的多个伪寄存器。调试器将自动伪寄存器设置为某些有用的值。用户定义的伪寄存器是可写入或读取的整数变量。所有伪寄存器都以美元符号($)开头。如果使用MASM语法,可以在美元符号之前添加at符号(@)。这个at符号告诉调试器以下标记是寄存器或伪寄存器,而不是符号。如果省略了at符号,调试程序的响应会更慢,因为它必须搜索整个符号表。

例如,以下两个命令产生相同的输出,但第二个命令更快。

0:000> ? $exp
Evaluate expression: 143 = 0000008f
0:000> ? @$exp
Evaluate expression: 143 = 0000008f

如果存在与伪寄存器同名的符号,则必须添加at符号@。如果使用C++表达式语法,则总是需要at符号(@)。

r(registers)命令是此规则的一个例外。调试器总是将其第一个参数解释为寄存器或伪寄存器。(不需要或不允许使用at符号@。)如果r命令有第二个参数,则根据默认表达式语法进行解释。如果默认表达式语法是C++,则必须使用以下命令将$T2伪寄存器复制到$T1伪寄存器。

0:000> r $t1 = @$t2

4.1、自动伪寄存器

调试器自动设置以下伪寄存器:

伪寄存器 描述

$ea


已执行的最后一个指令的有效地址。 如果此指令没有有效的地址,调试器将显示"错误的寄存器错误"。 如果此指令有两个有效的地址,调试器会显示第一个地址。


$ea2


已执行的最后一个指令的第二个的有效地址。 如果此指令不具有两个有效的地址,调试器将显示"错误的寄存器错误"。


$exp


最后一个表达式的计算。


$ra


寄信人地址为当前位于堆栈上。

此地址是在执行命令中尤其有用。 例如, g @$ ra继续,直到找到的寄信人地址 (尽管(Go Up) gu是"单步执行"当前函数的更精确地有效的方法)。


$ip


指令指针寄存器。

基于 x86 的处理器:与相同eip基于 Itanium 处理器:与相关iip。 (有关详细信息,请参阅此表后面的说明)。基于 x64 的处理器:与相同rip


$eventip


当前事件的时间处的指令指针。 此指针通常与匹配$ip,除非你切换线程或手动更改指令指针的值。


$previp


上一事件的时间处的指令指针。 (中断到调试器计为一个事件。)


$relip


指令指针与当前事件相关的。 分支跟踪时,此指针是指向分支源的指针。


$scopeip


当前指令指针本地上下文(也称为作用域)。


$exentry


当前进程的第一个可执行文件的入口点的地址。


$retreg


主要的返回值寄存器中。

基于 x86 的处理器:与相同eax基于 Itanium 处理器:与相同ret0基于 x64 的处理器:与相同rax


$retreg64


在 64 位格式中注册主要的返回值。

x86 处理器:与相同edx: eax对。


$csp


当前调用堆栈指针。 此指针是最具代表性的调用堆栈深度的寄存器。

基于 x86 的处理器:与相同esp基于 Itanium 处理器:与相同bsp基于 x64 的处理器:与相同rsp


$p


值的最后一个d \* (显示内存)打印命令。


$proc


当前进程 (即,地址 EPROCESS 块) 的地址。


$thread


当前线程的地址。 在内核模式调试,此地址是 ETHREAD 块的地址。 在用户模式调试,此地址为线程环境块 (TEB) 的地址。


$peb


当前进程的进程环境块 (PEB) 的地址。


$teb


当前线程的线程环境块 (TEB) 的地址。


$tpid


拥有当前线程的进程的进程 ID (PID)。


$tid


当前线程的线程 ID。


$dtid

 

$dpid

 

$dsid

 

$bpNumber


相应的断点的地址。 例如,美元 bp3 (或美元 bp03) 指的是断点的断点 ID 为 3。 数字始终是一个十进制数。 如果任何断点不的 ID 为数量$bp计算结果为零。 有关断点的详细信息,请参阅使用断点


$frame


当前的帧索引。 此索引是相同的帧号.frame (设置本地上下文)命令使用。


$dbgtime


根据计算机上运行调试器的当前时间。


$callret


返回值的最后一个函数.call (调用函数)中使用或调用.fnret /s命令。 数据类型$callret是此返回值的数据类型。


$extret

 

$extin

 

$clrex

 

$lastclrex


托管仅调试:上一次遇到公共语言运行时 (CLR) 异常对象的地址。


$ptrsize


指针的大小。 在内核模式下,此大小是目标计算机上的指针大小。


$pagesize


在一页上的内存字节数。 在内核模式下,此大小为目标计算机上的页面大小。


$pcr

 

$pcrb

 

$argreg

 

$exr_chance


当前的异常记录的可能性。


$exr_code


当前的异常记录异常代码。


$exr_numparams


当前的异常记录中的参数数量。


$exr_param0


当前的异常记录中的参数 0 的值。


$exr_param1


当前的异常记录中的值的参数 1。


$exr_param2


当前的异常记录中的参数 2 的值。


$exr_param3


当前的异常记录中的参数 3 的值。


$exr_param4


当前的异常记录中的参数 4 的值。


$exr_param5


当前的异常记录中的参数 5 的值。


$exr_param6


当前的异常记录中的参数 6 的值。


$exr_param7


当前的异常记录中的值的参数 7。


$exr_param8


当前的异常记录中的参数 8 的值。


$exr_param9


当前的异常记录中的值的参数 9。


$exr_param10


当前的异常记录中的参数 10 的值。


$exr_param11


当前的异常记录中的参数 11 的值。


$exr_param12


当前的异常记录中的值的参数 12。


$exr_param13


当前的异常记录中的值的参数 13。


$exr_param14


当前的异常记录中的值为 14 个参数。


$bug_code


如果发生了错误检查,这是错误代码。 适用于实时内核模式调试和内核故障转储。


$bug_param1


如果发生了错误检查,这是参数 1 的值。 适用于实时内核模式调试和内核故障转储。


$bug_param2


如果发生了错误检查,这是参数 2 的值。 适用于实时内核模式调试和内核故障转储。


$bug_param3


如果发生了错误检查,这是参数 3 的值。 适用于实时内核模式调试和内核故障转储。


$bug_param4


如果发生了错误检查,这是参数 4 的值。 适用于实时内核模式调试和内核故障转储。

在某些调试场景中,这些伪寄存器中的一些可能不可用。例如,在调试用户模式小型转储或某些内核模式转储文件时,不能使用$peb、$tid和$tpid。在某些情况下,您可以从~(thread status)而不是$tid学习线程信息。不能在第一个调试器事件上使用$previp伪寄存器。除非是分支跟踪,否则不能使用$relip伪寄存器。如果使用不可用的伪寄存器,则会出现语法错误。

一个包含结构的地址的伪寄存器(比如$线程)、$、$、$和$将根据C++表达式计算器中的适当数据类型进行评估,但不是在表达式求值器中。例如,命令?$teb显示teb的地址,而命令??@$teb显示整个teb结构。有关详细信息,请参见计算表达式。在基于Itanium的处理器上,IIP寄存器是捆绑对齐的,这意味着它指向包含当前指令的捆绑中的插槽0,即使正在执行不同的插槽。所以IIP不是完整的指令指针。$IP伪寄存器是实际的指令指针,包括bundle和slot。其他持有地址指针的伪寄存器($ra、$retreg、$eventip、$previp、$relip和$exentry)的结构与所有处理器上的$ip相同。

您可以使用r命令更改$ip的值。此更改也会自动更改相应的寄存器。当执行恢复时,它将恢复到新的指令指针地址。这个寄存器是唯一可以手动更改的自动伪寄存器。注意:在masm语法中,可以用句点(.)表示$ip伪寄存器。。在此期间之前不添加at符号(@),也不将该期间用作r命令的第一个参数。在C++表达式中不允许使用此语法。自动伪寄存器类似于自动别名。但是,可以将自动别名与别名相关的令牌(如$)一起使用,并且不能将伪寄存器与此类令牌一起使用

4.2、用户定义的伪寄存器

有20个用户定义的伪寄存器($t0、$t1、…$t19)。这些伪寄存器是可以通过调试器读写的变量。您可以在这些伪寄存器中存储任何整数值。它们作为循环变量尤其有用。 若要写入到一个这些伪寄存器,使用r (寄存器)命令,如以下示例所示。

0:000> r $t0 = 7
0:000> r $t1 = 128*poi(MyVar)

与所有伪寄存器一样,您可以在任何表达式中使用用户定义的伪寄存器,如下例所示。

0:000> bp $t3
0:000> bp @$t4
0:000> ?? @$t1 + 4*@$t2 

除非使用?与R命令一起切换。如果使用此开关,伪寄存器将获取分配给它的任何类型。例如,下面的命令将unicode_string**类型和0x0012ffbc值分配给$t15。

0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc

启动调试器时,用户定义的伪寄存器使用零作为默认值。注意,别名$u0、$u1、…$u9不是伪寄存器,尽管它们的外观相似。

4.3、示例

下面的示例设置了当前线程调用每次命中的断点NtOpenFile。 但在其他线程调用时,则不会命中此断点NtOpenFile

kd> bp /t @$thread nt!ntopenfile

下面的示例执行一个命令,直到寄存器保留指定的值。首先,在名为“eaxstep”的脚本文件中放入以下条件步进代码。

.if (@eax == 1234) { .echo 1234 } .else { t "$<eaxstep" }

接下来,发出以下命令。

t "$<eaxstep"

调试器执行一个步骤,然后运行您的命令。在这种情况下,调试器运行脚本,该脚本显示1234或重复该过程。

原文地址:https://www.cnblogs.com/yilang/p/11411467.html

时间: 2024-10-10 20:27:28

Windbg命令的语法规则系列(二)的相关文章

Python学习系列(四)Python 入门语法规则2

Python学习系列(四)Python 入门语法规则2 2017-4-3 09:18:04 编码和解码 Unicode.gbk,utf8之间的关系 2.对于py2.7, 如果utf8>gbk, utf8解码成Unicode,再将unicode编码成gbk 对于py3.5 如果utf8>gbk, utf8 直接编码成gbk(中间那一步直接被优化了) 3.很多时候,这个可以直接跳过,只有当编码出下问题的时候,再考虑这个知识点 二.运算符 1.算数运算: 2.比较运算: 3.赋值运算: 4.逻辑运算

docker常用命令、镜像命令、容器命令、数据卷,使用dockerFile创建镜像,dockefile的语法规则。

一.docker常用命令? 1. 常用帮助命令 1.1 docker的信息以及版本号 /* docker info 查看docker的信息 images2 docker本身就是一个镜像. docker version 查看docker的版本号 */ 1.2 docker的启动,停止,重启,查看状态. // service docker start/stop/restart/status 二.镜像命令? 1. 列举出所有的镜像(本地镜像) /* docker images 所拥有的参数: dock

Apache Kafka系列(二) 命令行工具(CLI)

Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka命令行工具(Command Line Interface,CLI),下文简称CLI. 1. 启动Kafka 启动Kafka需要两步: 1.1. 启动ZooKeeper [[email protected] kafka_2.12-0.11.0.0]# bin/zookeeper-server-start.sh config/zookeeper.properties 1.2.

Maven 系列 二 :Maven 常用命令,手动创建第一个 Maven 项目

1.根据 Maven 的约定,我们在D盘根目录手动创建如下目录及文件结构: 2.打开 pom.xml 文件,添加如下内容: 1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

Maven 系列 二 :Maven 常用命令,手动创建第一个 Maven 项目【转】

1.根据 Maven 的约定,我们在D盘根目录手动创建如下目录及文件结构: 2.打开 pom.xml 文件,添加如下内容: 1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

windbg命令详解

DLL 该扩展仅在内核模式下使用,即使它是在Ext.dll中的. Windows NT 4.0 Ext.dll Windows 2000 Ext.dll Windows XP和之后 Ext.dll 注释 如果不提供参数,调试器会列出所有进程,以及时间和优先级统计.这和使用!process @#Process 0 作为CommandString值一样. To terminate execution at any point, press CTRL+BREAK (in WinDbg) or CTRL

原始套接字基础(原始套接字系列二)

在进入Raw Socket多种强大的应用之前,我们先讲解怎样建立一个Raw Socket及怎样用建立的Raw Socket发送和接收IP包. 建立Raw Socket 在Windows平台上,为了使用Raw Socket,需先初始化WINSOCK: // 启动 WinsockWSAData wsaData;if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0){ cerr << "Failed to find Winsock 2.1 or

C语言快速入门系列(二)

C语言快速入门系列(二) 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译运行! 在这一节中我们会对C语言的基本语法进行进一步的学习! C语言是一门语言,可以和英语进行类比,英语句子 = 单词 + 语法 同样C语言的代码语句,也有着一套自己的规则! 废话不多说,直接正文! 本节学习路线图: 正文: 1.基本字符集 1.1 标识符 ①何为标识符:在C语言中,符号常量,变量,数组,函数等都需要一定的名称,我们把这种名称成为标识符 ②标识符的命名规则 答:只能

Wireshark入门与进阶系列(二)

摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文由CSDN-蚍蜉撼青松 [主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 上一篇文章我们讲了使用Wireshark进行数据包捕获与保存的最基本流程,更通常的情况下,我们对于要捕获的数据包及其展示.存储可能有一定要求,例如: 我们希望捕获的数据包中对我们有用