在程序中设置读、写、执行的硬件断点
作者Michael Chourdakis, 翻译Binhua Liu
下载源代码 –56.1KB
简介
我是基于以下理由决定写一篇关于硬件断点的文章的:
1,Visual C++只支持硬件写断点,而你可能需要在数据读取时触发断点。
2,或许你用的不是Visual C++,而你的调试器使用的是一些速度很慢的基于软件的断点机制。
3,你可能希望能程序中设置和移除断点。
4,或许你对CPU的底层机制感兴趣。
特性
支持x86和x64平台
支持为每个线程设置4个硬件断点
调试寄存器
x86/x64包括一组调试寄存器:DR0,DR1,DR2,DR3,DR6和DR7. 这些寄存器在32位模式下为32-bit, 64位模式下为64-bit. 其中DR0,DR1,DR2和DR3包含断点的线性地址, DR7包含的位解释如下:
位 | 功能 |
0-7 | 4个调试寄存器的标志位(每2个位对应一个寄存器).第一个标志位指定是否是一个本地断点(local breakpoint)(CPU在切换任务时重设该标志位),第二个标志位指定是否是一个全局断点(global breakpoint).在Windows平台,你只能使用第一个标志位(虽然我没有试过第二个). |
16-23 | 每2个位对应一个寄存器,用来定义断点合适被触发: 01b - 数据写入时触发 10b - 保留 11b - 数据读写时触发 |
24-31 | 每2个位对应一个寄存器,定义断点的大小 00b - 1字节 01b - 2字节 10b - 8字节 11b - 4字节 |
我们使用SetThreadContext来为线程设置断点. 之后,一旦断点被触发, 将产生一个单步异常EXCEPTION_SINGLE_STEP.
设置断点
见附件中的源代码:
1 | HANDLE SetHardwareBreakpoint( HANDLE hThread,HWBRK_TYPE Type,HWBRK_SIZE Size, void * s); |
hThread
- 被设置断点的线程的句柄
Type - 断点类型:
- HWBRK_TYPE_CODE
- HWBRK_TYPE_READWRITE
- HWBRK_TYPE_WRITE
Size - 断点的大小(Size)
- HWBRK_SIZE_1
- HWBRK_SIZE_2
- HWBRK_SIZE_4
- HWBRK_SIZE_8
addr - 设置断点的地址
该函数返回断点的句柄, 在 RemoveHardwareBreakpoint中被使用. 如果返回的是0,则表示
1,你不能访问这个线程
2,你已经在这个线程上设置了最大数量的断点(4个)
移除断点
1 | bool RemoveHardwareBreakpoint( HANDLE hBrk); |
移除断点,如果成功,返回true
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int __stdcall WinMain( HINSTANCE , HINSTANCE , LPSTR , int ) { char c1[100] = {0}; lstrcpyA(c1, "Hello 1" ); HANDLE hX1 = 0; hX1 = SetHardwareBreakpoint(GetCurrentThread(), HWBRK_TYPE_READWRITE,HWBRK_SIZE_4,c1); __try { volatile char a1 = c1[2]; // To ensure that it won't be optimized out. } __except(GetExceptionCode() == STATUS_SINGLE_STEP) { MessageBoxA(0, "Breakpoint hit!" ,0,MB_OK); } RemoveHardwareBreakpoint(hX1); return 0; } |
期待你们的评论和问题!
历史
本文写于2008/7/24
作者 Michael Chourdakis . http://www.turboirc.com
Binhua Liu 翻译于2011/7/21. 原文链接http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!