windbg学习----调试器命令示例
1.s搜索命令
1.1搜索dword
0:000> dd esp 0029e898 00050001 7ffdf6cc cccccccc cccccccc 0029e8a8 636e6554 20746e65 68636554 6f6c6f6e 0029e8b8 53287967 7a6e6568 296e6568 6d6f4320 0029e8c8 796e6170 6d694c20 64657469 00000000 0029e8d8 00000000 00000000 00000000 00000000 0029e8e8 00000000 00000000 00000000 00000000 0029e8f8 00000000 00000000 00000000 00000000 0029e908 00000000 00000000 00000000 00000000 0:000> s -[1]d 0029e898 L200 20746e65 0x0029e8ac
0:000> dc 0029eeec 0029eeec 505c3a43 72676f72 61446d61 545c6174 C:\ProgramData\T 0029eefc 65636e65 545c746e 6c755653 545c7746 encent\TSVulFw\T 0029ef0c 6c755653 442e5746 00005441 f13f0003 SVulFW.DAT....?. 0029ef1c f1d8a8e6 3f0003e6 01293f5b 03000300 .......?[?)..... 0029ef2c 3f293f05 3f3f3f29 3f00033f 3f293f5b .?)?)????..?[?)? 0029ef3c 0001033f 00000000 00000000 00000000 ?............... 0029ef4c 00000000 00000000 00000000 00000000 ................ 0029ef5c 00000000 00000000 00000000 00000000 ................ 0:000> s -[1]a 0029eeec L1000 "TSVulFw" 0x0029ef03 0:000> da 0x0029ef03 0029ef03 "TSVulFw\TSVulFW.DAT"注意是大小写字符敏感的
下面的命令显示所有位于0x77000000 到0x7F000000地址范围内的模块的详细信息
0:000> .foreach (place {lm1m}) {.if(( place >0x77000000)&( place <=0x7f000000)){.echo ${place}}} sechost USP10 MSCTF IMM32 SHLWAPI imagehlp GDI32 OLEAUT32 ole32 ntdll USER32 0:000> .foreach (place {lm1m}) {.if(( place >0x77000000)&( place <=0x7f000000)){dd ${place} L1}} 770b0000 00905a4d 770d0000 00905a4d 77170000 00905a4d 77290000 00905a4d 77340000 00905a4d 773a0000 00905a4d 773d0000 00905a4d 77420000 00905a4d 77790000 00905a4d 77c40000 00905a4d 77d90000 00905a4d
- r (Registers)和 ? 标志一起使用。该标志为伪寄存器$t0 和$t1指派有类型的值。循环体中,$t1具有ntdll!_LDR_DATA_TABLE_ENTRY*类型,所以程序可以直接引用它的成员。
0:000> dt _PEB -y Ldr @$peb VerifyTxSignDemo!_PEB +0x00c Ldr : 0x77d17880 _PEB_LDR_DATA 0:000> dt _PEB_LDR_DATA -v @$peb VerifyTxSignDemo!_PEB_LDR_DATA struct _PEB_LDR_DATA, 7 elements, 0x28 bytes +0x000 Length : 0x8010000 +0x004 Initialized : 0xff '' +0x008 SsHandle : 0x01000000 +0x00c InLoadOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes [ 0x77d17880 - 0x391c30 ] +0x014 InMemoryOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes [ 0x0 - 0x390000 ] +0x01c InInitializationOrderModuleList : struct _LIST_ENTRY, 2 elements, 0x8 bytes [ 0x77d17380 - 0x0 ] +0x024 EntryInProgress : (null)
0:000> r? $t1=&@$peb->Ldr->InLoadOrderModuleList;r $t1 $t1=77d1788c首先贴下脚本:
.echo "遍历链表" r? $t0=&@$peb->Ldr->InLoadOrderModuleList r $t0 .for (r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0; (@$t1 != 0) & (@$t1 != @$t0); r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)@$t1->InLoadOrderLinks.Flink) { as /x ${/v:$Base} @@c++(@$t1->DllBase) as /msu ${/v:$Mod} @@c++(&@$t1->BaseDllName) .block { .echo ${$Mod} at ${$Base} } ad ${/v:$Base} ad ${/v:$Mod} }运行结果如下:
遍历链表 $t0=77d1788c VerifyTxSignDemo.exe at 0x1000000 ntdll.dll at 0x77c40000 kernel32.dll at 0x76230000 KERNELBASE.dll at 0x76050000 USER32.dll at 0x77d90000 GDI32.dll at 0x773d0000 LPK.dll at 0x75db0000 USP10.dll at 0x770d0000 msvcrt.dll at 0x77000000 MSIMG32.dll at 0x721b0000 COMDLG32.dll at 0x761b0000 SHLWAPI.dll at 0x77340000 COMCTL32.dll at 0x750c0000 ADVAPI32.dll at 0x76310000 sechost.dll at 0x770b0000 RPCRT4.dll at 0x760a0000 SHELL32.dll at 0x763b0000 WINSPOOL.DRV at 0x75310000 ole32.dll at 0x77790000 OLEAUT32.dll at 0x77420000 oledlg.dll at 0x6c500000 gdiplus.dll at 0x740b0000 OLEACC.dll at 0x72d80000 IMM32.dll at 0x77290000 MSCTF.dll at 0x77170000 WINMM.dll at 0x73e30000 uxtheme.dll at 0x74240000 dwmapi.dll at 0x73ea0000 CRYPTBASE.dll at 0x75d10000 Crypt32.dll at 0x75ed0000 MSASN1.dll at 0x75e10000 WINTRUST.DLL at 0x75ff0000 imagehlp.dll at 0x773a0000 CRYPTSP.dll at 0x756f0000 rsaenh.dll at 0x755c0000 ncrypt.dll at 0x75950000 bcrypt.dll at 0x75930000 bcryptprimitives.dll at 0x75520000
分析:
0:000> r? $t0=&@$peb->Ldr->InLoadOrderModuleList 0:000> r $t0 $t0=77d1788c 0:000> dt _PEB -y ldr @$peb VerifyTxSignDemo!_PEB +0x00c Ldr : 0x77d17880 _PEB_LDR_DATA 0:000> dt 0x77d17880 _PEB_LDR_DATA VerifyTxSignDemo!_PEB_LDR_DATA +0x000 Length : 0x30 +0x004 Initialized : 0x1 '' +0x008 SsHandle : (null) +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x3928a8 - 0x3cfd90 ] +0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x3928b0 - 0x3cfd98 ] +0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x392948 - 0x3cfda0 ] +0x024 EntryInProgress : (null)
可以看到,$t0此时指向了
InLoadOrderModuleList指针,指向了_LDR_DATA_TABLE_ENTRY的一个链表,可以看下这个结构
0:000> dt -r2 _LDR_DATA_TABLE_ENTRY ntdll!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY +0x004 Blink : Ptr32 _LIST_ENTRY +0x004 Blink : Ptr32 _LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY +0x004 Blink : Ptr32 _LIST_ENTRY
这个结构是个循环链表,其中它的InLoadOrderLinks.Flink又指向下一个_LDR_DATA_TABLE_ENTRY,
0:000> r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0; 0:000> r $t1 $t1=003928a8 0:000> dd $t0 L1 77d1788c 003928a8
所以$t0所指向的内容是一个_LDR_DATA_TABLE_ENTRY指针,所以$t0是一个指向LDR_DATA_TABLE_ENTRY指针的指针(双指针),所以用(ntdll!_LDR_DATA_TABLE_ENTRY**)来强制转换!
后面要注意的是,由于别名之前被定义过了,
- 。${/v: } 标记会逐字解释别名,避免如果脚本运行之前定义过同名的别名使得它被替换的情况,所以不要用ad ${$Mod},因为这样的话,别名在前面定义过了,就直接被替换了!
- .block 标记用于增加一个额外的别名替换步骤。别名在整个脚本被加载时会进行一次替换,在进入每个语句块的时候还会进行一次替换。如果没有.block 标记和它的大括号,.echo命令无法接收到上一行中赋给$Mod和$Base 别名的值
无聊,再给个while遍历的:
.echo "开始遍历模块的脚本" r? @$t0=&@$peb->Ldr->InLoadOrderModuleList r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0; .while(@$t1!=@$t0) { as /x ${/v:$Base} @@c++(@$t1->DllBase) as /msu ${/v:$FullDllName} @@c++(&@$t1->FullDllName) .block { .echo ${$FullDllName} at ${$Base} } ad ${/v:$Base} ad ${/v:$FullDllName} r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)@$t1->InLoadOrderLinks.Flink }
结果如下:
开始遍历模块的脚本 E:\工作临时区\VerifyTxSignDemo\Debug\VerifyTxSignDemo.exe at 0x1190000 C:\Windows\SYSTEM32\ntdll.dll at 0x77520000 C:\Windows\system32\kernel32.dll at 0x75b20000 C:\Windows\system32\KERNELBASE.dll at 0x75630000 C:\Windows\system32\USER32.dll at 0x75f50000 C:\Windows\system32\GDI32.dll at 0x75f00000 C:\Windows\system32\LPK.dll at 0x77740000 C:\Windows\system32\USP10.dll at 0x75e60000 C:\Windows\system32\msvcrt.dll at 0x75c00000 C:\Windows\system32\MSIMG32.dll at 0x736d0000 C:\Windows\system32\COMDLG32.dll at 0x760d0000 C:\Windows\system32\SHLWAPI.dll at 0x75960000 C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.7601.17514_none_ec83dffa859149af\COMCTL32.dll at 0x712e0000 C:\Windows\system32\ADVAPI32.dll at 0x76290000 C:\Windows\SYSTEM32\sechost.dll at 0x77690000 C:\Windows\system32\RPCRT4.dll at 0x772b0000 C:\Windows\system32\SHELL32.dll at 0x76540000 C:\Windows\system32\WINSPOOL.DRV at 0x6ed10000 C:\Windows\system32\ole32.dll at 0x76330000 C:\Windows\system32\OLEAUT32.dll at 0x759c0000 C:\Windows\system32\oledlg.dll at 0x6eb50000 C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17825_none_72d273598668a06b\gdiplus.dll at 0x73ee0000 C:\Windows\system32\OLEACC.dll at 0x73600000 C:\Windows\system32\IMM32.dll at 0x77660000 C:\Windows\system32\MSCTF.dll at 0x75a50000 C:\Windows\system32\WINMM.dll at 0x756c0000 C:\Windows\system32\UxTheme.dll at 0x74070000 C:\Windows\system32\dwmapi.dll at 0x755e0000 C:\Windows\system32\CRYPTBASE.dll at 0x752e0000 C:\Windows\system32\Crypt32.dll at 0x75470000 C:\Windows\system32\MSASN1.dll at 0x753d0000 C:\Windows\system32\WINTRUST.DLL at 0x75690000 C:\Windows\system32\imagehlp.dll at 0x760a0000 C:\Windows\system32\CRYPTSP.dll at 0x74e10000 C:\Windows\system32\rsaenh.dll at 0x74bb0000 C:\Windows\system32\ncrypt.dll at 0x74f40000 C:\Windows\system32\bcrypt.dll at 0x74f20000 C:\Windows\system32\bcryptprimitives.dll at 0x74af0000 C:\Program Files\360\360safe\safemon\safemon.dll at 0x6b0b0000 C:\Windows\system32\PSAPI.DLL at 0x76530000 C:\Windows\system32\WININET.dll at 0x75840000 C:\Windows\system32\Normaliz.dll at 0x77680000 C:\Windows\system32\iertutil.dll at 0x77360000 C:\Windows\system32\urlmon.dll at 0x77190000 C:\Windows\system32\VERSION.dll at 0x74860000 C:\Windows\system32\WS2_32.dll at 0x764f0000 C:\Windows\system32\NSI.dll at 0x75e50000 C:\Windows\system32\NETAPI32.dll at 0x73b50000 C:\Windows\system32\netutils.dll at 0x73b40000 C:\Windows\system32\srvcli.dll at 0x750d0000 C:\Windows\system32\wkscli.dll at 0x73b30000 C:\Windows\system32\apphelp.dll at 0x75290000 C:\Windows\system32\SOGOUPY.IME at 0x10000000 C:\Program Files\SogouInput\Components\AddressSearch\1.0.0.1169\AddressSearch.dll at 0x70f30000 C:\Windows\system32\ntmarta.dll at 0x739d0000 C:\Windows\system32\WLDAP32.dll at 0x76240000 C:\Program Files\SogouInput\Components\PicFace\1.0.0.730\PicFace.dll at 0x70e80000
解释下为什么用&
因为我们需要的是对象的指针,而不是对象:
0:000> dt @$peb _PEB -y Ldr VerifyTxSignDemo!_PEB +0x00c Ldr : 0x77647880 _PEB_LDR_DATA我们可以看到0x77647880是_PEB_LDR_DATA的对象,但我们需要的是它的指针:
0:000> r? @$t0=&@$peb->Ldr; r @$t0; $t0=7ffdb00c 0:000> r? @$t0=@$peb->Ldr; r @$t0; $t0=77647880 0:000> dd 7ffdb00c L1 7ffdb00c 77647880
0:000> dd 7764788c L1 7764788c 003329a8 0:000> dd 003329a8 L1 003329a8 00332a38 0:000> dd 00332a38 L1 00332a38 00332d60 0:000> dd 00332d60 L1 00332d60 00332e78 0:000> dd 00332e78 L1 00332e78 003336e0 0:000> dd 003336e0 L1 003336e0 003337f0 0:000> dd 003337f0 L1 003337f0 00333970 0:000> dd 00333970 L1 00333970 00333b20 0:000> dd 00333b20 L1 00333b20 00333c08 0:000> dd 00333c08 L1 00333c08 00333ea0 0:000> dd 00333ea0 L1 00333ea0 00334008 0:000> dd 00334008 L1 00334008 003341e8 0:000> dd 003341e8 L1 003341e8 00334820 0:000> dd 00334820 L1 00334820 00334560 0:000> dd 00334560 L1 00334560 00334ae8 0:000> dd 00334ae8 L1 00334ae8 00334990 0:000> dd 00334ae8 L1 00334ae8 00334990 0:000> dd 00334990 L1 00334990 00334ce8 0:000> dd 00334ce8 L1 00334ce8 00334f08 0:000> dd 00334f08 L1 00334f08 00335258 0:000> dd 00335258 L1 00335258 00335438 0:000> dd 00335438 L1 00335438 00335608 0:000> dd 00335608 L1 00335608 00335c80 0:000> dd 00335c80 L1 00335c80 00335f48 0:000> dd 00335f48 L1 00335f48 00335e08 0:000> dd 00335e08 L1 00335e08 00336058 0:000> dd 00336058 L1 00336058 003362a8 0:000> dd 003362a8 L1 003362a8 7764788c 0:000> r? @$t0=&(@$peb->Ldr)->InLoadOrderModuleList; r @$t0; $t0=7764788c上面就是手动循环
也可以直接用简单的脚本来实现:
r @$t0=0x7764788c r @$t1=dwo(@$t0) .while(@$t1!=@$t0) { dd @$t1 L1 r @$t1=dwo(@$t1) }