实现硬件断点,起主要获取当火线程环境
//获取线程环境CONTEXT g_Context = { 0 };g_Context.ContextFlags = CONTEXT_CONTROL;GetThreadContext(hThread, &g_Context);在CONTEXT布局体中,存放了诸多当火线程环境的信息,以下是从winnt.h文件中找到的CONTEXT布局体
typedef struct _CONTEXT { // // The flags values within this flag control the contents of // a CONTEXT record. // // If the context record is used as an input parameter, then // for each portion of the context record controlled by a flag // whose value is set, it is assumed that that portion of the // context record contains valid context. If the context record // is being used to modify a threads context, then only that // portion of the threads context will be modified. // // If the context record is used as an IN OUT parameter to capture // the context of a thread, then only those portions of the thread's // context corresponding to set flags will be returned. // // The context record is never used as an OUT only parameter. // DWORD ContextFlags; // // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT // included in CONTEXT_FULL. // DWORD Dr0; DWORD Dr1; DWORD Dr2; DWORD Dr3; DWORD Dr6; DWORD Dr7; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_FLOATING_POINT. // FLOATING_SAVE_AREA FloatSave; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_SEGMENTS. // DWORD SegGs; DWORD SegFs; DWORD SegEs; DWORD SegDs; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_INTEGER. // DWORD Edi; DWORD Esi; DWORD Ebx; DWORD Edx; DWORD Ecx; DWORD Eax; // // This section is specified/returned if the // ContextFlags word contians the flag CONTEXT_CONTROL. // DWORD Ebp; DWORD Eip; DWORD SegCs; // MUST BE SANITIZED DWORD EFlags; // MUST BE SANITIZED DWORD Esp; DWORD SegSs; // // This section is specified/returned if the ContextFlags word // contains the flag CONTEXT_EXTENDED_REGISTERS. // The format and contexts are processor specific // BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];} CONTEXT;从CONTEXT布局体中我们可以看到存放了调试寄存器 Dr0-Dr3和Dr6、Dr7,通过设置这些寄存器我们可以实现硬件断点。
已经获取了当火线程环境,接下来就是设置调试寄存器
//传入下断点的地址、范例、长度void SetHardBP(DWORD addr, BreakPointHard type, BreakPointLen len){ //利用上文中的DR7寄存器位段信息 DBG_REG7 *pDr7 = (DBG_REG7 *)&g_Context.Dr7; if (len == 1) { //两字节的对齐粒度 addr = addr - addr % 2; } else if (len == 3) { //四字节的对齐粒度 addr = addr - addr % 4; } if (pDr7->L0 == 0) { g_Context.Dr0 = addr; //利用Dr0寄存器存放地址 pDr7->RW0 = type; //Dr7寄存器中的RW0设置范例 pDr7->LEN0 = len; //Dr7寄存器中的LEN0设置长度 pDr7->L0 = 1; //Dr7寄存器中的L0启用断点 } else if (pDr7->L1 == 0) { g_Context.Dr1 = addr; pDr7->RW1 = type; pDr7->LEN1 = len; pDr7->L1 = 1; } else if (pDr7->L2 == 0) { g_Context.Dr2 = addr; pDr7->RW2 = type; pDr7->LEN2 = len; pDr7->L2 = 1; } else if (pDr7->L3 == 0) { g_Context.Dr3 = addr; pDr7->RW3 = type; pDr7->LEN3 = len; pDr7->L3 = 1; }}调试寄存器的信息设置好之后,我们要将当前环境保存
//设置当前环境SetThreadContext(hThread, &g_Context);由此,硬件断点的大致实现思绪已经完成。
本人理解有限,如有错误,请批评指正!