[调试器的实现<控制台版>]第三章 硬件断点实现
1.相关函数,相关结构,与主要成员
//硬件断点处理部分 public: //硬件断点设置 void SetHardWarePoint(DWORD SetAddress, int DR, int PointType, int nLen = 1); //硬件DR0 void SetDR0HardWarePoint(int PointType, int nLen); //硬件DR1 void SetDR1HardWarePoint(int PointType, int nLen); //硬件DR2 void SetDR2HardWarePoint(int PointType, int nLen); //硬件DR3 void SetDR3HardWarePoint(int PointType, int nLen); //硬件写 void HardWareWrite(DWORD WriteAddress, int nLen); //硬件读或写 void HardWareReadWrite(DWORD ReadAddress,int nLen); //硬件执行 void HardWareExecute(DWORD ExecuteAddress); //硬件断点处理事件 void DebughardWareProc(); //释放设置的硬件标志 void DelHWBPointFlag(int nChoise); //硬件断点处理标记 struct HareWareFlag { BOOL DR0; //当前寄存器使用状态 BOOL DR1; BOOL DR2; BOOL DR3; HareWareFlag() { DR0 = FALSE; DR1 = FALSE; DR2 = FALSE; DR3 = FALSE; } };
2.设计思路
硬件调试寄存器DR0-DR3, 将用户下断地址赋给空闲的调试寄存器。并设置好DR7中位的数值。当命中硬件执行断点,在单步中,先取消掉这个硬件执行断点,设置单步,然后执行程序,进入单步后再重新设置这个硬件执行断点。
当设置硬件断点时,通过对DR7进行相应取值即可设置成功。
3.删除硬件断点
在删除硬件断点时,同样通过对DR7进行赋值可达到删除断点的效果。
DR7赋值:
DR0 &= 0xfffffffe; DR1 &= 0xfffffffb
DR2 &= 0xffffffef; DR3 &= 0xffffffbf
4.图片资料部分详解: <DR6和DR7寄存器>
LE和GE:
P6 family和之后的IA32处理器都不支持这两位。当设置时,使得处理器会检测触发数据断点的精确的指令。当其中一个被设置的时候,处理器
会放慢执行速度,这样当命令执行的时候可以通知这些数据断点。建议在设置数据断点是需要设置其中一个。切换任务时LE会被清除而GE不会被清除。为了兼容
性,Intel建议使用精确断点时把LE和GE都设置为1。
LEN0到LEN3
指定在调试地址寄存器DR0到DR3中指定的地址位置的大小。如果R/Wx位为0,则LENx位也必须为0,否则会产生不确定的行为。
可能取值:
00 1字节
01 2字节
10 保留
11 4字节
R/W0到R/W3
指定各个断点的触发条件。它们对应于DR0到DR3中的地址以及DR6中的4个断点条件标志。
00 只执行
01 写入数据断点
10 I/O端口断点(只用于pentium+,需设置CR4的DE位,DE是CR4的第3位 )
11 读或写数据断点
调试状态寄存器Dr6
该寄存器用于表示进入陷阱1的原因,各个位的含义如下:
B0~B3,如果其中任何一个位置位,则表示是相应的Dr0~3断点引发的调试陷阱
注: 硬件断点为永久断点!