本文介紹使用調試器命令必須遵循的語法規則。使用Windbg調試時,應遵守以下一般語法規則:
- 您可以在命令和參數中使用大小寫字母的任意組合,除非在本節的主題中特別指出。
- 可以用一個或多個空格或逗號(,)分隔多個命令參數。
- 通常可以省略命令與其第一個參數之間的空格。如果這種省略不會造成任何歧義,則可以經常省略其他空格。
閱讀本文中的命令引用注意以下事項:
- 粗體字體的字符表示必須逐字鍵入的項目。
- 斜體字體的字符表示參考主題“參數”部分中解釋的參數。
- 括號([xxx])中的參數是可選的。帶有豎線([XXX|YYY])的括號表示可以使用一個或無一個封閉參數。
-
帶豎線(XXX|YYY)的大括號表示必須僅使用其中一個封閉參數。
一、數字表達式
調試器接受兩個不同類型的數值表達式:C++表達式和MASM 表達式。 每個這些表達式遵循用於輸入和輸出自己語法規則。
1.1、MASM 數字和運算符
- MASM表達式中的數字
在masm表達式中我們可以輸入二進制、八進制、十進制、十六進制數字。 使用n(設置基數)命令將默認基數設置為16、10或8。所有未固定的數字都將在此基數中解釋。可以通過指定0x前綴(十六進制)、0n前綴(十進制)、0t前綴(八進制)或0y前綴(二進制)來重寫默認基數。 您還可以通過在數字后面添加h來指定十六進制數字。您可以在數字中使用大寫或小寫字母。例如,“0x4ab3”、“0x4ab3”、“4ab3h”、“4ab3h”和“4ab3h”具有相同的含義。 如果不在表達式的前綴后面添加數字,則該數字將被讀取為0。因此,您可以將0寫為0,前綴后跟0,並且只寫前綴。例如,在十六進制中,“0”、“0x0”和“0x”具有相同的含義。 您可以以XXXXXXXX`XXXXXXXX格式輸入十六進制64位值。 - MASM表達式中的符號
在masm表達式中,任何符號的數值都是其內存地址。根據符號所指的內容,此地址是全局變量、局部變量、函數、段、模塊或任何其他可識別標簽的地址。要指定與地址關聯的模塊,請包括模塊名稱和感嘆號(!)在符號名稱之前。如果符號可以解釋為十六進制數,請在符號名之前包含模塊名和感嘆號,或僅包含感嘆號。 使用兩個冒號(:)或兩個下划線(_)指示類的成員。 只有在符號名稱前面添加模塊名稱和感嘆號時,才能在符號名稱中使用重音符(`)或撇號(')。 -
MASM表達式中的數字運算符
可以使用一元運算符修改表達式的任何組件。您可以使用二進制運算符組合任意兩個組件。一元運算符優先於二元運算符。使用多個二進制運算符時,運算符遵循下表中描述的固定優先級規則。 您可以始終使用括號來覆蓋優先規則。如果一個MASM表達式的一部分被括在括號中,並且在表達式之前出現兩個符號(@),則表達式根據C++表達式規則進行解釋。不能在兩個at符號和左括號之間添加空格。還可以使用@ @ C++(…)指定表達式計算器。或@@masm(…).執行算術計算時,MASM表達式計算器將所有數字和符號視為ulong64類型。一元地址運算符將ds作為地址的默認段。表達式按運算符優先順序計算。如果相鄰運算符的優先級相等,則表達式將從左到右進行計算。
可以使用以下一元運算符:
運算符 含義 +
一元加
-
一元負
非
如果參數為零,則返回 1。 任何非零值的參數,則返回零。
hi
高 16 位
low
低 16 位
by
從指定的地址的低序位字節。
$pby
與相同通過,但前者的物理地址。 可以讀取僅使用默認緩存行為的物理內存。
wo
從指定的地址的低序位字。
$pwo
與相同wo ,但前者的物理地址。 可以讀取僅使用默認緩存行為的物理內存。
dwo
從指定的地址雙字。
$pdwo
與相同dwo ,但前者的物理地址。 可以讀取僅使用默認緩存行為的物理內存。
qwo
從指定的地址四字。
$pqwo
與相同qwo ,但前者的物理地址。 可以讀取僅使用默認緩存行為的物理內存。
poi
從指定的地址指針大小的數據。 指針大小為 32 位或 64 位。 在內核調試,此大小基於的處理器目標計算機。 在用戶模式下調試在基於 Itanium 的計算機上,此大小為 32 位或 64 位,具體取決於目標應用程序。 因此, poi是要使用如果你想指針大小的數據的最佳運算符。
$ppoi
與相同poi ,但前者的物理地址。 可以讀取僅使用默認緩存行為的物理內存。
可以使用以下二進制運算符。 每個單元格中的運算符優先於較小的單元中。 相同單元中的運算符均屬於相同的優先級,從左到右進行分析。
運算符 含義 *
/
mod (或 %)
乘法
整數除法
取模 (余數)
+
-
添加
減法
<<
>>
>>>
左的移
邏輯右移位
算術右移位運算
= (或 = =)
<
>
<=
>=
!=
等於
小於
大於
小於或等於
大於或等於
不等於
和(或 &)
位與
xor (或 ^)
按位 XOR (異或)
或(或 |)
按位 OR 運算符
<, >、 =、 = =、 和 ! = 的比較運算符計算結果為 1,如果表達式為 true 或為零,如果表達式為 false。 單個等號 (=) 是雙等號 (= =) 相同。 不能使用副作用或 MASM 表達式中的分配。在"操作數錯誤"中無效的操作 (如被零除) 結果返回到調試器命令窗口。
-
MASM表達式中的非數字運算符
此外可以在 MASM 表達式中使用以下其他運算符。
運算符 含義 $fnsucc(FnAddress, RetVal, Flag)
解釋RetVal位於函數的返回值的值FnAddress地址。 如果此返回值被返回成功代碼,稱為$fnsucc返回TRUE。 否則為$fnsucc返回FALSE。
如果返回類型為布爾值、 bool、 句柄、 HRESULT 或 NTSTATUS, $fnsucc正確理解是否在指定的返回值被稱為成功代碼。 返回類型是否為指針,所有值,而NULL才會被視為成功代碼。 成功的值對於任何其他類型進行定義標志。 如果標志為 0,一個非零值的RetVal為 success。 如果標志為 1,零值的RetVal為 success。
$iment (地址)
加載的模塊列表中返回映像入口點的地址。 地址指定的可移植可執行文件 (PE) 映像基址。 通過查找映像的 PE 映像標頭中的映像入口點找到該項,地址指定。
您可以使用此函數的是已在模塊列表中,並設置這兩個模塊無法解析的斷點通過使用bu命令。
$scmp("String1", "String2")
計算結果為-1、 0 或 1,如strcmp C 函數。
$sicmp("String1", "String2")
計算結果為-1、 0 或 1,如stricmp Microsoft Win32 函數。
$spat("String", "Pattern")
計算結果為,則返回 TRUE或FALSE取決於是否字符串匹配模式。 匹配不區分大小寫。 模式可以包含各種通配符和說明符。 有關語法的詳細信息,請參閱字符串通配符語法。
$vvalid(Address, Length)
確定是否內存范圍的開始處地址,並為擴展長度字節是否有效。 如果有效,內存$vvalid的計算結果為 1。 如果內存是無效的$vvalid計算結果為 0。
- MASM表達式中的寄存器和偽寄存器
您可以在masm表達式中使用寄存器和偽寄存器。您可以在所有寄存器和偽寄存器之前添加at符號(@)。at符號使調試器更快地訪問該值。 對於最常見的基於x86的寄存器來說,這個at符號是不必要的。對於其他寄存器和偽寄存器,我們建議您添加at符號,但實際上並不需要它。如果省略了較不常用的寄存器的at符號,調試器將嘗試將文本解析為十六進制數,然后作為符號,最后作為寄存器。 還可以使用句點(.)指示當前指令指針。在此期間之前不應添加at符號,並且不能將期間用作r命令的第一個參數。此期間的含義與$IP偽寄存器相同。 - MASM表達式中的源行號
可以在masm表達式中使用源文件和行號表達式。必須使用重音符(`)將這些表達式括起來。
1.2、C++數字和運算符
Windbg中的C++表達式解析器支持所有形式的C++表達式語法。該語法包括所有數據類型(包括指針、浮點數和數組)和所有C++一元和二元運算符。
- C++表達式中的數字
C++表達式中的數字被解釋為十進制數,除非用另一種方式指定它們。要指定十六進制整數,請在數字前面添加0x。要指定一個八進制整數,請在數字前面加0(零)。默認調試器基數不影響您輸入C++表達式的方式。不能直接輸入二進制數(除非在C++表達式中嵌套了一個MASM表達式)。您可以以XXXXXXX`XXXXXXXXX格式輸入一個十六進制的64位值。(您也可以省略重音符('.))兩種格式產生相同的值。可以使用帶整數值的L、U和I64后綴。創建的數字的實際大小取決於后綴和輸入的數字。有關此解釋的更多信息,請參見C++語言引用。C++表達式計算器的輸出保持C++表達式規則指定的數據類型。但是,如果將此表達式用作命令的參數,則始終進行強制轉換。例如,當整數值用作命令參數中的地址時,不必向指針強制轉換整數值。如果表達式的值不能有效地轉換為整數或指針,則會出現語法錯誤。對於某些輸出,可以使用0N(十進制)前綴,但不能將其用於C++表達式輸入。 - C++表達式中的字符和字符串
您可以通過將字符用單引號(“)包圍來輸入字符。標准的C++轉義字符是允許的。您可以通過將字符串文本用雙引號(“)包圍來輸入字符串文本。您可以在這樣的字符串中使用\“作為轉義序列。但是,字符串對表達式計算器沒有意義。 - C++表達式中的符號
在C++表達式中,每個符號根據其類型來解釋。 根據符號所指的內容,可以將其解釋為整數、數據結構、函數指針或任何其他數據類型。如果在C++表達式中使用與C++數據類型(如未修改的模塊名)不符的符號,則會出現語法錯誤。 如果符號可能不明確,可以添加模塊名和感嘆號(!)或者只在符號前加一個感嘆號。 只有在符號名稱前添加模塊名稱和感嘆號,才能在符號名稱中使用重音符(`)或撇號(“)。 在模板名稱后面添加分隔符時,可以在這些分隔符之間添加空格。 -
C++表達式中的運算符您可以始終使用括號來覆蓋優先規則。如果在括號中包含一部分C++表達式,並在表達式之前加上兩個符號(@),則根據MASM表達式規則對表達式進行解釋。不能在兩個at符號和左括號之間添加空格。此表達式的最終值作為ULUN64值傳遞給C++表達式求值器。還可以使用@ @ C++(…)指定表達式計算器。或@@masm(…).數據類型通常以C++語言表示。指示數組([])、指針成員(->)和UDT成員(.)的符號。和類(::)的成員都可以識別。支持所有算術運算符,包括賦值和副作用運算符。但是,不能使用new、delete和throw運算符,也不能實際調用函數。支持指針算法並正確縮放偏移量。請注意,不能向函數指針添加偏移量。(如果必須向函數指針添加偏移量,請先將偏移量強制轉換為字符指針。)與C++一樣,如果使用具有無效數據類型的運算符,則會發生語法錯誤。調試器的C++表達式分析器使用的規則比大多數C++編譯器稍微寬松一些,但是所有的主要規則都被強制執行。例如,不能移動非整數值。可以使用以下運算符。每個單元格中的運算符優先於較低單元格中的運算符。同一單元格中的運算符具有相同的優先級,並從左到右進行分析。與C++一樣,表達式評估在其值已知時結束。這個結尾使您能夠有效地使用表達式,例如??myptr和&*myptr。
運算符 含義 表達式 // 注釋
忽略所有后續文本
類 ::成員
類 :: ~成員
::名稱
類的成員
類 (析構函數) 的成員
全局
結構 。 字段
指針 - > 字段
Name [integer]
LValue ++
LValue --
dynamic_cast <type>(Value)
static_cast <type>(Value)
reinterpret_cast <type>(Value)
const_cast <type>(Value)
結構中的字段
引用結構中的字段
數組下標
增量 (之后評估版)
遞減 (后評估版)
類型轉換 (始終執行)
類型轉換 (始終執行)
類型轉換 (始終執行)
類型轉換 (始終執行)
(type) Value
sizeof value
sizeof( type )
++ 左值
-- 左值
~ 值
\! ReplTest1
ReplTest1
+ 值
& 左值
值
類型轉換 (始終執行)
表達式的大小
數據類型的大小
增量 (之前評估版)
遞減 (在之前評估版)
位求補
不 (布爾值)
一元負
一元加
數據類型的地址
取消引用
結構 。 指針
Pointer -> \* Pointer
指向成員的結構的指針
指向引用結構成員的指針
Value Value
Value / Value
Value % Value
乘法
部門
取模
Value + Value
Value - Value
添加
減法
Value << Value
Value >> Value
按位左移
按位右移
Value < Value
Value <= Value
Value > Value
Value >= Value
早於 (比較)
小於或等於 (比較)
大於 (比較)
大於或等於 (比較)
Value == Value
Value != Value
等於 (比較)
不等於 (比較)
Value & Value
位與
Value ^ Value
按位 XOR (異或)
Value | Value
按位 OR 運算符
Value && Value
邏輯與
Value || Value
邏輯或
LValue =Value
LValue = Value
LValue /= Value
LValue %=Value
LValue +=Value
LValue -= Value
LValue <<= Value
LValue >>= Value
LValue &= Value
LValue |= Value
LValue ^= Value
分配
乘並賦值
相除並賦值
取模和分配
添加和分配
相減並賦值
左移位,並將分配
右移位和分配
和分配
或和分配
XOR 並賦值
值 ? 值 :值
條件評估
值 , 值
評估所有值,然后丟棄最右側的值之外的所有
- C++語言中的寄存器和偽寄存器
可以在C++表達式中使用寄存器和偽寄存器。必須在寄存器或偽寄存器之前添加at符號(@)。表達式計算器自動執行正確的強制轉換。實際寄存器和整數值偽寄存器被轉換為ulong64。所有地址都轉換為puchar,$thread轉換為ethread*,$proc轉換為eprocess*,$teb轉換為teb*,$peb轉換為peb*。不能通過賦值或副作用運算符更改寄存器或偽寄存器。必須使用r(寄存器)命令更改這些值。
- C++表達式中的宏
可以在C++表達式中使用宏。必須在宏之前添加數字符號(#)。可以使用以下宏。這些宏與具有相同名稱的Microsoft Windows宏具有相同的定義。(Windows宏在winnt.h中定義。)
宏 返回值 #CONTAINING_RECORD (地址,類型,字段)
返回給定類型的結構和結構中的字段的地址結構的實例的基址。
#FIELD_OFFSET (類型,字段)
返回命名的字段的字節偏移量中的已知的結構類型。
#RTL_CONTAINS_FIELD (Struct,大小,字段)
指示給定的字節大小是否包括所需的字段。
#RTL_FIELD_SIZE(Type, Field)
而無需字段的類型返回已知類型的結構中的字段的大小。
#RTL_NUMBER_OF(Array)
以靜態方式調整大小的數組中返回元素的數。
#RTL_SIZEOF_THROUGH_FIELD(Type, Field)
通過和包括在指定的字段會返回已知類型的結構的大小。