Windbg常用命令
.extpath 扩展模块搜索路径
.ecxr;kb
!analyze -v
~ - 列举出当前进程上下文中的所有线程
~* - 列举出当前进程上下文中的所有线程的详细信息
lm - 列举出所有加载的模块
!sym noice/quiet - 代码提示开关
.srcpath -设置源码路径
k - 显示当前堆栈
~*kb -显示出所有线程占用的堆栈
dv - 显示出本地变量(使用ctrl + alt + v切换模式)
.Frame - 调用堆栈
dt xxx - 显示出诸如PEB等的数据结构
dt ESAlertServer!* /v /s 14
!gle/!error - 显示出最新线程错误
!teb - 显示出当前线程执行块
!peb - 显示出当前进程执行块
r [@register] - 显示所有注册的值
ln [Address] - 显示地址类型
x [] -查询全局变量和全局函数
!locks - 显示所有死锁
exit (退出)
.kdfiles map.ini
map.ini
map
\Systemroot\system32\drivers\tag.sys
c:\host.sys
vertarget 显示操作系统信息
u - 反汇编
uf
bp [Kernel!SetLastError] [value] - 设置断点
bl - 显示断点信息
ba - 数据断点
ba w4 0x4000000 "kb;g" - 显示出地址0x40000调用的所有堆栈
p,pa,t,ta - 控制命令
.time
!runaway 7
- Bit 0 (0x1)
- Causes the debugger to show the amount of user time consumed by each thread.
- Bit 1 (0x2)
- Causes the debugger to show the amount of kernel time consumed by each thread.
- Bit 2 (0x4)
- Causes the debugger to show the amount of time that has elapsed since each thread was created.
显示当前线程的错误值:!gle会显示当前线程的上一个错误值和状态值。!error命令可以解码hresult。
查看lock:!locks显示各线程的锁资源使用情况。对调试死锁很有用。
查看handle:!handle显示句柄信息。假如一段代码导致句柄泄漏,你只需要在代码执行前后使用!handle命令并比较两次输出的区别。有一个命令!htrace对调试与句柄有关的bug非常有用。在开始调试前输入:
!htrace –enable
然后在调试过程中使用!htrace handle_value 来显示所有与该句柄有关的调用堆栈。
显示当前线程,进程和模块信息:
!teb显示当前线程的环境信息。最常见的用途是查看当前线程堆栈的起始地址,然后在堆栈中搜索值。
!peb显示当前进程的环境信息,比如执行文件的路径等等。
lm显示进程中加载的模块信息。
0:001> !heap -s
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00150000 00000002 1024 52 52 5 1 1 0 0 L
00250000 00008000 64 12 12 10 1 1 0 0
00370000 00000002 64 36 36 5 2 1 0 0 L
00380000 00001002 64 16 16 0 0 1 0 0 L
003a0000 00001002 256 12 12 4 1 1 0 0 L
00030000 00001002 64 32 32 4 1 1 0 0 L
003e0000 00001002 64 32 32 24 1 1 0 0 L
Virtual block: 00aa0000 - 00aa0000 (size 00000000)
Virtual block: 00bc0000 - 00bc0000 (size 00000000)
00a80000 00001003 64 20 20 8 1 1 2 bad
-----------------------------------------------------------------------------
0:001> !heap -s
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
00150000 00000002 1024 52 52 5 1 1 0 0 L
00250000 00008000 64 12 12 10 1 1 0 0
00370000 00000002 64 36 36 5 2 1 0 0 L
00380000 00001002 64 16 16 0 0 1 0 0 L
003a0000 00001002 256 12 12 4 1 1 0 0 L
00030000 00001002 64 32 32 4 1 1 0 0 L
003e0000 00001002 64 32 32 24 1 1 0 0 L
Virtual block: 00aa0000 - 00aa0000 (size 00000000)
Virtual block: 00bc0000 - 00bc0000 (size 00000000)
Virtual block: 00cd0000 - 00cd0000 (size 00000000)
Virtual block: 00de0000 - 00de0000 (size 00000000)
00a80000 00001003 64 20 20 8 1 1 4 bad
-----------------------------------------------------------------------------
0:001> !heap -stat -h 00a80000
heap @ 00a80000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
100000 4 - 400000 (99.76)
1000 1 - 1000 (0.10)
800 1 - 800 (0.05)
280 1 - 280 (0.02)
20 12 - 240 (0.01)
30 9 - 1b0 (0.01)
40 6 - 180 (0.01)
160 1 - 160 (0.01)
50 4 - 140 (0.01)
110 1 - 110 (0.01)
100 1 - 100 (0.01)
d0 1 - d0 (0.00)
60 2 - c0 (0.00)
10 b - b0 (0.00)
0:001> !heap -flt s 100000
_HEAP @ 150000
_HEAP @ 250000
_HEAP @ 370000
_HEAP @ 380000
_HEAP @ 3a0000
_HEAP @ 30000
_HEAP @ 3e0000
_HEAP @ a80000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00aa0018 20000 0000 [0b] 00aa0020 100000 - (busy VirtualAlloc)
00bc0018 20000 0000 [0b] 00bc0020 100000 - (busy VirtualAlloc)
00cd0018 20000 0000 [0b] 00cd0020 100000 - (busy VirtualAlloc)
00de0018 20000 0000 [0b] 00de0020 100000 - (busy VirtualAlloc)
0:001> !heap -p -a 00aa0018
address 00aa0018 found in
_HEAP @ a80000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00aa0018 20000 0000 [0b] 00aa0020 100000 - (busy VirtualAlloc)
dt _DPH_BLOCK_INFORMATION
WinDBG中设置条件断点
条件断点:断点指令 + “j(Excecute If-Else) 和 gc (Go from Conditional Breakpoint)”
形如:bp Address "j (Condition) 'OptionalCommands'; 'gc' "
这里仅简单说明该如何写后面的条件语句
1. 非结构体变量:
"j (poi(MyVar)>5) '';'gc'" 在代码中,MyVar是整数变量。默认的debug配置采用MASM语法,因此MyVar被当作指针看待,在做条件判断时,需要使用poi解引用。如果debug配置采用C++语法,MyVar会被解析为整数变量,可直接用于条件判断。条件为真时对应的语句为空,则当条件满足时,会断在此处。gc表示从断点处继续运行。
2. 结构体变量
"j (@@c++(MyStruct->field)>5) '';'gc'" 判断结构体变量中的某个成员变量时,采用C++语法解析表达式:@@c++(...)。因默认配置是masm语法,故对于结构体成员都用此种方法解析。
3. 寄存器
1 "j @eax = 0xa3 ''; 'gc'" <1>
2 "j @eax = 0xc0004321 '';'gc'" <2>
3 "j (@eax & 0x0`ffffffff) = 0x0`c0004321 '';'gc'" <3>
式<1>:当eax的值为0xa3时,触发该断点。
在masm表达式中,寄存器是做符号扩展的,即0xc0004321实际被当作是0xffffffff`c0004321,即便实际显示时是0xc00004321。这种符号扩展仅存在于kernel mode中。因此式<2>在kernel mode会失败。最好的改法则是按照式<3>的方式做条件比较,该方式可以同时用于kernel mode和user mode。
bu MSMPPEKey::insert "kb; .time; g"
bm /a iassam!Auth* "kb; g"