原理:利用了4个硬断位置设置了4个有用的断点
举例代码如下:(可以4个位置的关系与处理都可以再复杂很多很多倍。)
代码:#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#pragma pack(1)
typedef struct _DEBUG_DR6_
{
union{
ULONG32 _DR6;
struct {
unsigned B0 : 1;
unsigned B1 : 1;
unsigned B2 : 1;
unsigned B3 : 1;
unsigned Reverted : 9;
unsigned BD : 1;
unsigned BS : 1;
unsigned Reverted2 : 17;
}st;
}u;
}DEBUG_DR6, *PDEBUG_DR6;
typedef struct _DEBUG_DR7_
{
union{
ULONG32 _DR7;
struct {
unsigned L0 : 1; //0
unsigned G0 : 1; //1
unsigned L1 : 1; //2
unsigned G1 : 1; //3
unsigned L2 : 1; //4
unsigned G2 : 1; //5
unsigned L3 : 1; //6
unsigned G3 : 1; //7
unsigned LE : 1; //8
unsigned GE : 1; //9
unsigned reserved : 3; //001 //10-11-12
unsigned GD : 1; //13...
unsigned reserved2 : 2; //00
unsigned RW0 : 2;
unsigned LEN0 : 2;
unsigned RW1 : 2;
unsigned LEN1 : 2;
unsigned RW2 : 2;
unsigned LEN2 : 2;
unsigned RW3 : 2;
unsigned LEN3 : 2;
}st;
}u;
}DEBUG_DR7, *PDEBUG_DR7;
#pragma pack()
PVOID pHookAddress[4] = { NULL };//只有4个位置!
PVOID pJmpAddress[4] = { NULL };
int MyFilter(EXCEPTION_POINTERS * pException)
{
static ULONG32 s_Count = 0;
DEBUG_DR6 dr6;
PCONTEXT pContext;
pContext = pException->ContextRecord;
dr6.u._DR6 = pException->ContextRecord->Dr6;
printf("%x eip = %p except %x\r\n",s_Count++, pContext->Eip,pException->ExceptionRecord->ExceptionCode);
if (dr6.u.st.B0)
{
if (pContext->Eip == (DWORD)pHookAddress[0])
{
pContext->Eip = (DWORD)pJmpAddress[0];
}
return EXCEPTION_CONTINUE_EXECUTION;
}
if (dr6.u.st.B1)
{
if (pContext->Eip == (DWORD)pHookAddress[1])
{
pContext->Eip = (DWORD)pJmpAddress[1];
}
return EXCEPTION_CONTINUE_EXECUTION;
}
if (dr6.u.st.B2)
{
if (pContext->Eip == (DWORD)pHookAddress[2])
{
pContext->Eip = (DWORD)pJmpAddress[2];
}
return EXCEPTION_CONTINUE_EXECUTION;
}
if (dr6.u.st.B3)
{
if (pContext->Eip == (DWORD)pHookAddress[3])
{
pContext->Eip = (DWORD)pJmpAddress[3];
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
void Fuck_Call()
{
MessageBoxA(NULL, "异常\r\n", "提示", MB_OK);
ExitProcess(-1);
}
void Fuck_OK()
{
Sleep(1);
}
void Fuck_Call_3()
{
MessageBoxA(NULL, "异常3\r\n", "提示3", MB_OK);
ExitProcess(-1);
}
void Fuck_Call_1()
{
MessageBoxA(NULL, "异常1\r\n", "提示1", MB_OK);
ExitProcess(-1);
}
void Fuck_Call_2()
{
MessageBoxA(NULL, "异常2\r\n", "提示2", MB_OK);
ExitProcess(-1);
}
void setHwbp()
{
CONTEXT ctx = { 0 };
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (GetThreadContext(GetCurrentThread(), &ctx))
{
ctx.Dr0 = (DWORD)pHookAddress[0];
ctx.Dr1 = (DWORD)pHookAddress[1];
ctx.Dr2 = (DWORD)pHookAddress[2];
ctx.Dr3 = (DWORD)pHookAddress[3];
ctx.Dr7 = 0x455;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
SetThreadContext(GetCurrentThread(), &ctx);
//printf("set hwbp ok\r\n");
}
}
void NormalLoop()
{
setHwbp();
while (1)
{
__try
{
Fuck_Call();
Fuck_Call_3();
Fuck_Call_2();
Fuck_Call_1();
}
__except (MyFilter(GetExceptionInformation()))
{
}
Sleep(1000);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
pJmpAddress[0] = (PVOID)Fuck_OK;
pHookAddress[0] = (PVOID)Fuck_Call;
pJmpAddress[1] = (PVOID)Fuck_OK;
pHookAddress[1] = (PVOID)Fuck_Call_3;
pJmpAddress[2] = (PVOID)Fuck_OK;
pHookAddress[2] = (PVOID)Fuck_Call_2;
pJmpAddress[3] = (PVOID)Fuck_OK;
pHookAddress[3] = (PVOID)Fuck_Call_1;
NormalLoop();
return 0;
}
|