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交规都有哪些变化呢?新国标红绿灯老司机中招了?如果不懂几本驾驶证都不够扣
郑绪岚《牧羊曲》:清澈嗓音与精湛技巧的完美融合
户口迁移会影响养老金领取吗?答案在这里!
嗜酸细胞性食管炎的饮食管理指南
食管炎患者的面食指南:从选择到注意事项
这4类运动对肾好,可惜被很多人忽略了
炒青菜头加一把它,醇鲜清香,美味可口,全家吃了都有很好
绿色蔬果低钠低脂高纤维
桂林至昆明深度游全攻略:行程规划、必去景点与旅行贴士
桂林至昆明深度游全攻略:行程规划、必去景点与旅行贴士
石家庄至昆明自驾游的行车时间与路线建议
赵贞月教你修复友情的五大秘籍
修复友情,这些技巧你get了吗?
当归补血口服液的功效与作用有什么
蛇年创意红包袋热销,你买了吗?动态“微信红包封面”也卖疯了
南京盐水鸭——还原百年老店的地道风味
湖南省网上家长学校:助力科学育儿,共建和谐家庭
教育故事:助力青少年成长的智慧之源
安卓免打扰模式:让你的学习效率翻倍的秘密武器
用手机勿扰模式守护家庭时光
维生素B2片:功效、副作用与建议
维生素B2片:功效、副作用与建议
上海天文台揭秘:气候变化影响地球自转
科学家揭秘:人类活动竟影响地球自转速度!