数字表达式语法
基本语法规则
- 十六进制
前缀:0x
或0n
例如:0x3A
,0n3A
- 十进制
直接写数字,无需前缀 - 八进制
前缀:0o
或0
例如:0o72
,072
- 二进制
前缀:0b
例如:0b111010
支持操作符
- 加减乘除,取模
- 按位与,按位或,按位异或,按位非
- 左移,右移
变量和寄存器
- 可以使用
$
符号来引用自定义变量
例如:$var1 + $var2
- 可以直接使用寄存器名称
例如:@eax
,@ebx
特殊符号
- 可以用括号改变运算优先级
例如:(3 + 5) * 2
字符串通配符语法
概述
- 使用字符串通配符来匹配和搜索特定的字符串或模式,这在分析调试信息、查找符号或内存内容时非常有用
基本通配符
- 星号
匹配零个或多个字符
例如:*test*
可以匹配任何包含“test”的字符串,如“mytest
”,“testing
”等 - 问号
匹配单个任意字符
例如:t?st
可以匹配“test
”,“tast
”,“tost
”等
转义字符
- 为了匹配实际的通配符字符(如
*
或?
),可以使用反斜杠 (\
) 进行转义: - 例如:
file\*name
匹配包含“file*name
”的字符串
特殊字符匹配
- 方括号
匹配方括号内的任意一个字符
例如:[a-z]
匹配任何一个小写字母 - 波浪号
匹配指定字符集之外的任意字符
例如:~[0-9]
匹配任何非数字字符
使用正则表达式
- 虽然
WinDbg
本身对正则表达式支持有限,但通过一些调试扩展工具(如WinDbg
的!regex
扩展),可以使用更强大的正则表达式功能进行复杂的字符串匹配和搜索 - 列出符合特定通配符模式的符号
例如:x ntdll!*mem*
列出ntdll
模块中所有包含“mem
”的符号 - 在内存中搜索特定的字符串模式
例如:s -su 0x1000 0x2000 "test*"
在指定的内存范围内搜索包含“test
”开头的Unicode
字符串 - 在符号或地址上设置断点,支持通配符
例如:bp kernel32!Create*
在所有以“Create
”开头的函数上设置断点
寄存器语法
基本寄存器访问
- 访问寄存器
@eax
:访问x86
架构中的EAX
寄存器
@rax
:访问x64
架构中的RAX
寄存器
@ebx
:访问x86
架构中的EBX
寄存器
@rbx
:访问x64
架构中的RBX
寄存器 - 查看所有寄存器
r
- 查看特定寄存器
r eax
修改寄存器值
- 修改
EAX
寄存器的值:
r eax=0x12345678
- 修改
RAX
寄存器的值(x64架构):
r rax=0x1234567890abcdef
使用寄存器进行表达式计算
- 计算
EAX + EBX
的值:
? @eax + @ebx
- 将
ECX
寄存器的值加上0x100
并显示结果:
? @ecx + 0x100
特殊寄存器
- 标志寄存器(
Flags
):
@efl
:访问x86/x64
架构中的标志寄存器
r efl
- 段寄存器
@cs
:代码段寄存器
@ds
:数据段寄存器
@es
:额外段寄存器
@fs
:额外段寄存器
@gs
:额外段寄存器
r cs
- 控制寄存器(仅在调试模式下):
@cr0
:控制寄存器0
@cr3
:控制寄存器3
伪寄存器语法
概述
- 是调试器提供的一种特殊机制,用于简化某些常见调试任务
- 这些伪寄存器并不对应实际的硬件寄存器,而是由调试器内部定义和维护的
常见伪寄存器:
$ip
:当前指令指针(相当于EIP/RIP
)
用于获取或设置当前的指令指针$csp
:当前调用堆栈指针(相当于ESP/RSP
)
用于获取或设置当前的调用堆栈指针$retreg
:返回寄存器(相当于EAX/RAX
)
用于获取或设置返回值寄存器$tid
:当前线程ID
$thread
:当前线程地址$proc
:当前进程地址$peb
:当前进程环境块(PEB
)地址$teb
:当前线程环境块(TEB
)地址$bp
:断点伪寄存器
修改伪寄存器值
- 修改
$ip
伪寄存器以改变程序的执行位置
r $ip=0x12345678
- 伪寄存器可以与其他寄存器和常量一起用于表达式计算
? $ip + 0x10
伪寄存器的更多用法
- 显示当前调用堆栈中的返回地址:
dds $csp L1
- 切换到特定线程:
~[$tid]s
- 显示当前线程的环境块(
TEB
)内容:
dt _TEB $teb
- 显示当前进程的环境块(
PEB
)内容:
dt _PEB $peb
源文件语法
概述
WinDbg
提供了一些命令和语法,用于与源文件进行交互和调试源代码
加载源文件
- 要在
WinDbg
中调试源代码,你首先需要确保符号文件和源文件路径正确设置
1 |
.srcpath [Path] |
1 |
.srcpath C:\MySourceFiles |
- 也可以使用
.srcpath+
命令追加源文件路径:
1 |
.srcpath+ C:\AdditionalSourceFiles |
列出源文件路径
1 |
.srcpath |
关联源文件和符号文件
- 确保
WinDbg
能够正确关联源文件和符号文件,你可以使用以下命令加载符号文件:
1 2 |
.sympath [SymbolPath] .reload /f |
1 2 |
.sympath srv*C:\Symbols*http://msdl.microsoft.com/download/symbols .reload /f |
查看源代码
- 查看当前代码位置:
1 |
.linenum |
- 跳转到特定文件和行号:
1 |
.g [FileName]:[LineNumber] |
1 |
.g main.c:100 |
设置断点
- 可以在特定的源代码行设置断点:
1 |
bp [FileName]:[LineNumber] |
1 |
bp main.c:100 |
查看源代码上下文
- 可以查看当前执行点的源代码上下文:
1 |
.list |
高级命令
- 打开源文件窗口显示当前源文件:
1 |
.viewsource |
- 显示源文件和对应的汇编代码:
1 |
.src /m |
- 向前显示更多行:
1 |
.list |
- 向后显示更多行:
1 |
.list - |
- 指定行数:
1 |
.list 50 |
- 调试过程中,你可以设置当前源文件和行号,强制
WinDbg
显示特定位置的源代码:
1 |
.setsrc main.c:100 |
地址和地址范围语法
概述
- 在
WinDbg
中,地址和地址范围的语法规则用于指定内存地址和内存区域,以便进行查看、修改、设置断点等操作
基本地址表示法
- 十六进制地址
WinDbg
中的地址通常以十六进制表示- 例如:
0x7fffd000
,0x7fffd0000000
- 模块偏移量
- 可以使用模块名和偏移量来表示地址
- 例如:
kernel32!CreateFile + 0x100
- 符号地址
- 可以使用符号表示地址
- 例如:
MyApp!main
,ntdll!DbgBreakPoint
地址范围
- 地址范围通常用于内存查看和搜索操作,表示起始地址和结束地址或起始地址和长度
- 指定起始地址和结束地址
- 格式:
[StartAddress] [EndAddress]
- 例如:
0x7fffd000 0x7fffdfff
- 格式:
- 指定起始地址和长度
- 格式:
[StartAddress] L[Length]
- 例如:
0x7fffd000 L1000
- 格式:
常见命令中的地址和地址范围用法
- 查看内存内容
- 查看指定地址处的内存
使用dd
命令(显示双字)
dd 0x7fffd000
- 查看指定地址范围内的内存
使用dd
命令(指定地址范围)
dd 0x7fffd000 0x7fffdfff
dd 0x7fffd000 L100
- 查看指定地址处的内存
- 搜索内存
- 搜索指定地址范围内的字节序列
s -b 0x7fffd000 0x7fffdfff "MyString"
- 搜索指定地址范围内的字节序列
- 设置断点
- 在指定地址设置断点
bp 0x7fffd000
- 在模块符号上设置断点
bp kernel32!CreateFile
- 在地址范围内设置访问断点
ba w 4 0x7fffd000
- 在指定地址设置断点
- 反汇编
- 反汇编指定地址处的代码
u 0x7fffd000
- 反汇编指定地址范围内的代码
u 0x7fffd000 0x7fffd020
u 0x7fffd000 L20
- 反汇编指定地址处的代码
线程语法
概述
- 在
WinDbg
中,线程的管理和操作是调试过程中的一个重要部分
查看线程信息
- 列出所有线程
~
- 显示特定线程的信息
~3
切换线程
- 切换到特定线程
~3s
- 切换到当前活动线程
~#s
查看和修改线程上下文
- 使用
r
命令显示当前线程的寄存器上下文 - 使用
~[ThreadID]r
命令显示特定线程的寄存器上下文
1 |
~3r |
- 使用
r [Register]=[Value]
命令修改当前线程的寄存器值
1 |
r eax=0x12345678 |
堆栈跟踪
- 使用
k
命令显示当前线程的堆栈跟踪 - 使用
~[ThreadID]k
命令显示特定线程的堆栈跟踪~3k
- 使用
~*k
命令显示所有线程的堆栈跟踪
挂起和恢复线程
- 使用
~[ThreadID]n
命令挂起指定的线程~3n
- 使用
~[ThreadID]m
命令恢复指定的线程~3m
杀死线程
- 使用
~[ThreadID]k
命令杀死指定的线程~3k
特殊命令
- 使用
!teb
命令显示当前线程的TIB
信息 - 使用
!teb [ThreadAddress]
命令显示特定线程的TIB
信息
1 |
!teb 0x12345678 |
线程上下文切换
- 在不同的线程之间切换时,
WinDbg
会自动更新寄存器和堆栈跟踪信息,以反映当前选定的线程 - 确保在执行关键调试任务前切换到正确的线程非常重要
进程语法
概述
- 在
WinDbg
中,与进程相关的命令和语法规则用于管理和调试进程
查看进程信息
- 使用
命令列出所有正在调试的进程
- 使用
命令后接进程
ID
显示特定进程的信息
1 |
| 1 |
切换进程
- 使用
.process
命令切换到指定的进程/r
选项用于刷新当前的进程和线程上下文/p
选项后跟进程地址
1 |
.process /r /p 0x12345678 |
查看和设置进程环境
- 使用
!peb
命令显示当前进程的PEB
- 使用
!peb
命令后跟进程地址显示特定进程的PEB
1 |
!peb 0x12345678 |
查看进程模块
- 使用
lm
命令列出当前进程加载的模块 - 使用
lm m
命令列出所有进程加载的模块
切换到进程的线程
- 使用
~
命令列出所有线程 - 使用
~[ThreadID]s
命令切换到指定线程
1 |
~3s |
调试子进程
- 使用
.childdbg
命令设置是否调试子进程- 其中,
1
表示调试子进程,0
表示不调试子进程
- 其中,
1 |
.childdbg 1 |
进程内存信息
- 使用
!address
命令显示当前进程的内存分布 - 使用
!address [Address]
命令显示特定地址的内存信息
1 |
!address 0x12345678 |
系统语法
概述
WinDbg
中的系统语法规则涉及一系列命令和语法,用于获取和操作系统级别的信息,如处理器、内存、设备驱动程序等
查看系统信息
- 使用
!sysinfo
命令查看系统的基本信息 - 使用
!cpuinfo
命令查看处理器的信息
查看内存信息
- 使用
!address
命令显示系统内存的详细分布信息 - 使用
!address [Address]
命令显示指定地址的详细信息 - 使用
!memusage
命令显示系统物理内存的使用情况
查看驱动程序信息
- 使用
lm
命令列出所有加载的驱动程序
1 |
lm t n |
- 使用
!driver
命令查看特定驱动程序的详细信息
1 |
!driver nt |
查看设备信息
- 使用
!devobj
命令列出系统中的所有设备对象 - 使用
!devnode
命令查看特定设备节点的详细信息
1 |
!devnode 0xfffffa8001234567 |
查看模块和符号
- 使用
lm
命令列出所有加载的模块 - 使用
x
命令查看特定模块的符号信息
1 |
x nt!* |
查看和控制中断
- 使用
!irql
命令显示当前中断请求级别(IRQL
) - 使用
!irql [Level]
命令设置中断请求级别
1 |
!irql 2 |
查看系统时间和时钟信息
- 使用
!time
命令显示系统时间信息 - 使用
!timer
命令显示系统计时器信息
多处理器语法
概述
- 在
WinDbg
中,多处理器语法用于管理和调试系统中的多个处理器(CPU
) - 这包括查看处理器状态、切换当前处理器、查看每个处理器的上下文信息等
查看处理器信息
- 使用
!cpuinfo
命令查看系统中所有处理器的详细信息 - 使用
!pcr
命令查看当前处理器控制区(PCR
)的内容
切换当前处理器
- 使用
~*
命令列出所有处理器的基本信息 - 使用
~~[ProcessorNumber]s
命令切换到指定的处理器
1 |
~~0s |
查看和修改处理器上下文
- 使用
r
命令显示当前处理器的寄存器上下文 - 使用
~[ProcessorNumber]r
命令显示特定处理器的寄存器上下文
1 |
~0r |
- 使用
r [Register]=[Value]
命令修改当前处理器的寄存器值
1 |
r eax=0x12345678 |
查看处理器的堆栈跟踪
- 使用
k
命令显示当前处理器的堆栈跟踪 - 使用
~[ProcessorNumber]k
命令显示特定处理器的堆栈跟踪
1 |
~0k |
- 使用
~*k
命令显示所有处理器的堆栈跟踪
设置断点
- 使用
bp
命令设置全局断点,适用于所有处理器 - 使用
~[ProcessorNumber]bp
命令在特定处理器上设置断点
1 |
~0bp [Address] |
高级用法
- 使用
!pcr [ProcessorNumber]
命令查看特定处理器的PCR
内容
1 |
!pcr 0 |
- 使用
~[ThreadID]m
命令设置或显示线程的处理器亲和性
1 |
~3m |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Dump分析:调试方法与实践,空指针访问03/15
- ♥ Soui应用 动画二06/27
- ♥ C++程序高级调试与优化_第一篇07/20
- ♥ COM组件_101/31
- ♥ Soui三05/19
- ♥ WindowsHOOK相关03/17