WinDBG使用

1. 符号路径设置:
Ctrl+S在弹出的窗口中输入你的符号路径,路径的格式只要符合Windows操作系统路径格式即可,路径可以多个,中间以分号间隔,c:\symbols\local;
Windbg可以自动到Microsoft的服务器上下载符号表文件(.dbg或.pdb,有时DLL和EXE也会下载),只要在符合表路径里做如下设置:srv*c:\symbols\server*http://msdl.microsoft.com/download/symbols,这样如果相关符号表在c:\symbols\local目录没有找到的话,Windbg会自动在Microsoft的Symbol Servers上下载,保存在本地的c:\symbols\server目录下。
 
2. 线程命令
查看线程    ~
线程切换    ~+线程序号+s
 ~#  显示原始的产生异常的线程(或调试器附加到进程时活动的线程)

冻结线程~<tid>f

解冻线程~<tid>u

3. 把当时程序内存空间数据都保存下来,生成的文件称为dump 文件,命令是 .dump

选项(1): /m

命令行示例:.dump /m C:\dumps\myapp.dmp
注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。
选项(2): /ma
命令行示例:.dump /ma C:\dumps\myapp.dmp
注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。
选项(3):/mFhutwd
命令行示例:.dump /mFhutwd C:\dumps\myapp.dmp
注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。
 
4. 条件断点
基本格式为bp Address "j (Condition) 'OptionalCommands'; 'gc' "
例如,当某个事件设为通知状态时中断,则为: bp Kernerl32!SetEvent  "j (poi(esp+4)=id) 'echo breaked'; 'gc' "
多个条件可用|,&等符号连接
poi(esp+4)=id 为中断条件,因为SetEvent是stdcall的,调用到他这的时候还没有push ebp,所以第一个参数为esp+4,poi为取地址中的值,如果函数是fastcall等,还可能是ecx,edx等
 
5. 内存断点
ba  e2 address     //执行时中断
ba  r2 address     //读取时中断
ba  w2 address   //写入时中断

6. !runaway 显示每个线程消费的时间
Bit 0 (0x1) 让调试器显示每个线程消耗的用户模式时间(user time),默认就是0x1 Bit 1 (0x2) 显示每个线程消耗的内核时间(kernel time)。 Bit 2 (0x4) 显示每个线程从创建开始经历了多少时间 !runaway 1;  !runaway 3等都可
7. 64位系统下抓的dump,可能无法正常显示调用栈  .load wow64exts
 .effmach x86   //切环境到x86
!wow64exts.sw     Switches between x86 and native mode.   有时mini dump可能无x86的栈信息

!wow64exts.k count
Dumps a combined 32-bit/64-bit stack trace. If count is specified, the command dumps the first count addresses in each stack trace.

!wow64exts.info
Dumps basic information about the PEB of the process, the TEB of the current thread, and thread local storage (TLS) slots used by WOW64.

!wow64exts.r address

Dumps context for the specified address. If address is not specified, the command dumps context for the processor.


8.  vertarget,.time 都可用来查看进程运行了多长时间

9. 从dump查看所在机器的ie版本 lm列举模块,看ie开头的模块的版本,一般是iertutil.dll
10.单步调试 p 执行一行,遇到函数不进入  t 单步执行,遇到函数进入 gu 执行到当前函数结束 bp 对地址或符号下断点 bm 一次可下多个断点,比如bm modeule!class:* bl 显示所有断点 bc index 清除断点
11.中断 sxe ld:[dllname]  如 sxe ld:[ntdll]//加载dll时中断
sxe ud:[dll name]//free dll时中断
bu wininet!DllMain//直接在dllmain下断

12.手动切换至异常栈 有时dump里面并无异常信息,需要手动构造异常栈, ChildEBP RetAddr  Args to Child              
0773ed70 77606a04 75486a8e 00000002 0773edc4 ntdll!KiFastSystemCallRet
0773ed74 75486a8e 00000002 0773edc4 00000001 ntdll!ZwWaitForMultipleObjects+0xc
0773ee10 76f9bd66 0773edc4 0773ee38 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
0773ee58 76f9bdd4 00000002 7ffd8000 00000000 kernel32!WaitForMultipleObjectsExImplementation+0xe0
0773ee74 76fb05ef 00000002 0773eea8 00000000 kernel32!WaitForMultipleObjects+0x18
0773eee0 76fb088a 0773efc0 00000001 00000001 kernel32!WerpReportFaultInternal+0x186
0773eef4 76fb0838 0773efc0 00000001 0773ef90 kernel32!WerpReportFault+0x70
0773ef04 76fb07b3 0773efc0 00000001 40c34bd7 kernel32!BasepReportFault+0x20
0773ef90 77637f02 00000000 775de324 00000000 kernel32!UnhandledExceptionFilter+0x1af
0773ef98 775de324 00000000 0773ffd4 77611208 ntdll!__RtlUserThreadStart+0x62
0773efac 775de1b4 00000000 00000000 00000000 ntdll!_EH4_CallFilterFunc+0x12
0773efd4 77607199 fffffffe 0773ffc4 0773f0dc ntdll!_except_handler4+0x8e
0773eff8 7760716b 0773f0c0 0773ffc4 0773f0dc ntdll!ExecuteHandler2+0x26
0773f01c 775df98f 0773f0c0 0773ffc4 0773f0dc ntdll!ExecuteHandler+0x24
0773f0a8 77606ff7 0073f0c0 0773f0dc 0773f0c0 ntdll!RtlDispatchException+0x127
0773f0a8 00000000 0073f0c0 0773f0dc 0773f0c0 ntdll!KiUserExceptionDispatcher+0xf
类似上面这样的异常栈,analyze命令是找不到异常信息的,kb命令也显示不了具体抛异常时候的栈信息,需要自己找异常上下文,基本思路是 从kernel32!UnhandledExceptionFilter的参数EXCEPTION_POINTERS,下面是EXCEPTION_POINTERS 结构的声明:
typedef struct _EXCEPTION_POINTERS 
{  
    PEXCEPTION_RECORD ExceptionRecord;  
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
找到 ContextRecord的地址后,用.cxr命令即可切换到相应栈环境。如果kb里显示的kernel32!UnhandledExceptionFilter的参数无效的话,可以用dps命令自己在栈上找
有些情况下堆栈中没有UnhandledExceptionFilter,而只有_except_handler函数,这个是SEH异常处理函数。函数原型:EXCEPTION_DISPOSITION __cdecl _except_handler( 
                         struct _EXCEPTION_RECORD *ExceptionRecord,
                         void * EstablisherFrame,
                         struct _CONTEXT *ContextRecord,
                         void * DispatcherContext); 

第一和第三个参数,分别对应上文的EXCEPTION_POINTERS结构体的两个参数
13. !idt 显示idt信息,!dpcs显示dpc信息 14. !stacks 1 XX 显示内核栈信息,1表示换出的内核栈也显示,XX是一个过滤条件,如写为ndis,则只显示包含ndis的栈 15.  !heap命令,显示堆信息,参数比较多,列出常用的几个 !heap -x Address 在堆中查找包含这个Address的内存块,-v可选,表示也搜索虚拟内存,会较慢 !heap -i HeapAddr显示指定Heap的信息 16. ?命令用于数值转换,比如 ?bb4输出为Evaluate expression: 2996 = 00000bb4 17. dt命令也可以只看数据结构的某一个域,比如 dt nt!_KPCR XXX MHz,只看MHz域
Windbg是一款用于Windows调试的工具,可以用来分析dmp文件。以下是使用Windbg的教程: 1. 下载Windbg:你可以从Windows 10 SDK中下载Windbg,或者在已安装Windows 10 SDK的情况下,在控制面板的程序中选择安装Debugging Tools For Windows。 2. 准备dmp文件:你可以通过使用Windows管理器的"创建转储文件"功能来生成dmp文件,或者使用Windbg附加到进程的方式,在程序运行到出错位置后生成dmp文件。 3. 打开dmp文件:你可以使用Windbg或者Visual Studio来打开dmp文件进行分析。如果是通过"创建转储文件"生成的dmp文件,可以使用Windbg或者Visual Studio打开。如果是通过Windbg附加到进程后生成的dmp文件,可以使用Windbg打开。 4. 分析dmp文件:使用Windbg打开dmp文件后,你可以使用各种Windbg命令来分析和调试程序。你可以参考相关的参考文章和教程来学习如何使用Windbg进行调试。 需要注意的是,使用Visual Studio打开通过Windbg附加到进程生成的dmp文件时可能会提示版本过旧无法打开。这是因为Visual Studio和Windbg使用的调试引擎不同。在这种情况下,建议使用Windbg来分析dmp文件。 希望这个教程对你有帮助! #### 引用[.reference_title] - *1* *2* *3* [windbg使用教程(调试异常及死锁等)](https://blog.csdn.net/baidu_38621657/article/details/110942007)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值