Windbg命令学习8(.frame和dt)
这里使用一个debug程序:
1.frame
.frame命令指定使用哪个局部上下文(作用域)来解析局部变量,或者显示当前的局部上下文
帧序号(frame number)是堆栈帧在堆栈回溯中的位置。可以使用k (Display Stack Backtrace)命令或者Calls 窗口查看堆栈回溯。第一行 (当前帧) 的帧序号是0。后面的行分别是1、2、3等等。
0:000> kn # ChildEBP RetAddr 00 0012f78c 7c92daea ntdll!KiFastSystemCallRet 01 0012f790 7c932298 ntdll!ZwRequestWaitReplyPort+0xc 02 0012f7b0 7c872a51 ntdll!CsrClientCallServer+0x8c 03 0012f8ac 7c872b98 kernel32!ReadConsoleInternal+0x1be 04 0012f934 7c8018b7 kernel32!ReadConsoleA+0x3b 05 0012f98c 102c207c kernel32!ReadFile+0x64 06 0012fa20 102c19c9 MSVCR90D!_read_nolock+0x62c [f:\dd\vctools\crt_bld\self_x86\crt\src\read.c @ 233] 07 0012fa70 10253e43 MSVCR90D!_read+0x219 [f:\dd\vctools\crt_bld\self_x86\crt\src\read.c @ 93] 08 0012fa98 102523e8 MSVCR90D!_filbuf+0x113 [f:\dd\vctools\crt_bld\self_x86\crt\src\_filbuf.c @ 136] 09 0012faf0 10252440 MSVCR90D!getc+0x208 [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetc.c @ 76] 0a 0012fafc 1025245a MSVCR90D!_fgetchar+0x10 [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetchar.c @ 37] 0b 0012fb04 0041160b MSVCR90D!getchar+0xa [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetchar.c @ 47] 0c 0012fbe4 004114b2 test2!MyCls::hold+0x2b [d:\project1\test2\test2\test2.cpp @ 28] 0d 0012fcec 0041167a test2!foo1+0xa2 [d:\project1\test2\test2\test2.cpp @ 39] 0e 0012fdc0 004116ea test2!foo2+0x3a [d:\project1\test2\test2\test2.cpp @ 45] 0f 0012fe94 00411743 test2!foo3+0x3a [d:\project1\test2\test2\test2.cpp @ 51] 10 0012ff68 00411ce8 test2!main+0x23 [d:\project1\test2\test2\test2.cpp @ 56] 11 0012ffb8 00411b2f test2!__tmainCRTStartup+0x1a8 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 586] 12 0012ffc0 7c817077 test2!mainCRTStartup+0xf [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 403] 13 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> .frame d 0d 0012fcec 0041167a test2!foo1+0xa2 [d:\project1\test2\test2\test2.cpp @ 39] 0:000> x 0012fce4 pcls = 0x00392a28 0012fcd8 rawptr = 0x00392a28
.frame 帧号,之后跟x,可以显示当前这个函数里面的局部变量
对应d帧的代码:
void foo1() { MyCls *pcls=new MyCls(); void *rawptr=pcls; pcls->set("abcd"); pcls->output(); pcls->hold(); };
x显示的是pcls和rawptr
2dt
dt命令显示局部变量、全局变量或数据类型的信息。它也可以仅显示数据类型。即结构和联合(union)的信息
在查看PE文件时,要加载ntdll,再用dt ntdll!_image_dos_headers
而要看section(区块)结构时,要加载ole32.dll,如果程序原来没有包括这个dll,那么这个dll是没否再加进来的
dt后可以带通配符,如下面命令会列出ntdll的所有类型
0:000> dt ntdll!* ntdll!LIST_ENTRY64 ntdll!LIST_ENTRY32
如果只想显示某个字段,可以用-ny 加上搜索选项,如:
0:000> dt -v ntdll!_PEB -ny BeingDebugged @$peb struct _PEB, 91 elements, 0x248 bytes +0x002 BeingDebugged : 0x1 ''
-v是详细输出。这会输出结构的总大小和字段数量这样的附加信息
也可以用-y 来连接通配符,如:
0:000> dt -v ntdll!_PEB -y B* @$peb struct _PEB, 91 elements, 0x248 bytes +0x002 BeingDebugged : 0x1 '' +0x003 BitField : 0x8 ''
0:000> dt pcls Local var @ 0x12fce4 Type MyCls* 0x00392a28 +0x000 str : 0x00415800 "abcd" +0x004 inobj : innner 0:000> dt rawptr Local var @ 0x12fcd8 Type void* 0x00392a28 0:000> dt -b-r pcls Local var @ 0x12fce4 Type MyCls* 0x00392a28 +0x000 str : 0x00415800 "abcd" +0x004 inobj : innner +0x000 arr : "abcd" [00] 97 'a' [01] 98 'b' [02] 99 'c' [03] 100 'd' [04] 0 '' [05] 0 '' [06] 0 '' [07] 0 '' [08] 0 '' [09] 0 ''