我是如何检测硬件断点的-

硬件断点

Baklib
狐白 最后一次编辑 3 年多前
526
由于应用层直接访问DRx 会直接产生#GP异常
所以应用层的检测只有
NtGetContextThread 向量化异常处理
先来说说NtGetContextThread怎么检测的
我们只要判断Context=DR0->DR4 不等于0就可以了 不过这种方法已经对目前的主流调试器无效了
因为有插件来隐藏了 也就是HOOK NtGetContextThread HOOK NtSetContextThread
主要说的是程序自身接管自身的异常 也就是VEH
当调试器下硬件断点 会占用DR0-DR4的位置
所以我们自身触发一个异常 比如:INT3
VEH的异常里面 我们检测Context=DR0->DR4  是否是0 这样一来
HOOK NtGetContextThread(获取的DR0-DR4为0) HOOK NtSetContextThread就无效了 
(如何检测程序是否处理了 而不是被调试器给接管了呢) 我们可以在veh的异常子程序中建立一个全局变量 如果程序处理了 可以自定义这个变量的值 如果没有那么这个值也就是等于创建全局变量的值 =NULL
或者可以使用RDTSC 来判断是否被调试器接管 --
其次是硬件占坑 -原理很简单 可以参考SE壳
也就是下自身主线程的DR0-DR4 为指定的地址
这样一来 如果调试器继续下硬件断点 会将DR0的值 改为所下断点的地址
然后可以通过NtGetContextThread DR0来获取是不是等于自身的地址
不过这种方法还是有弊端 所以可以加强下
比如创建一个线程(硬件占坑)用来检测是否 程序被(SSDTHOOK)HOOK NtGetContextThread
因为HOOK NtGetContextThread后 程序自身获取的DR0-DR4始终为0  配合硬件占坑 可以很有效的检测