调试器
关于调试器。
调试器类型
- 用户态调试器
- 内核态调试器
用户态调试器
- 查看调试目标的状态
- 线程、内存、寄存器以及进程空间中打开的内核对象等
- 修改调试目标的状态
- 实时调试
- 分析包含进程快照的转储文件
- 事后调试
调试工具
- cdb.exe
- 字符界面
- 可以对windows用户态的内存和结构进行底层分析
- ntsd.exe
- 与cdb类似
- windbg.exe
内核态调试器
- 可以从整体上来分析计算机系统
- 对于内核态调试器而言,每个进程或线程都只是一组数据结构,它们的内存地址与系统中安装的物理内存有着直接的关联,如果有内存页没有被加载到物理内存,就无法查看对应的内存信息
- 可以修改整个计算机的状态
- 实时内核调试
- 主要被设备驱动程序开发人员使用
- 可以加载内核态的转储文件
调试工具
- kd.exe
- windbg.exe
调试器命令
标准命令
- 以可执行文件的方式实现的命令
- 不需要任何前缀
元命令
- 另一种以可执行文件实现的命令
- 命令以
.
开头
扩展命令
- 可以在调试目标上执行的其他的功能
- 命令以
!
开头
调试器配置
符号文件
- 编译器和链接器在创建
.exe
,.dll
,.sys
以及其他可执行文件(二进制文件或映像)的时候,创建的一些其他附加文件。
符号文件内容
- 全局变量的名字和地址
- 函数名、地址以及原型
- 帧指针优化数据
- 局部变量的名字和地址
- 源文件路径以及每个符号的行号
- 变量、结构等的类型信息
寄存器
- 根据调试器中设置的寄存器掩码来显示寄存器的值
关于命令
- 命令
r
可以访问处理器中的寄存器 - 命令
rm
显示寄存器掩码 - 命令
rm ?
显示寄存器掩码各个位的含义 - 命令
rm 0
将寄存器掩码设置为零
伪寄存器
- 不同平台的指令指针寄存器的名字存在差异,所以调试器引入了伪寄存器对应到不同的硬件架构上
$ip
- X86
- $ip = eip
- X64
- $ip = rip
- Itanium
- $ip = iip
$ra
- 当前函数的返回地址
$retreg
- 主要的值寄存器,函数调用返回的结果将放在这里
- X86
- $retreg = eax
- X64
- $retreg = rax
- Itanium
- $retreg = ret0
$csp
- X86
- $csp = esp
- X64
- $csp = rsp
- Itanium
- $csp = psp
$proc
- 当前的进程
- 包含的是用户态的进程环境块地址
$thread
- 当前的线程
- 包含的是用户态的线程环境块地址
$tpid
- 当前进程的标识
$tid
- 当前线程的标识
调用栈
- 记录在执行完当前函数之后程序继续执行的地址
- 栈内存区域是由栈寄存器控制的
- X86处理器的栈通常朝着低地址方向增长
- X86处理器的栈的栈顶地址保存在栈指针寄存器中,也就是esp
函数和栈
- 当进入函数时,编译器将生成所谓的栈帧,栈帧的基指针是通过寄存器ebp来维护的。
- 函数前导指令将把ebp的当前值保存在栈上,然后将当前栈帧的基指针值加载到ebp中,这个值,将会在ebp中一直保留直到执行函数后继指令。
- 在函数中,编译器通过将ebp与正偏移相加来获得函数参数的地址;编译器通过将ebp与负偏移来取得在函数中分配的局部变量的地址。
- 在后继指令中,函数执行之前保留的ebp的值,将被重新加载到ebp中。这样在完成函数调用之后,寄存器ebp的值将会恢复到函数调用之前的值。
关于命令
- 命令
k
可以分析当前的栈 - 命令
kp
将在一行内显示所有参数 - 命令
kP
将把每个参数单独显示一行 - 命令
kp 5
将显示调用栈中的前5个函数 - 命令
kb
将显示在栈上传递给函数的前3个函数 - 命令
kf
将显示在调用栈上函数所使用的栈大小 - 手动重新构造栈
dc esp
k = a b c
,a,b,c为dc esp
显示内容的前3条
- 命令
bp
将设置一个断点 - 命令
bc *
将清除所有断点 - 命令
bm
将在参数中指定一个符号模式,后果就是在所有与这个模式匹配的地址上都将设置一个断点 - 命令
bu
将设置一个延迟断点,只有当这个断点所在的模块被加载时,延迟断点才会成为一个真正的断点 - 命令
dv
将显示局部变量的值 - 命令
dv aa*
将显示与aa匹配的变量的值 - 命令
dv /i
将在第二列显示符号类型和参数类型 - 命令
dv /v
将显示变量的储存位置 - 命令
dv /v
将显示变量的储存位置 - 命令
dt
可以将一块内存按照作为参数传给它的数据结构的类型来解析 - 命令
dc
用来查看一个堆块dc @ecx 14
ln 00401504
dt KBTest @ecx
- 命令
!peb
将显示进程环境块的内容,如调试目标的启动参数 - 命令
!teb
将显示线程环境块的内容 - 命令
!gle
将抽取出错误码并且显示格式化的字符串 - 命令
t
用于单步执行代码- 汇编模式跟踪代码时,t每次执行一条汇编指令
- 源代码模式跟踪代码时,t每次可能会执行多条汇编指令
1+t
:step/trace by source line
1-t
:none
- 命令
p
将把整个函数调用视作一条语句来执行 - 命令
pc
将使代码的执行停止在下一个子例程的调用处 - 命令
g
表示无条件的恢复调试目标的执行 - 命令
g <address>
表示将调试目标执行到指定地址 - 命令
gu
将使调试目标执行完当前函数并且返回到调用者 - 命令
wt
能够获得被调函数的一些信息 - 命令
~
能够列出所有线程 - 命令
~0s
将切到0号线程 - 命令
.frame
将改变上下文并且控制对dv
命令所能显示的局部变量 - 命令
.thread
将设置当前的线程的上下文到当前的寄存器上 - 命令
!error
能够找出与错误相关的一些信息 - 命令
.formats
能够以各种格式来显示参数 - 命令
bp test::call "gu;.if (eax!=1){g}"
,条件断点的格式 - 命令
!process
可以获取目标进程中EPROCESS
结构的地址 - 命令
!object
能够获取到一个结构的头地址,然后基于该地址来设置内存访问断点
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Soui四05/23
- ♥ Soui六06/01
- ♥ Windows 核心编程 _ 进程四06/25
- ♥ Windbg:命令实践详解一03/27
- ♥ Soui三05/19
- ♥ 包管理器:各平台安装卸载相关记述09/17