windbg设置条件断点
2016-07-28 22:35
260 查看
一直以为windbg的bp断点只是简单的在某个地址上下断点,后来才发现bp断点功能很强大:除了可以设置条件断点还是windbg脚本的基础.
使用方法很简单:bp address ".if(condition){};.else{}" 具体例子形如:bp `4dbg.cpp:18` ".if(hFile>=0){};.else{gc;}"这里是对源文件中某一行下条件断点,如果句柄值大于等于0则中断调试器,否则继续往下运行。岔开一下对源码下断点的方式为: bp `filename:linenumber` (首尾那模糊的两点是波浪键那一点).
如果条件断点中使用了别名(什么是别名?点此链接) 需要注意一下两点:
1.必须使用.block{}把使用别名的包含在里面;
2.必须在使用别名前,先用ad命令把别名删除掉;
下面用一段代码示例条件断点的用法:
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwReturn;
char* Buffer[]={"123","456","789"};
HANDLE hFile=CreateFile("C:\\a.txt",
GENERIC_WRITE|GENERIC_READ,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
for(int i=0;i<3;i++)
{
WriteFile(hFile,Buffer[i],strlen(Buffer[i]),&dwReturn,NULL);
}
CloseHandle(hFile);
return 0;
}我想在这段代码中设置这样两个断点:
1.CreateFile是否成功打开文件,即hFile是否大于0,若成功,则断下,否则继续运行(从return 0退出程序),这个断点可以这样设置:
bp `4dbg.cpp:12` ".if(hFile>=0){};.else{gc;}"2.想获得调用WriteFile时,第二个参数的内容,并且如果传入的字符串和456匹配,则中断调试器运行,可以这么写(有点复杂):
bp kernel32!WriteFile "
r @$t1=poi(esp+8);
ad *;
as /ma $buf @$t1;
.block
{
r @$t2=$spat(@\"$buf\",@\"456\")
.if(@$t2==0)
{
gc;
}
}
"大概解释一下:
poi(esp+8)是从栈变量中取值,将值作为地址返回给调用者,这里是一个临时变量。
当程序执行call kernel32!WriteFile进入kernel32!WriteFileImplementation时,esp+8指向传给函数的第二个参数:
4dbg!main+0xa3:
01251443 ff15ac812501 call dword ptr [4dbg!_imp__WriteFile (012581ac)] ds:0023:012581ac={kernel32!WriteFileImplementation (769a55a6)}
0:000> t
kernel32!WriteFileImplementation:
769a55a6 8bff mov edi,edi
0:000> dd esp+8
002bfa24 0125574c 00000003 002bfb30 00000000esp+8在此处就是栈变量,变量地址为0x002bfa24;他的值为0125574c,是字符串的首地址:
参考资料:
windbg 脚本简单入门
46.windbg-条件断点(windbg script)
使用方法很简单:bp address ".if(condition){};.else{}" 具体例子形如:bp `4dbg.cpp:18` ".if(hFile>=0){};.else{gc;}"这里是对源文件中某一行下条件断点,如果句柄值大于等于0则中断调试器,否则继续往下运行。岔开一下对源码下断点的方式为: bp `filename:linenumber` (首尾那模糊的两点是波浪键那一点).
如果条件断点中使用了别名(什么是别名?点此链接) 需要注意一下两点:
1.必须使用.block{}把使用别名的包含在里面;
2.必须在使用别名前,先用ad命令把别名删除掉;
下面用一段代码示例条件断点的用法:
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwReturn;
char* Buffer[]={"123","456","789"};
HANDLE hFile=CreateFile("C:\\a.txt",
GENERIC_WRITE|GENERIC_READ,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
for(int i=0;i<3;i++)
{
WriteFile(hFile,Buffer[i],strlen(Buffer[i]),&dwReturn,NULL);
}
CloseHandle(hFile);
return 0;
}我想在这段代码中设置这样两个断点:
1.CreateFile是否成功打开文件,即hFile是否大于0,若成功,则断下,否则继续运行(从return 0退出程序),这个断点可以这样设置:
bp `4dbg.cpp:12` ".if(hFile>=0){};.else{gc;}"2.想获得调用WriteFile时,第二个参数的内容,并且如果传入的字符串和456匹配,则中断调试器运行,可以这么写(有点复杂):
bp kernel32!WriteFile "
r @$t1=poi(esp+8);
ad *;
as /ma $buf @$t1;
.block
{
r @$t2=$spat(@\"$buf\",@\"456\")
.if(@$t2==0)
{
gc;
}
}
"大概解释一下:
poi(esp+8)是从栈变量中取值,将值作为地址返回给调用者,这里是一个临时变量。
当程序执行call kernel32!WriteFile进入kernel32!WriteFileImplementation时,esp+8指向传给函数的第二个参数:
4dbg!main+0xa3:
01251443 ff15ac812501 call dword ptr [4dbg!_imp__WriteFile (012581ac)] ds:0023:012581ac={kernel32!WriteFileImplementation (769a55a6)}
0:000> t
kernel32!WriteFileImplementation:
769a55a6 8bff mov edi,edi
0:000> dd esp+8
002bfa24 0125574c 00000003 002bfb30 00000000esp+8在此处就是栈变量,变量地址为0x002bfa24;他的值为0125574c,是字符串的首地址:
0:000> da 0125574c 0125574c "123"随后,为字符串的首地址(保存在临时变量t1)取一个别名,并在block中进行字符串匹配,匹配的结果存放在临时变量t2中。最后比较t2的值
参考资料:
windbg 脚本简单入门
46.windbg-条件断点(windbg script)
相关文章推荐
- Linux 自检和 SystemTap
- Python 七步捉虫法
- 路由器的配置与调试
- 对于技术人员的出现了运行时间错误,是否要进行调试的解决方法
- C++软件添加dump调试打印日志(推荐)
- 在ASP.NET 2.0中操作数据之七十二:调试存储过程
- 讲解WordPress开发中一些常用的debug技巧
- 必备的JS调试技巧汇总
- JavaScript程序设计之JS调试
- 可以用来调试JavaScript错误的解决方案
- 如何调试异步加载页面里包含的js文件
- jQuery下的Ajax调试步骤
- 调试一段PHP程序时遇到的三个问题
- JavaScript高级程序设计 错误处理与调试学习笔记
- Javascript调试脚本的经验之谈第1/2页
- 在IE,Firefox,Safari,Chrome,Opera浏览器上调试javascript
- Android App调试内存泄露之Cursor篇
- Lua的编译、执行和调试技术介绍
- 解决Visual Studio 2012 Update 4 RC启动调试失败的方案
- PHPStorm+XDebug进行调试图文教程