別名 是會自動取代為其他字串的字串。 您可以在調試程式命令中使用它們,並避免重新調整某些常見片語。
別名是由別名名稱和對等的別名所組成。 當您使用別名名稱做為調試程式命令的一部分時,名稱會自動由別名對等專案取代。 在命令被剖析或執行前,此取代會立即發生。
除錯程式支援三種別名:
您可以設定並命名 使用者命名別名。
您可以設定 固定名稱別名,但名稱 為 $u 0、 $u 1、...、 $u 9。
調試程式會設定和命名 自動別名。
定義 User-Named 別名
當您定義使用者命名的別名時,可以選擇別名名稱和別名對應:
別名名稱可以是不包含空格符的任何字串。
別名等同項可以是任何字串。 如果您在鍵盤上輸入,別名對等專案不能包含前置空格或歸位字元。 或者,您可以將它設定為記憶體中的字串、數值表達式的值、檔案的內容、環境變數的值,或一或多個調試程式命令的輸出。
別名名稱和對等別名都會區分大小寫。
若要定義或重新定義使用者命名的別名,請使用 as (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 符號模組。 此別名可以等於 ntdll 或 nt。 |
$ntwsym |
在利用 WOW64 進行 32 位偵錯時,最適合用於 NT 符號的模組。 此別名可以是 ntdll32 或其他 32 位版本的 Ntdll.dll。 |
$ntsym |
對應目前電腦模式中 NT 符號的最合適模組。 當您以原生模式進行偵錯時,此別名與 $ntnsym相同。 當您以非原生模式進行偵錯時,調試程式會嘗試尋找符合此模式的模組。 (例如,在使用 WOW64 的 32 位偵錯期間,此別名與 $ntwsym相同。 |
$CurrentDumpFile |
調試程式載入的最後一個傾印檔案名稱。 |
$CurrentDumpPath |
除錯器載入的最後一個轉存檔案的目錄路徑。 |
$CurrentDumpArchiveFile |
調試程式載入的最後一個傾印檔案(CAB 檔案)的名稱。 |
$CurrentDumpArchivePath |
調試程式載入的最後一個轉儲封存檔案(CAB 檔案)的目錄路徑。 |
自動別名類似於 自動虛擬緩存器,不同之處在於您可以搭配別名相關令牌使用自動別名(例如 ${ }),而您無法搭配這些令牌使用虛擬緩存器。
在調試程式命令視窗中使用別名
定義別名之後,您可以在任何命令專案中使用它。 別名名稱會自動取代為對等的別名。 因此,您可以將別名用於程式中的表達式或宏。
即使別名以引號括住,仍會正確展開。 因為別名對等專案可以包含任意數目的引號或分號,因此別名對等專案可以代表多個命令。
只有在名稱與其他字元隔開空格符時,才會辨識使用者命名別名。 別名名稱的第一個字元必須位於行首,或在空格、分號或引號之後。 其別名名稱的最後一個字元必須結束行,或後面接著空格、分號或引號。
注意 您在 [調試程式命令] 視窗中 輸入的任何文字開頭為 “as”、“aS”、“ad” 或 “al” 並不會收到別名取代。 這項限制可防止別名命令失效。 不過,這項限制也表示位於 ad 或 al 之後的行上命令不會取代其別名。 如果您想要在開頭為其中一個字串的行中取代別名,請在別名前面新增分號。
不過,即使它位於其他文字旁邊,您也可以使用 ${ } 令牌來展開使用者命名的別名。 您也可以將此令牌與特定參數搭配使用,以防止擴充別名,或顯示特定別名相關值。 如需這些情況的詳細資訊,請參閱 ${ } (別名解釋器) 。
固定名稱別名可以正確地從行內的任何位置展開,無論它在行內的文字中如何內嵌。
您無法使用只能在 WinDbg 中使用的命令(.open、.write_cmd_hist(寫入命令歷程記錄)、.lsrcpath 和 .lsrcfix)以及一些額外的命令(.hh、.cls、.wtitle、.remote、kernel-mode .restart 和 user-mode .restart)使用別名。
在腳本檔案中使用別名
當您在腳本檔案中使用別名時,必須特別小心,以確保別名在正確的時間擴充。 請考慮下列文稿:
.foreach (value {dd 610000 L4})
{
as /x ${/v:myAlias} value + 1
.echo value myAlias
}
ad myAlias
第一次通過迴圈時 ,as,aS (設定別名) 命令會將值指派給 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 的任何值。 第三個命令會採用 ?@$t0 命令的第三個標記,並嘗試將該標記的值賦值給 myAlias。 第四個命令會列出所有別名及其值。 我們預期 myAlias 的值會是 5,但實際上是“Token”。
Alias Value
------- -------
myAlias Token
問題是 as 命令位於 .foreach 循環主體中的行首。 當行以 as 命令開頭時,該行中的別名和標記不會展開。 如果我們在 as 命令前面放置分號或空格符,則會展開任何已經有值的別名或標記。 在此範例中,變數 myAlias 不會擴展,因為它還沒有值。 因為值等於 5,所以 Token 被展開。 以下是相同的命令序列,但在as命令之前添加了分號。
r $t0 = 5
ad myAlias
.foreach /pS 2 /ps 2 (Token {?@$t0}) {;as myAlias Token}
al
現在我們會取得預期的輸出。
Alias Value
------- -------
myAlias 5
遞歸別名
您可以在任何別名的定義中使用固定名稱別名。 您也可以在固定名稱別名的定義中使用使用者自定義的別名。 不過,若要在另一個使用者命名別名的定義中使用使用者命名的別名,您必須在 as 或 aS 命令之前新增分號,否則別名取代不會發生在該行上。
當您使用此類型的遞歸定義時,每次使用別名時都會立即轉譯。 例如,下列範例會顯示 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
您可以使用別名作為重複使用常用命令的巨集。 下列範例會遞增 eax 和 ebx 暫存器兩次。
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 檔案中預先定義固定名稱別名。 若要預先定義固定名稱別名,請在 [NTSD] 條目中新增您想要的 $u 欄位,如下列範例所示。
[NTSD]
$u1:_ntdll!_RtlRaiseException
$u2:"dd esp 14;g"
$u9:$u1 + 42
您無法在 Tools.ini 檔案中設定使用者命名別名。
Fixed-Name 別名與 User-Named 別名
用戶名稱別名比固定名稱別名更容易使用。 其定義語法更簡單,您可以使用 al (List Aliases) 命令來列出它們。
當固定命名別名在其他文字旁出現時,將會被取代。 若要在使用者命名別名位於其他文字旁邊時加以取代,請將它括在 ${ } (別名解釋器) 令牌中。
固定別名的取代會在使用者命名的別名取代之前發生。