windbg条件断点总结
1 . 条件断点是断点命令 ( bp 或者 bu ) 与j命令或者.if命令一起使用的,后面跟着一个gc命令
0:000> bp Address "j (Condition) 'OptionalCommands'; 'gc' "
0:000> bp Address ".if (Condition) {OptionalCommands} .else {gc}"
2. 这里说下j命令,j命令的语法如下, 这里的Expression是表达式,通过计算表达式的值,TRUE就指向Command1, FALSE指向Command2
j Expression Command1 ; Command2
j Expression 'Command1' ; 'Command2'
这里也可以使用多个命令,多个命令用单引号' ' 包含,并且用分号 ; 分隔开, 如果命令字符串有一个,那么单引号也可以省略
Command2后面不能添加额外的命令或者增加多余的分号,就算你添加了,Command2分号后面的值也会被忽略
0:000> j (MySymbol=0) 'r eax'; 'r ebx; r ecx' 如果MySymbol为0,执行r eax, 否则执行r ebx r ecx
你可以省略在r eax附加的单引号,如果你想忽略命令,就直接使用空格来作为标记
0:000> j (MySymbol=0) ''; 'r ebx; r ecx'
0:000> j (MySymbol=0) ; 'r ebx; r ecx'
你也可以在其他命令中使用j命令,比如,你可以使用j命令来创建一个条件断点
0:000> bp `mysource.cpp:143` "j (poi(MyVar)>0n20) ''; 'gc' "
3. 这里俩说说z命令 z (Execute While), 当条件成立时,z命令会执行一个命令
User-Mode
Command ; z( Expression )
Kernel-Mode
Command ; [Processor] z( Expression )
Command: 当表达式条件为真的时候,命令最少执行一次
在许多调试器命令中,分号都是用于分割不相关的命令,在z命令中,分号从命令参数中分割Z命令
Command命令总是至少执行一次,当表达式检测到非零时,命令再次被执行,然后表达式再次被检测,这个行为类似于C语言的do-while循环,并不是简单的while循环
如果"z"左侧有很多分号分开的命令,那么当表达式为真的时候,z左侧所有的命令都将被执行
如果z之后添加其他分号和额外的命令,这些额外的命令将会在lopp完成后执行,但是通常不建议这样做, 因为他会产生无意义的输出
除非因为其他行为表达式变成FALSE
注意,你可以嵌套Z命令
下面的代码展示一中eax寄存器清零的方法
0:000> reax = eax - 1 ; z(eax)
下面的代码展示了eax和ebx寄存器递增,直到他们中的一个至少是8,然后ecx寄存器+1
0:000> reax=eax+1; rebx=ebx+1; z((eax<8)|(ebx<8)); recx=ecx+1 (来这里理解成do-while 更容易理解)
下面例子使用C++表达式语法,然后使用$t0为寄存器作为循环变量
0:000> .expr /s c++
Current expression evaluator: C++ - C++ source expressions
db pindexcreate[@$t0].szKey; r$t0=@t0+1; z( @$t0 < cIndexCreate )
4. 这里说说.if 标记(token)
.if (Condition) { Commands }
.if (Condition) { Commands } .else { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands }
.if (Condition) { Commands } .elsif (Condition) { Commands } .else { Commands }
Condition: 如果条件计算后值为0的话,就作为false,否则作为true, 括号中的条件是可选的,条件必须是表达式,不能是调试器命令,它将被MASM或者C++语法计算
Commands:按条件执行一个或多个命令,命令块需要包括在大括号中,即使里面只有一个命令,多个命令应该由分号分隔开,但是最后一个命令则不需要用分号
5. 这里说说gc命令( Go from Conditional Breakpoint )
gc命令从条件断点中恢复执行,与命中断点的方法相同
当一个条件断点的末尾包含一个执行命令的时候,这应该是gc命令
0:000> bp Address "j (Condition) 'OptionalCommands'; 'gc' "
当表达式为FALSE,并且遇到断点的话,将使用与上次相同的类型继续执行,比如你用g命令遇到了这个断点,将恢复执行,但是当你单步到这里的时候,gc将以单步的方式恢复执行
另外,下面是个不正确的断点公式,将总是恢复执行,即使你在遇到断点前正在单步
0:000> bp Address "j (Condition) 'OptionalCommands'; 'g' "
6. 使用J命令的条件断点的基本语法如下:
0:000> bp Address "j (Condition) 'OptionalCommands'; 'gc' "
使用.if标记的条件断点的语法如下:
0:000> bp Address ".if (Condition) {OptionalCommands} .else {gc}"
下面的命令设置了一个断点在Mysourc.dpp文件的143行,当触发这个断点后,会检测MyVar这个变量,如果这个变量小于等于20,就继续执行,如果大于20,就停止执行
0:000> bp `mysource.cpp:143` "j (poi(MyVar)>0n20) ' '; 'gc' "
0:000> bp `mysource.cpp:143` ".if (poi(MyVar)>0n20) {} .else {gc}"
这里解释一波
bp命令是设置断点,即使上面这两个例子使用的是bp,你仍然可以用bu命令
源文件和行数是用~指定的
当断点触发后,双引号" "中的命令将被执行,上面的例子中,命令是j命令或者.if标记,在括号中测试表达式
在源程序中,MyVar是一个整数,如果你使用C++语法,MyVar将作为一个整数,在这个例子中( 已经默认的调试器配置中 )使用MASM表达式语法,
在MASM表达式中,MyVar被作为一个地址,因此你需要poi操作符来解引用它
如果你的变量是一个C指针,那么你需要解引用两次,像这样poi(poi(MyPtr)), 0n前缀,代表这是个10进制
括号中的表达式后面跟着两个命令,j命令后面的是单引号' '保护,.if标记后面是尖括号{ }包含,如果表达式为真的话,第一个命令被执行,
在上面的 例子中,第一个命令为空,因为不会执行命令,并且将控制交给调试器,如果括号中的表达式为FALSE,则第二个命令将被执行
第二个命令应该尽量使用gc,因为这个命令会恢复执行,与上次触发断点前的方式一样( 单步,步进,自由执行 )
如果要在每次传递断点或最终命中时看到消息, 可以在单引号或大括号中使用其他命令。例如:
0:000> bp `:143` "j (poi(MyVar)>5) '.echo MyVar Too Big'; '.echo MyVar Acceptable; gc' "
0:000> bp `:143` ".if (poi(MyVar)>5) {.echo MyVar Too Big} .else {.echo MyVar Acceptable; gc} "
这些注释是很重要的,如果你有几个断点,同时触发,调试器并不会显示哪个断点命中
7. 条件断点和寄存器符号扩展
你可以设置条件断点在寄存器值上面,下面的命令将断在myFunction函数的开始处,如果EAX寄存器等于0xA3
0:000> bp mydriver!myFunction "j @eax = 0xa3 '';'gc'"
0:000> bp mydriver!myFunction ".if @eax = 0xa3 {} .else {gc}"
注意,下面类似的命令并不一定会中断,当eax等于0xC0004321的时候
0:000> bp mydriver!myFunction "j @eax = 0xc0004321 '';'gc'"
0:000> bp mydriver!myFunction ".if @eax = 0xc0004321 {} .else {gc}"
上面的命令会失败,因为MASM表达式计算的符号扩展寄存器的高位为1,当eax的值为0xC0004321的时候,它将被作为0xFFFFFFFF~C0004321,
但是并不是在用户模式,因此前面的命令在用户模式下,将无法正常工作,如果你屏蔽了eax的高位,命令将在内核模式下正常工作,但是现在,他在用户模式将会失败
为了让你的命令在用户和内核模式下正常工作,在上面的命令中,你应该屏蔽高32位,通过AND操作符与运算0x00000000~FFFFFFFF
0:000> bp mydriver!myFunction "j (@eax & 0x0`ffffffff) = 0x0`c0004321 '';'gc'"
0:000> bp mydriver!myFunction ".if (@eax & 0x0`ffffffff) = 0x0`c0004321 {} .else {gc}"
8. 条件断点的局限
如果你从内核调试器控制用户态调试器,则不能使用条件断点或其他任何断点命令,比如gc命令 ,g命令,如果使用这些命令, 则串行接口可能无法保持断点的数量, 并且您将无法中断回CDB中
windbg条件断点总结的更多相关文章
- Windbg 字符串条件断点
0x01 前言 Windbg 作为 Windows 下的主流调试器,除了人机交互相比其他调试器略有不足外,其他功能都是十分强大的存在. 在所有的调试器中断点功能都是必不可少的,Windbg 可以使用 ...
- Windbg:如何给字符串下条件断点
因为Windgb支持MASM语法,字符串的比较方法有$scmp和$sicmp.用法和c中的字符串比较方法一致.在需要比较字符串成员变量的时候,遇到了点问题.因为字符串成员变量无法直接获取字符串内容.p ...
- Windbg 实践之结合条件断点
Case 1 1.bu USER32!PostMessageW "r $t0=@$t0+1;.printf\"PostMessageW Call Count:%d\",@ ...
- Windbg使用简明指南
第一章 准备 1.1. 环境配置 _NT_DEBUGGER_EXTENSION_PATH=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 _NT_SY ...
- 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令
调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令 调试SQLSERVER (一)生成dump文件的方法调试SQLSERVER (二)使用Windbg调试SQLSERVER ...
- GDB 和 windbg 命令对照(转载)
From:http://blog.csdn.net/joeleechj/article/details/10020501 命令 ...
- windbg学习进阶之——dump分析常用命令收集
#重要说明 (1) windbg命令分为标准命令,元命令和扩展命令. 标准命令提供最基本的调试功能,不区分大小写.如:bp g dt dv k等 元命令提供标准命令没有提供的功能,也内建在调试 ...
- windbg常见命令
WinDbg WinDbg支持以下三种类型的命令: · 常规命令,用来调试进程 · 点命令,用来控制调试器 · 扩展命令,可以添加叫WinDbg的自定义命令, ...
- WinDbg调试命令汇总
一. 1. !address eax 查看对应内存页的属性 2. vertarget 显示当前进程的大致信息 3 !peb 显示process Environment Block 4. lmvm 可以 ...
随机推荐
- 继承and派生
1.什么是继承?(python2与python3) 在程序中继承是一种新建子类的方式,新创建的类称之为子类\派生类,被继承 的类称之为父类\基类\超类 继承描述的是一种遗传关系,儿子可以重用爹的属性 ...
- Day10作业及默写
1,继续整理函数相关知识点,写博客. 2,写函数,接收n个数字,求这些参数数字的和.(动态传参) def func(*number): sum=0 for num in number: sum+=nu ...
- sqlite的数据类型
参考sqlite官方文档:https://www.sqlite.org/datatype3.html 绝大多数的SQL数据库采用静态的.严格的数据类型,数据库中的值由数据表的列类型定义决定. 然而,s ...
- Spring Boot 揭秘与实战(五) 服务器篇 - 其他内嵌服务器 发表于 2017-01-03 | Spring框架 | Spri
文章目录 1. Jetty 的切换 2. Undertow的使用 Spring Boot 可选择内嵌 Tomcat.Jetty 和 Undertow,因此我们不需要以 war 包形式部署项目.< ...
- 2.24 js处理内嵌div滚动条
2.24 js处理内嵌div滚动条 前言 前面有篇专门用js解决了浏览器滚动条的问题,生活总是多姿多彩,有的滚动条就在页面上,这时候又得仰仗js大哥来解决啦.一.内嵌滚动条 1.下面这张图 ...
- kafka definitive guide - reading notes
一.认识Kafka 1)什么是sub/pub模型, 发布订阅模型 Publish/subscribe messaging is a pattern that is characterized by ...
- Vim正则表达式匹配替换字符串
/********************************************************************** * Vim正则表达式匹配替换字符串 * 说明: * 用V ...
- 服务器安装wordpress,搭建自己的博客平台
自己构造网站的话,建立一个简单的网页还可以(比如,yongjieshi.com),对于建立复杂的博客就需要借助第三方的工具,常见的有wordpress,在阿里云上安装wordpress,我主要参考了这 ...
- Nginx访问日志、 Nginx日志切割、静态文件不记录日志和过期时间
1.Nginx访问日志 配制访问日志:默认定义格式: log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_loc ...
- .net core 微服务架构-docker的部署-包括网关服务(Ocelot)+认证服务(IdentityServer4)+应用服务(asp.net core web api)
本文主要介绍通过Docker来部署通过.Net Core开发的微服务架构,部署的微服务主要包括统一网关(使用Ocelot开发).统一认证(IdentityServer4).应用服务(asp.net c ...