转载注明>> 【作者:张佩】【原文:http://www.yiiyee.cn/Blog】
引子
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)。
用户调试环境
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 // 系统进程不用,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 命令。在列出的所有进程中,任意选择一个,只要不是那几个OS的进程即可。
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符号文件。
参考:msdn
8,162 total views, 2 views today
有一个问题请教老师,请问
6: kd> x srv!srvcomputername
这种命令前面的数字,这里是6是表示什么意思?
6是处理器ID。
對於 kernel summary dump 似乎不管用?!