windbg 命令收集
文章目录
windbg的命令非常多. 有很多漂亮的命令, 用一次以后突然会忘记. 还是记下来比较合适啊.
符号相关:
!sym noisy :开启符号打印. 这样符号加载的信息显示就非常多了
查看pe信息
!dh [Options] Address : 查看模块pe信息 !dh -f : display file headers !dh -s : section headers !dh -a : all header informations !verifier:查看Verifier 检测统计信息
监视窗口:
@@(poi(0ffb6bae0))
显示0ffb6bae0指向的值. 具体可以参照windbg的命令语法写一个很复杂的命令.
@@(eax)
监视器窗口添加eax的值
@$peb @$teb @$ip
监视窗口添加peb teb eip的值
@$proc
监视窗口添加 eprocess的结构信息
条件断点:
bp kernel32!CreateFileW+0x5 “dU /c 50 poi(@ebp+8) ;gc”
断在CreateFileW, 然后打印第一个参数. 也就是文件名称了还可以这样
bp kernel32!OpenFileMappingW+5 “kv 10;dU /c 30 poi(@ebp+10)”
更可以这样
bp kernel32!CreateFileW+0x5 “dU /c 50 poi(@ebp+8) ;gu; r eax; gc”
更牛逼的是这样, 加个判断
bp kernel32!CreateFileW+0x5 “dU /c 50 poi(@ebp+8) ;gu; r eax; .if (@eax < 0 ) {.echo hit }.else{gc}”
字符串条件断点(OllyDbg):
使用快捷键:Shift+F2设置条件断点,在条件中输入。
ASCII字符集字符串设置方法:
代码:
STRING [eax] == ”DDLX_CHAR” STRING [eax] == ”DDLX_char” //不区分大小写 STRING [eax] == ”DDLX” //不区分文本长度
UNICODE字符集字符串设置方法:
代码:
UNICODE [eax] == ”DDLX_WCHAR”
UNICODE [eax] == ”DDLX_wchar” //不区分大小写
UNICODE [eax] == ”DDLX” //不区分文本长度
字符串条件断点(Windbg):
//全字符串匹配,区分大小写 bp 0041141d ”r @$t1 = eax; as /ma ${/v:pzString} $t1;.if ($scmp(\”${pzString}\”,\“DDLX_CHAR\”)==0) {} .else {gc}”
//全字符串匹配,不区分大小写 bp 0041141d ”r @$t1 = eax; as /ma ${/v:pzString} $t1;.if ($sicmp(\”${pzString}\”,\“DDLX_char\”)==0) {} .else {gc}”
//字符串还可以模糊匹配,*表示0-?个模糊字符 bp 0041141d ”r @$t1 = eax; as /ma ${/v:pzString} $t1;.if ($spat(\”${pzString}\”,\“DDLX*\”)==0) {} .else {gc}”
UNICODE字符集字符串设置方法:
bp 0041141d “r @$t1 = eax; as /mu ${/v:pzString} $t1;.if ($scmp(\”${pzString}\”,\“DDLX_WCHAR\”)==0) {} .else {gc}”
可以看到, 就是一个/mu /ma的区别. 看看windbg的帮助, 发现还有很多其他样式可供选择.
打印线程堆栈, 线程LastError值
~*e ? @$tid;!gle
~*e ? @$tid;kv
~* k( ~* kv ) 打印所有线程堆栈
显示进程中每个线程的的iD和LastError值.
过滤命令窗口输出信息
.prompt_allow 设置单步过程中,是否显示一些附带信息,通过+/-控制。 dis 反汇编当前指令 ea 当前指令地址 reg 寄存器 src 源代码行中位置 sym 符号 例如关闭所有单步过程中的显示,可以输入.prompt_allow –dis –ea –reg –src -sym特别地,你可以通过rm指令来设置显示哪些寄存器,你可以通过rm ?来显示可以设置的值。 1 32位寄存器 2 64位寄存器,如果支持 4 浮点寄存器 8 段寄存器 10 MMX寄存器 20 Debug 寄存器,如果在内核模式,还能显示CR类的寄存器 40 SSE XMM 寄存器 如果需要同时显示几类寄存器,只要把对应的数字加起来就可以了,例如你希望同时显示MMX寄存器和SSE XMM寄存器,你可以输入rm 50
异常处理相关
有 sx, sxd, sxe, sxi, sxn, sxr 几条命令可用来设置异常和事件的处理方式。比如:
0:000> sxe ld
可以在加载 dll 时中断下来。
调试运行相关: gn 强制返回已经处理了异常 gh 跳过异常处理使用程序自带的异常处理. ba 硬件断点 dl 遍历链表 如 dl nt!PsActiveProcessHead 1000 dt -r3 nt!_KPCR 显示结构遍历3层. .call 调用目标程序的函数.
进程线程相关
.dml_start 以DML的方式显示一些自定义功能,默认情况下会显示各类命令帮助已经关于调试进程的一些基本信息。DML命令在命令浏览窗口将会得到更好的支持。你能使用CTRL+N打开该窗口并使用此指令 !dml_proc 也用来显示进程信息,不带参数时直接显示进程列表,比!process 0 0 命 令显示的格式要紧凑好看点, 是一条霸气侧漏的语句 !thread 列出当前线程信息
!cs 显示互斥量信息 .thread 地址 切换到某个线程
内存命令
!address 命令显示内存信息,如内存范围、内存权限等。 !vm 标号 命令显示虚拟内存信息 !memusage 命令显示物理内存信息 !pte 命令显示指定地址对应的页表项(PTE)和页目录项(PDE)。 !pfn 命令显示物理内存页的详细信息,指定页面帧编号为参数 !db/!eb 命令用来显示、修改物理内存,类似的还有!dd/!dc/!dq/!ed 等 !vprot address 显示某个地址所在的模块属性.
lm 列出模块信息.
lm m kern* 查找kern开头的模块信息.
lmf 显示模块的具体路径
lmv 显示模块的具体信息
写代码的时候记得列出标号是多么重要
!pool 命令显示内核内存池信息 !poolused 命令按照内存池 Tag 显示内存池信息。 !poolfind 命令显示所有指定 Tag 的内存信息
对象相关命令 !handle 命令显示句柄信息,包括句柄类型、句柄引用计数、句柄名等 !object 命令显示对象信息。 !object xxxxxxx 命令显示指定对象的信息,xxxxxxxx 表示对象地址 !drvobj 命令显示驱动信息,主要是显示 DRIVER_OBJECT 结构的信息 !devobj 命令显示驱动设备信息,主要是显示 DEVICE_OBJECT 结构信息。
蓝屏Dump相关命令 !analyze -v 命令是分析蓝屏 dump 时首先应该执行的命令,该命令会显示蓝屏原因、蓝屏上下文等,并会根据 蓝屏原因自动进行相关的分析,给出进一步分析的建议。
.ecxr 命令会回到异常产生的地方.
查看目标机(底层相关命令)
vertarget 命令可以显示目标系统的基本信息,如系统版本、计算机名、内核基址等 dg 命令主要显示选择子的详细信息 !cpuinfo 命令显示CPU 信息 !pcr 命令显示处理器控制域(Processor Control Region)信息,也就是KPCR 结构信息,每个CPU 对应一个KPCR 结构,可以在命令中指定需要显示的CPU 序号,不指定则显示当前CPU 的PCR 信息。
!prcb 命令显示处理器控制块(Processor Control Block)信息,也就是KPRCB 结构信息,同样,每个CPU对应一个KPRCB 结构,该结构紧接在KPCR 结 构后面,由KPCB 结构中的PrcbData 表示。命令中可以指定CPU 序号。 !idt 命令显示中断服务表,可以指定中断号显示,也可以显示全部的中断服务表 !irql 命令显示目标系统中断到WinDbg 时的中断请求级(IRQL),在 Windows2003 及以后的系统上可用,调试和IRQL 相关的程序时可能会用 !running 命令显示所有CPU 上正在运行的线程信息,便于了解系统当前的情况,如果 是分析蓝屏文件,则可以 看到蓝屏时系统正在执行什么线程。 !gflag 命令显示、设置系统全局标志,用于控制系统行为,和WinDbg 自带的gflags.exe 工具类似,不过设置 后只对当前调试会话有效。
句柄泄漏查找:
1)找到windbgs安装目录下的gflags.exe工具,该工具可用来打开windows自带的一些调试选项,具体gflags.exe的详细使用可以查看windbg帮助;这里我们设置勾上application verifiwer,该工具主要可用来对程序做一些稳定性的检测,本次调试主要用于保存栈的相关信息。同时设置stackbacktrace即栈的大小为10.
2)运行windbg,打开第一步编译的程序,并使其跑起来;此时你查看任务管理器中的句柄信息,会发行相应进程句柄一直在增加。
3)windbg用ctrl+break命令中断进程运行,用!htrace -enable命令开启句柄检测;htrace提供了进行句柄相关检测的命令,可查看windbg帮助。
4)再次中断进程,使用!htrace -snapshot命令,获得此时进程句柄的镜像。并再次让程序运行。
5)第三次中断进程运行,我们再使用!htrace -diff命令获得当前句柄状态与第4步 snapshot镜像句柄的差异;
6)我们使用lsa 传递指定位置对应的代码,lsa handlew2!fun4+0x0000002e
到这里,我们就找到了泄露句柄的函数,真是神奇啊。
文章作者 忆杰
上次更新 2014-02-05