WinDBG 要点学习

来源:互联网 发布:数据库系统分为 编辑:程序博客网 时间:2024/06/07 05:19
WinDBG
 用户可以自由定义调试事件的处理方式,编写调试扩展模块来定制和补充WinDBG的调试功能。
 目前版本的WinDBG提供了20多条标准命令,140 多条元命令,大量的扩展命令。
 WinDBG使用工作空间来描述和存储一个调试项目的属性、参数、以及调试器设置等信息。
 WinDBG支持两种方法在命令中加入注释文字,一种是使用*命令,一种使用$$。
 WinDBG支持定义和使用三类别名:用户命名别名,固定名称别名,WinDBG自动定义的别名。

 在很多命令前可以加上进程和线程限定符,用来指定这些命令所适用的进程和线程。
 以下命令显示0号线程的寄存器和栈回溯,
~0r;~0k;
 可以把输入的命令和命令的执行结果记录到一个文本文件中,称为Log File。
 附加到已经运行的进程的方法有:使用菜单或F6热键;将WinDBG设置为JIT调试器;启动WinDBG时使用-p开关;启动WinDBG时使用-pn开关;使用.attach命令。
 当调试系统服务或者被其它程序自动启动的程序时,通常需要使用上面介绍的方法来建立调试会话。
 非入侵式调试,WinDBG与目标进程没有真正建立调试与被调试的关系。

WinDBG 双机内核调试
 两台系统之间的通信方式,目前WinDBG支持串行口、1394、USB2三种方式。
 内核调试引擎内建在Windows系统中,缺省是禁止的。
 如果目标系统是Windows Vista,应该使用BCDEdit工具来修改它的启动选项。
 对于串行口方式,主机和目标系统所使用的COM端口号可以不同,但波特率应该一样。
 对于1394方式,主机和目标机的channel号一定要一致。

 所谓局部上下文,Local Context,是指局部变量所基于的语境。
 在调试时,调试器缺省显示的是当前函数所对应的局部上下文。
 当前函数和局部变量都是与栈帧密切相关的,所以WinDBG调试器通常使用栈帧号来代表局部上下文。
 使用不带任何参数的.frame命令可观察当前的局部上下文。
 使用dv命令可以显示当前函数的参数和局部变量。

栈回溯的基本原理和步骤
 根据程序的当前执行位置,得到程序指针寄存器的值,然后查找符号得到当前所在的函数。
 寻找当前函数的栈帧基准地址;EBP是栈帧的基准地址,ESP是栈的当前栈顶地址。
 得到的EBP值便是栈回溯报告中的ChildEBP值,将其记录在当前行的第一列。
 寻找当前函数的返回地址,这个信息通常被保存在EBP+4位置。
 典型的函数返回地址在0x400000到0x80000000间。
 寻找父函数的栈帧基地址;继续寻找父函数的父函数;直到ChildEBP值等于0,表示已经到达当前线程的最后一帧。


 命令e用来修改指定内置地址或者区域的内容。
 在任一用户态调试会话中执行dt ntdll!*List*可以看到很多链表类型。
 Windows中主要使用两种链表,一种是双向链表,每个节点是一个LIST_ENTRY结构。
 另一种是单向链表,每个节点是SINGLE_LIST_ENTRY结构。
 Windows系统内所有进程的EPROCESS结构是通过ActiveProcessLinks字段相互链接的。
 全局变量PsInitialSystemProcess记录了初始的系统进程的EPROCESS结构的地址。
 使用如下的dt命令来遍历所有进程,
dt nt!_EPROCESS -l ActiveProcessLinks.Flink -y Ima -yoi Uni poi(PsInitialSystemProcess)


 可使用WinDBG的.call元命令来从调试器中调用被调试程序中的函数。
 模仿C/C++语言中的流程控制关键字,WinDBG定义了一系列元命令和扩展来实现流程控制,统称为流程控制符号。
 WinDBG命令程序中可以使用如下几种变量:自动的伪寄存器;用户赋值的伪寄存器;用户定义的别名;自动别名;固定名称的别名。
 控制线程执行,第一种方法是通过增加线程的挂起计数来禁止线程被恢复运行。
 输入如下命令可以增加1号线程的挂起计数,
~1 n
 控制线程执行的第二种方法是使用~f和~u命令,前者冻结一个线程,后者解冻。


 Windows操作系统的进程加载器加入了特别的调试支持:在完成最基本的用户态初始后,系统的进程初始化函数就会主动执行断点指令,触发断点,让调试目标中断到调试器中。这个断点称为初始断点。
 NTDLL的LdrpInitializeProcess函数调用了DbgBreakPoint,后者包含了断点指令。
 初始线程真正在新进程环境下执行是从内核态的KiThreadStartup开始的。
 KiThreadStartup 将线程的IRQL(中断级别)降到APC级别后调用PspUserThreadStartup来为线程在用户态执行做准备。
 
0 0
原创粉丝点击