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),默认就是0x1Bit 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 = 00000bb417. dt命令也可以只看数据结构的某一个域,比如 dt nt!_KPCR XXX MHz,只看MHz域
### Windbg 使用教程 #### 一、环境搭建 为了能够顺利使用WinDbg进行调试,需要先安装合适的版本。对于新用户来说,推荐安装WinDbg Preview版,该版本更新频繁且兼容性较好[^2]。 #### 二、基础命令介绍 掌握一些常用的命令有助于快速上手WinDbg: - **启动程序并附加到进程** - 可以通过`File -> Open Executable...`来打开可执行文件(.exe),或者利用快捷键Ctrl+E。 - **继续运行/暂停目标应用程序** - 输入`g`可以让被调试的应用程序继续执行直到遇到断点或者其他异常情况为止;当希望中断正在运行的目标应用时,则可以点击工具栏上的“Break”按钮或将光标置于命令窗口内按组合键Ctrl+Break实现强制停止[^3]。 - **查看调用堆栈信息** - 执行`kv`指令会显示当前线程完整的函数调用链路详情,这对于理解代码流程非常有帮助。 - **反汇编特定区域机器码** - 如果想要了解某段C/C++源码对应的底层汇编码是什么样的形式的话,那么就可以借助于`uf <function_name>`来进行局部范围内的逆向分析操作了。 - **读取内存中的数据值** - 当涉及到具体地址处的数据访问需求时(比如字符串),则可通过`da <address>`的形式获取相应位置存储的内容展示出来给开发者查阅。 - **刷新模块列表** - 若是在动态链接库(DLLs)加载过程中遇到了问题或者是怀疑某些DLL未正常注入至进程中去的时候,不妨试试`.reload`这条语句的作用吧! #### 三、高级特性探索 除了上述提到的基础功能外,WinDbg还提供了许多强大的扩展能力等待着大家深入挖掘,例如生成转储(dump)文件以便离线状态下也能开展有效的故障排查工作等。 ```powershell // 创建小型Dump文件示例 .dump /ma c:\path\to\your\dmpfile.dmp ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值