DR6为状态寄存器,DR7为控制寄存器。
DR4和DR5保留。当CR4.DE==1时,访问DR4和DR5产生#UD异常;IF CR4.DE==0,访问DR4和DR5将是对DR6和DR7的访问。
要设置断点的话这些信息基本上已经够了。
addr == 4n 时可以设dword断点
addr == 4n + 2 时可以设word断点
addr == 2n+1 时只能byte断点。
比如说在 00401000处,你可以设三种断点
在 00401002处,你只能设word和byte断点
在 00401005处,你只能设byte断点
windows系统中你可以用GetThreadContext或者WowGetThreadContext(位系统)。内核模式下可以用PsGetThreadContext或者捕获异常然后读取。
SetThreadContext设置的线程上下文是对当前线程有效的,那么为什么OD的硬件断点能够对当前进程有效?
因为OD是遍历线程下断,新建线程也下断。
使用SetThreadContext的注意事项:
·获取线程context的时机。载入目标进程发生第一次EXCEPT_BREAKPOINT 时发生在APC中,线实的CONTEXT暂时被存放在栈上,当APC结束调用NtContinue返回内核时写回去,如果此时调用SetThreadContext,断点只在APC期间有效,但是我们可以直接改写在栈上的CONTEXT,这样就可以提前设置断点了。
·打开目标进程的权限要够。
只要能使用Drx的断点功能就可以配合SEH、调试API进行一些反跟踪。
下面是一个anti-OD的示例:
// OD 每次获得被调试程序的控制权后 都会把Drx的值设为自己的设定值
// 倘若没有设硬件断点 就是Drx每次都会请0
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
void InitDetect()
{
CONTEXT context;
HANDLE hThread = GetCurrentThread();
context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread, &context);
context.Dr0 = 0xFF;
context.Dr1 = 0xFE;
context.Dr2 = 0xFD;
context.Dr3 = 0xFC;
SetThreadContext(hThread, &context);
}
// 只针对OD 其他调试器未验证 微软的调试器就无效
// anti OD断点
BOOL IsDebuged()
{
CONTEXT context;
HANDLE hThread = GetCurrentThread();
context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread, &context);
printf("Dr0:%x\n", context.Dr0);
printf("Dr1:%x\n", context.Dr1);
printf("Dr2:%x\n", context.Dr2);
if (context.Dr0 != 0xFF || context.Dr1 != 0xFE || context.Dr2 != 0xFD)
{
return TRUE;
}
return FALSE;
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务