Windbg常用指令(持续更新)
1、!drvobj
!drvobj 扩展命令显示DRIVER_OBJECT的详细信息。
语法
!drvobj DriverObject [Flags]
参数
DriverObject
指定驱动对象。可以是DRIVER_OBJECT的16进制地址或者驱动的名字。
Flags
(Windows 2000和之后) 可以是下面这些位的任意组合。(默认为0x01。)
Bit 0 (0x1) 显示驱动拥有的设备对象。 Bit 1 (0x2) 显示驱动的dispatch例程的入口点。 Bit 2 (0x4) 显示驱动的设备对象的详细信息(需要设置bit 0)。
DLL
Windows 2000 Kdextx86.dll
Windows XP和之后 Kdexts.dll
注释
如果DriverObject指定设备名,但是没有带前缀,则假定使用\Driver\前缀。注意该命令在使用表达式求值器前会检查DriverObject是否是合法地址或者设备名。
如果DriverObject是一个地址,它必须是DRIVER_OBJECT结构的地址。这可以通过检查传递给DriverEntry函数的参数得到。
该扩展命令会显示指定的驱动程序创建的所有设备对象的立标。还会显示该驱动对象注册的所有fast I/O例程。
下面是一个Symbios Logic 810 SCSI 小端口驱动程序的例子:
kd> bp DriverEntry // breakpoint at DriverEntry
kd> g
symc810!DriverEntry+0x40:
80006a20: b07e0050 stl t2,50(sp)
kd> r a0 //address of DevObj (the first parameter)
a0=809d5550
kd> !drvobj 809d5550 // display the driver object
Driver object is for:
\Driver\symc810
Device Object list:
809d50d0
还可以使用!devobj 809d50d0来获得设备对象的信息。
2、dt _DRIVER_OBJECT 地址
dt命令主要用来查看相关的变量,结构体等的信息,它配合一些参数使用可以 获取想要的信息。
3、 bp 设定调试断点
(1)比如可以这样写:0:018>bp notepad!WinMain 在notepade的winmain函数处下断点。
断点的位置可以用符号来表示,如上,也可以直接用地址以及windbg的Pseudo_Register(虚拟寄存器)。
比如,我们用e x e n t r y 表 示 进 程 的 入 口 , 那 么 可 以 用 b p @ exentry表示进程的入口,那么可以用bp @exentry表示进程的入口,那么可以用bp@exentry在进程的入口设置断点。
(2)如果notepade的winmain的入口地址为01006420,那么断点也可以这么写:
Bp 01006420
bp mysource.cpp:143` ‘j (poi(MyVar)”0x20) ‘’’’; ‘‘g’’ ’
意思就是:当myvar的值等于0x20时,g命令继续执行;
(3)下面一个设置条件断点
0:001> bp exceptioninject!foo3 “k; .echo ‘breaks’ ; g”
在exceptioninject!foo3上设置断点后,每次断下来后,先用k显示callstack,然后用.echo命令输出简单的字符串‘breaks’,最后g命令继续执行。
(4)下面看一个更复杂的设置条件断点的例子:
ba w4 execptioninject!i ”j(poi(exceptioninject!i)<0n40) ‘.printf//”exceptioninject!i value is :%d//”,poi(exceptioninject!i); g’ ; ‘.echo stop!’ ”
首先ba w4 exceptioninject!i 表示在修改exceptioninject!i这个全局变量的时候,停下来
;
j(judge)命令的作用就是对后面的表达式作条件判断如果为true,执行第一个单引号里面的命令,否则执行第2个单引号里面的命令,条件表达式是(poi(exceptioninject!i)<0n40),在windbg中excepioninject!i符号表示符号所在的内存地址,而不是符号的数值,相当于c语言的&操作符的作用,poi命令就是取这个地址上的值,相当于c语言的*操作符。
所以这个条件判断的意思就是判断exceptioninject!i的值,是否小于十进制的40。如果为真,就执行第一个单引号,‘.printf//”exceptioninject!i value is :%d//”,poi(exceptioninject!i); g’,如果为假,就执行第二个单引号‘.echo stop!’
第一个单引号里有三个命令,.printf .echo 和g。这里的printf和c语言的printf函数语法一样,不过由于这个printf命令本身是在ba命令的双引号里面,所以需要用//来转义print中的引号。第一个引号的作用是:打印出当前exceptioninject!i的值,.echo命令换行 g命令继续执行
第二个引号的作用就是显示stop,由于后面没有g命令,所以windbg会停下。
4、P
跟踪指令
5、U
数据查看指令
eg: 在上一步中我们使用跟踪指令P,看到了一句call esi,这时,我们使用u指令,查看call的这个esi究竟是什么函数
u esi
补充:nt! 是什么意思
ntfs 是什么意思
6、R
命令显示和修改寄存器上的值
7、D
da
显示ascii码
dc
按单字节显示字符
db
按单字节显示
dd
按4字节显示
dD
按8字节显示(64位下常用)
df
按浮点显示
dp
按4字节或者8字节显示(取决于是32位系统还是64位系统)
dw
按2字节显示
dW
按2字节显示字符
dyb
按二进制位显示(一字节一组)
dyd
按二进制位显示(4字节一组)
8、 lmf
列出当前进程中加载的所有dll文件和对应的路径
9、 lmf!address eax
查看对应内存页的属性
10、 vertarget
显示当前进程的大致信息
11、 !peb
显示process Environment Block
12、 lmvm
查看任意一个dll的详细信息
13、 E
命令可以用来修改内存地址
跟d命令一样,e命令后面也可以跟类型后缀,比如ed命
14、 k
命令用来显示当前线程的堆栈,如下
跟d命令一样,k后面也可以跟很多后缀,比如kb kp,kn,kv,kl等,这些后缀控制了显示的格式和信息。
KB显示三个参数;
Kp显示所有的参数,但需要Full Symbols或Private PDBSymbols支持。KP与Kp相似,只是KP将参数换行显示了;
Kv用于显示FPO和调用约定;
KD,用于显示Stack的Dump,在跟踪栈时比较有用。
这些指令区分大小。
15、 X
查找符号的二进制地址如下
希望大家可以有所收获,主要用于平时的指令记录(持续更新)。