-
-
[原创]VC利用调试寄存器实现硬件断点,处理断点异常
-
发表于:
2012-12-4 05:29
12033
-
[原创]VC利用调试寄存器实现硬件断点,处理断点异常
【文章标题】:VC利用调试寄存器实现硬件断点源码
【文章作者】:yhswwr(SilenceRet)
【作者QQ】:3412259
【编写语言】:C++
【使用工具】:VS2008.VC++9
【本文链接】:http://bbs.pediy.com/showthread.php?p=1122838
【参考链接】:http://bbs.pediy.com/showthread.php?t=107515
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!(当前行剽窃自justhxy)
/************************************************************************
SetHardWareBP:
设置线程硬件断点
hThread: 线程句柄
dwAddr: 断点地址
dwDrIndex: 硬件寄存器(0~3)
nType: 断点类型(0:执行,1:读取,2:写入)
nLen: 读写断点数据长度(1,2,4)
/************************************************************************/
BOOL SetHardWareBP(HANDLE hThread,DWORD dwAddr,DWORD dwDrIndex=0,UINT nType=0,UINT nLen=1)
{
BOOL bResult=FALSE;
CONTEXT context = {0};
context.ContextFlags=CONTEXT_DEBUG_REGISTERS;
if(::GetThreadContext(hThread,&context))
{
DWORD dwDrFlags=context.Dr7;
//将断点地址复制进入对应Dr寄存器(参考CONTEXT结构)
memcpy(((BYTE *)&context)+4+dwDrIndex*4,&dwAddr,4);
//决定使用哪个寄存器
dwDrFlags|=(DWORD)0x1<<(2*dwDrIndex);
//见OD读写断点时 这个置位了,执行没有(置位也正常-_-)
dwDrFlags|=0x100;
//先[COLOR="Sienna"]将对应寄存器对应4个控制位清零(先或,再异或,还有其它好方法吗)[/COLOR] =.= 悲催的小学生
dwDrFlags|=(DWORD)0xF<<(16+4*dwDrIndex);
dwDrFlags^=(DWORD)0xF<<(16+4*dwDrIndex);
//设置断点类型,执行:00 读取:11 写入:01
//([B][COLOR="Olive"]不知何故,测试时发现不论是11还是01,读写数据时均会断下来[/COLOR][/B])
if (nType==1)
dwDrFlags|=(DWORD)0x3<<(16+4*dwDrIndex); //读取
else if(nType==2)
dwDrFlags|=(DWORD)0x1<<(16+4*dwDrIndex); //写入
//else if(nType==0)
//dwDrFlags=dwDrFlags //执行
//设置读写断点时数据长度
if (nType!=0)
{
if(nLen==2 && dwAddr%2==0)
dwDrFlags|=(DWORD)0x1<<(18+4*dwDrIndex); //2字节
else if(nLen==4 && dwAddr%4==0)
dwDrFlags|=(DWORD)0x3<<(18+4*dwDrIndex); //4字节
}
context.Dr7=dwDrFlags;
if (::SetThreadContext(hThread,&context)) bResult=TRUE;
}
return bResult;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!