在程序中设置读、写、执行的硬件断点

作者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个位对应一个寄存器,用来定义断点合适被触发:
00b - 代码执行时触发

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

posted @   Binhua Liu  阅读(6812)  评论(4编辑  收藏  举报
编辑推荐:
· 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框架的用法!
点击右上角即可分享
微信分享提示