Windbg中查看計算機名

轉載註明>> 作者:張佩】【原文:www.yiiyee.cn/blog/


引子


使用Windbg調試目標對象的時候,用戶發現到它的一個缺陷,就是不能自動識別目標設備的機器名。實際上Windbg總是標出了Machine Name的關鍵字,但卻從來都沒有顯示。可以認爲Windbg在這個地方有點小缺陷。見下面的例子:

0:000> vertarget
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 6.1.7601.18015 (win7sp1_gdr.121129-1432)
Machine Name: //空空如也
Debug session time: Thu Aug 22 10:11:04.000 2013 (UTC + 8:00)
System Uptime: 14 days 17:26:44.613
Process Uptime: 14 days 17:14:25.000
  Kernel time: 0 days 0:09:02.000
  User time: 0 days 0:42:36.000
在調試一些很困難問題的時候,比如目標系統boot失敗、桌面不能正常顯示、dump分析,這些情況下,我們沒法通過登錄到目標機器上去查看機器名,只能藉助Windbg來實現。雖然Windbg沒有自動顯示功能,但仍然可以通過兩種方法來實現手動實現。我們分兩種情況來講:用戶調試環境(或用戶dump),內核調試環境(或內核dump)。


用戶調試環境


在用戶調試的時候,可以通過進程的當前查看環境COMPUTERNAME。查看環境變量有下面兩種方法:

1. 執行!PEB命令,可列舉出當前進程使用的全部環境變量

2. 執行!envvar xxx 命令,查看指定的環境變量,如下所示:

0:000> !envvar computername
        computername = MOZHANG

這臺目標設備的機器名是Mozhang。


內核調試環境


用戶調試環境中,這是唯一的辦法。在內核調試環境中,我們也可以通過查看指定進程的環境變量,來實現。不過步驟略複雜一些,因爲如果當前進程是System進程、會話管理器進程、子系統進程等OS的進程,它們這些進程裏面的PEB中,是沒有COMPUTERNAME環境變量的(System進程則沒有PEB),直接執行!peb或!envvar就會無效,這種情況下,需要把當前進程切換到其它進程去。

0: kd> !process 	// 當前進程爲System進程
PROCESS fffffa8007288040
    SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00188000  ObjectTable: fffff8a000003000  HandleCount: 364.
    Image: System
    VadRoot fffffa800911a840 Vads 9 Clone 0 Private 16. Modified 6371. Locked 64.
    DeviceMap fffff8a00000c500
0: kd> !envvar computername
0: kd> !peb
PEB NULL...  // PEB爲空也

如果遇到這種情況,必須避開這些進程,切換到其它進程去,步驟如下:

6: kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS fffffa8007288040 // System進程不用,PEB爲空
    SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00188000  ObjectTable: fffff8a000003000  HandleCount: 385.
    Image: System

PROCESS fffffa800981a540 // 會話管理器進程不用
    SessionId: none  Cid: 013c    Peb: 7f607a64000  ParentCid: 0004
    DirBase: 03dd0000  ObjectTable: fffff8a00029e600  HandleCount:  36.
    Image: smss.exe

PROCESS fffffa8009cc5800 // 子系統進程不用
    SessionId: 0  Cid: 01a0    Peb: 7f65140f000  ParentCid: 0194
    DirBase: 108ad0000  ObjectTable: fffff8a0009ced80  HandleCount:  96.
    Image: csrss.exe

PROCESS fffffa80073c5080 // 此進程可用
    SessionId: 0  Cid: 01f0    Peb: 7f633826000  ParentCid: 0194
    DirBase: 10a276000  ObjectTable: fffff8a00134ed80  HandleCount:  84.
    Image: wininit.exe


6: kd> .process /i fffffa80073c5080
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
6: kd> g
Break instruction exception - code 80000003 (first chance)
nt!DbgBreakPointWithStatus:
fffff800`f227b930 cc              int     3
4: kd> !envvar computername
        computername = mozhang
上面是分了三個步驟:

1. 列舉進程列表,用!process 0 0 命令。在列出的所有進程中,任意選擇一個,只要不是那幾個系統的進程即可。

2. 切換到指定進程,通過.proces /i xxx命令,xxx爲內核進程對象的地址。進程切換是發送命令給目標設備的系統進行處理的,所以要執行以下go命令,以使目標設備有時間去完成進程切換的工作。

3. 執行!Peb!envvar xxx命令。

上面介紹的是通過環境便來來獲取目標機器名。在內核調試的時候,還有另一種更方便的辦法,這種辦法也是MSDN文檔裏有說明的。原來在系統的srv.sys模塊中,通過一個全局變量srv!srvcomputername保存了本機的機器名。這樣的話,我們只要查看這個變量就可以了。此變量的類型爲UNICODE_STRING。我們通過下面的方法來實現:

6: kd> x srv!srvcomputername
fffff880`07107048 srv!SrvComputerName = <no type information>

6: kd> dt nt!_unicode_string  fffff880`07107048
 "mozhang"
   +0x000 Length           : 0xE
   +0x002 MaximumLength    : 0xE
   +0x008 Buffer           : 0xfffff8a0`02eaac90  "mozhang"
有人擔心,如果我沒有srv.sys的符號文件怎麼辦。這一點是沒問題的,srv.sys是微軟的系統模塊,我們可以通過微軟的公共符號服務器獲取它的public符號文件。


參考:http://msdn.microsoft.com/en-us/library/windows/hardware/ff543991(v=vs.85).aspx


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章