Windbg及Dump⽂件分析⽅法
介绍
WinDbg全称Debugging Tools for Windows,是windows平台下的调试⼯具。
获取Windbg的三种途径:
(1)在Visual Studio安装时安装Windows Driver Kit(WDK)。WDK中包含WinDbg。
(2)安装Windows Software Development Kit (SDK)。SDK中包含WinDbg。
(3)如果只下载单独的WinDbg,先下载SDK,在安装过程中选择“Debugging Tools for Windows”,同时勾掉其他选择框。
⽤户模式的WinDbg
WinDbg有两种类型:内核模式调试器和⽤户模式调试器。内核模式⽤于调试Windows内核以及驱动程序。⽤户模式⽤于调试⽤户程序,本⽂主要介绍⽤户模式的调试器,内核模式调试器的使⽤⽅法可在微软官⽹查。
notepad++⽆代码情况下调试
(1)打开
(2)在File菜单中选择Open Executable, 在 Open Executable 对话框中选择(C:\Windows\System32),点击Open。
(3)在底部窗⼝中,输⼊命令:
.sympath srv*
窗⼝将输出以下内容:
Symbol search path is: srv*
符号搜索路径指⽰WinDbg查符号⽂件(PDB)的地⽅,通过符号⽂件调试器可以获取代码模块中的函数名称、变量名等信息。输⼊如下命令将通知WinDbg进⾏初始化搜索和加载符号⽂件动作:
.reload
(4)输⼊以下命令可查看模块的符号
x notepad!*
如果看不到任何输出,在此输⼊.reload命令。
输⼊以下命令可查看模块中包含main名称的符号
x notepad!*main*
窗⼝将输出以下内容:
00a31409 notepad!WinMain (<no parameter info>)
00a331c9 notepad!WinMainCRTStartup (<no parameter info>)
(5)输⼊以下命令可在notepad!WinMain上打断点:
bu notepad!WinMain
输⼊以下命令验证断点是否已经设置:
bl
窗⼝将输出以下内容:
0 e Disable Clear 00a31409 0001 (0001) 0:**** notepad!WinMain
(6)输⼊以下命令运⾏Notepad:
g
Nopad将会运⾏到WinMain函数,并中断。输⼊以下命令可查看Notepad进程已加载模块列表:
lm
调试器窗⼝将输出以下内容:
start end module name
00a30000 00a60000 notepad (pdb symbols) C:\Program Files (x86)\Windows
Kits\10\Debuggers\x86\sym\notepad.pdb\BAF2EA337470437B9DF28CCDFD3EDEB22\notepad.pdb 6dfa0000 6dff1000 WINSPOOL (deferred)
6e1b0000 6e34e000 COMCTL32 (deferred)
73730000 73739000 VERSION (deferred)
74f10000 74f1c000 CRYPTBASE (deferred)
74f20000 74f80000 SspiCli (deferred)
74f80000 74ffb000 COMDLG32 (deferred)
75100000 75191000 OLEAUT32 (deferred)
75300000 75f4b000 SHELL32 (deferred)
76130000 76220000 RPCRT4 (deferred)
76220000 762c1000 ADVAPI32 (deferred)
76510000 76610000 USER32 (deferred)
76640000 76687000 KERNELBASE (deferred)
76730000 76787000 SHLWAPI (deferred)
76930000 76949000 sechost (deferred)
76d30000 76dfc000 MSCTF (deferred)
76e00000 76e90000 GDI32 (deferred)
76f30000 76f90000 IMM32 (deferred)
770c0000 7721c000 ole32 (deferred)
77250000 772fc000 msvcrt (deferred)
77350000 773ed000 USP10 (deferred)
773f0000 773fa000 LPK (deferred)
77400000 77510000 kernel32 (deferred)
77a50000 77bd0000 ntdll (pdb symbols) C:\Program Files (x86)\Windows
Kits\10\Debuggers\x86\sym\wntdll.pdb\EA251A0A79C44D5AAF977F6875A518662\wntdll.pdb
输⼊以下命令可查看调⽤堆栈信息:
k
调试器窗⼝将输出以下内容:
# ChildEBP RetAddr
00 0020fbac 00a3190e notepad!WinMain
01 0020fc3c 7741336a notepad!_initterm_e+0x1a1
02 0020fc48 77a89902 kernel32!BaseThreadInitThunk+0xe
03 0020fc88 77a898d5 ntdll!__RtlUserThreadStart+0x70
04 0020fca0 00000000 ntdll!_RtlUserThreadStart+0x1b
(7)输⼊以下命令再次运⾏Notepad:
g
(8)如果想中断Notepad的运⾏,可在Debug菜单中选择Break。
(9)输⼊以下命令可在ZwWriteFile处设置并且验证断点:
bu ntdll!ZwWriteFile
bl
(10)输⼊g再次运⾏Notepad。在Notepad窗⼝中输⼊⼀些⽂字然后在⽂件菜单中选择保存。运⾏代码将会在ZwCreateFile处中断。输
⼊k可查看调⽤堆栈。
在调试器窗⼝左下⾓,命令⾏的左侧,显⽰了处理器和线程的数字。在上图中处理器数字为0,线程数字为0。下图中处理器数字为0,线程数字为19。所以,在下图中我们看到是线程19(在处理器0上运⾏)的堆栈。
(11)输⼊以下命令可查看现场0的堆栈:
~
0s
k
(12)输⼊以下命令退出调试,并且从Notepad进程中分离:
qd
有代码情况下调试
假设写好了以下简单的控制台程序并且已经编译完成。
...
void MyFunction(long p1, long p2, long p3)
{
long x = p1 + p2 + p3;
long y = 0;
y = x / p2;
}
void main ()
{
long a = 2;
long b = 0;
MyFunction(a, b, 5);
}
在这个例⼦中,我们假设编译好了程序(),符号⽂件(MyApp.pdb)在C:\MyApp\x64\Debug这个路径中,程序代码在C:\MyApp\MyApp。
(1)打开WinDbg
(2)在File菜单中选择Open Executable,在Open Executable对话框中选择⽂件路径C:\MyApp\x64\Debug,选择,点击Open。
(3)输⼊命令:
.sympath srv*
.sympath+ C:\MyApp\x64\Debug
.srcpath C:\MyApp\MyApp
现在WinDbg知道从何处查程序的符号和代码。
(4)输⼊命令:
.reload
bu MyApp!main
g
程序将启动并发⽣中断,中断位置在main函数上。WinDbg显⽰出了代码和命令窗⼝。
(5)在Debug菜单中选择Step Into(或者按下F11)。继续单步调试知道进⼊MyFunction函数。当单步调试到代码⾏“y = x / p2”时,程序将会发⽣崩溃并且在调试器中发⽣中断。调试器窗⼝将输出以下内容:
(1450.1424): Integer divide-by-zero - code c0000094 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
MyApp!MyFunction+0x44:
00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000
(6)输⼊命令:
!analyze -v
WinDbg将显⽰出问题(除0异常)的分析结果
FAULTING_IP:
MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7]
00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h]
EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044)
ExceptionCode: c0000094 (Integer divide-by-zero)
ExceptionFlags: 00000000
NumberParameters: 0
...
STACK_TEXT:
00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44
00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38
00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d
00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe
00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd
00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d
STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论