X64硬件断点(指令断点)技术详解
创作时间:
作者:
@小白创作中心
X64硬件断点(指令断点)技术详解
引用
CSDN
1.
https://blog.csdn.net/weixin_43751677/article/details/145888026
硬件断点是软件调试中一种强大的工具,它允许开发者在程序执行到特定地址时触发中断,从而进行更精细的控制和观察。本文将深入探讨X64架构下的硬件断点机制,包括调试寄存器的功能、访问权限以及如何通过代码设置硬件断点。
调试寄存器概述
在X64架构中,调试寄存器主要包括断点地址寄存器(DR0-DR3)、调试状态寄存器(DR6)和调试控制寄存器(DR7)。这些寄存器用于设置和监视最多4个断点,每个断点可以指定线性地址、断点位置的长度、触发条件以及是否启用。
调试寄存器的功能
- 断点地址寄存器(DR0-DR3):保存断点的32/64位线性地址。断点比较在物理地址转换之前进行。
- 调试状态寄存器(DR6):报告生成调试或断点异常时生效的条件。
- 调试控制寄存器(DR7):指定导致生成断点的内存或I/O访问形式。
调试寄存器的访问
调试寄存器是特权资源,只能在实地址模式、SMM或CPL为0的保护模式下访问。以下是32位和64位架构下的调试寄存器布局:
调试控制寄存器(DR7)详解
调试控制寄存器(DR7)用于启用或禁用断点并设置断点条件。以下是DR7寄存器中各个标志的详细说明:
- L0-L3(本地断点使能)标志(位0, 2, 4, 6):启用当前任务的相关断点条件。处理器会在每次任务切换时自动清除这些标志。
- G0-G3(全局断点使能)标志(位1, 3, 5, 7):启用所有任务的相关断点条件。处理器在任务切换时不会清除这些标志。
- LE和GE(本地和全局精确断点使能)标志(位8, 9):在P6系列处理器及后续IA-32处理器中不支持。
- RTM(受限事务性内存)标志(位11):启用RTM事务区域的高级调试。
- GD(通用检测使能)标志(位13):启用调试寄存器保护,防止在访问调试寄存器时产生干扰。
- R/W0-R/W3(读/写)字段(位16, 17, 20, 21, 24, 25, 28, 29):指定断点的条件。当DE标志被设置时,处理器按以下方式解释这些位:
- 00:仅在指令执行时中断
- 01:仅在数据写入时中断
- 10:I/O读写中断
- 11:中断数据读取或写入,但不中断指令获取
- LEN0-LEN3(长度)字段(位18、19、22、23、26、27、30和31):指定断点地址寄存器中指定地址处的内存位置的大小。
调试状态寄存器(DR6)详解
调试状态寄存器(DR6)用于报告在生成最后一个调试异常时采样的调试条件。以下是DR6寄存器中各个标志的详细说明:
- B0-B3(断点条件检测)标志(位0到3):表示其关联的断点条件在生成调试异常时满足。
- BLD(总线锁定检测)标志(位11):表示调试异常是由于总线锁定被断言而触发的。
- BD(调试寄存器访问检测)标志(位13):表示下一条指令流中的指令访问了一个调试寄存器。
- BS(单步执行)标志(位14):表示调试异常是由单步执行模式触发的。
- BT(任务切换)标志(位15):表示调试异常是由于任务切换引起的。
- RTM(受限事务性内存)标志(位16):表示调试异常发生在RTM区域内部。
代码示例:设置硬件断点
下面是一个来自泰坦反汇编引擎的函数示例,展示了如何设置硬件断点:
__declspec(dllexport) bool TITCALL SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack)
{
if((bpxAddress % 2) != 0)
if((bpxAddress % 4) != 0)
if((bpxAddress % 8) != 0)
if(!IndexOfRegister)
{
if(!DebugRegister[0].DrxEnabled)
IndexOfRegister = UE_DR0;
else if(!DebugRegister[1].DrxEnabled)
IndexOfRegister = UE_DR1;
else if(!DebugRegister[2].DrxEnabled)
IndexOfRegister = UE_DR2;
else if(!DebugRegister[3].DrxEnabled)
IndexOfRegister = UE_DR3;
}
uint dr7;
GetContextData(UE_DR7, &dr7);
DebugRegister[hwbpIndex].DrxExecution = false;
switch(bpxType)
{
case UE_HARDWARE_EXECUTE:
hwbpSize = SIZE_1;
DebugRegister[hwbpIndex].DrxExecution = true;
case UE_HARDWARE_READWRITE:
hwbpType = TYPE_READWRITE;
}
hwbpMode = MODE_LOCAL;
dr7.HWBP_MODE[hwbpIndex] = hwbpMode;
dr7.HWBP_SIZE[hwbpIndex] = hwbpSize;
dr7.HWBP_TYPE[hwbpIndex] = hwbpType;
for(unsigned int i = 0; i < hListThread.size(); i++)
{
SetContextDataEx(hListThread.at(i).hThread, UE_DR7, dr7);
SetContextDataEx(hListThread.at(i).hThread, IndexOfRegister, bpxAddress);
}
DebugRegister[hwbpIndex].DrxBreakPointType = bpxType;
DebugRegister[hwbpIndex].DrxBreakPointSize = bpxSize;
DebugRegister[hwbpIndex].DrxEnabled = true;
DebugRegister[hwbpIndex].DrxBreakAddress = (ULONG_PTR)bpxAddress;
DebugRegister[hwbpIndex].DrxCallBack = (ULONG_PTR)bpxCallBack;
}
异常识别:陷阱类型与错误类型
硬件断点触发的异常可能是陷阱类型(trap)或错误类型(fault)。关键在于确定异常发生的时间点是在指令执行前还是指令执行后。这直接影响到栈中的返回地址以及是否需要在中断处理程序中设置EFLAGS的RF位。
参考资料
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3: System Programming Guide
- 《软件调试 卷1》
本文主要参考了Intel白皮书的VOLUME 3系统编程指南篇的CHAPTER 18,详细介绍了DEBUG、BRANCH PROFILE、TSC以及Intel资源管理技术(Intel RDT)特性。对于更深入的学习,建议参考《软件调试 卷1》,内容详实且与白皮书内容相近。此外,X64DBG使用的反汇编引擎源码中也包含了硬件异常响应的具体实现,可以通过逆向分析Windows的KiDebugTrapOrFault函数或Linux的源码来进一步了解。
热门推荐
皮克斯《夏日友晴天》:一个跨越偏见的友谊故事
运动员低心率之谜:心脏结构优化与科学训练双管齐下
2025年电动车新规来袭,你准备好了吗?
破壁机加热功能让烹饪更简单,3款暖心汤品轻松做
超材料引领未来科技潮流
4/4拍60速度,钢琴新手也能弹好的《青花》
珀斯光荣主场迎战领头羊,奥克兰FC能否延续不败金身?
深圳至重庆全程列车指南:包括高铁、普通快车及票价及时刻表信息
正确使用高锰酸钾:外用安全,内服危险
泰国签证新规:入境游客需携带15000泰铢现金,三国推新措施促旅游
女性分享隐私背后的信任:男性该如何正确回应
万茜:在《人民警察》争议中展现坚韧演技
夏日清凉必备:绿豆汤花样做法大揭秘
S37赛季马可波罗攻略:攻速流装备铭文搭配与实战技巧
海南最大单体海洋温泉:五国温泉城开业,120个特色泉池等你泡
不同类型便秘的饮食改善指南
沈阳地铁9号线张官屯站主体结构封顶,二期工程迎来重要里程碑
广东连州地下河:喀斯特地貌造就的岭南第一暗河
南善小食店:佛山老字号的地道美味
认知训练是脑外伤康复关键,最新研究证实光疗有效
圣诞主题生日蛋糕装饰教程:打造节日氛围满满的甜点
包虫病防治有了新方案:15部门联手,2030年实现疫情控制
牛黄解毒片的正确使用方法
无创肝纤维化诊断技术获重大突破,磁共振影像实现精准检测
天府机场跻身“5000万级”机场行列,智慧服务与国际航线双领先
秋冬进补,清炖羊肉汤正当时
育儿专家教你巧妙回应孩子奇思妙问
揭阳启动进贤门改造项目,将成古城文化新地标
机顶盒维修指南:几招轻松解决常见故障
楚雄到西双版纳:打卡千年古刹白塔寺,感受云南多元文化魅力