Assembly로 하는 코드들은 다른 데 나와 있어서
Visual C++로 해 보았다.
LPEXCEPTION_POINTERS except_ptr;
__try {
RaiseException(1, 0, 0, NULL);
}
__except (except_ptr = GetExceptionInformation(),
EXCEPTION_EXECUTE_HANDLER)
{
CONTEXT *ctx = except_ptr->ContextRecord;
if (ctx->Dr0 != 0 ||
ctx->Dr1 != 0 ||
ctx->Dr2 != 0 ||
ctx->Dr3 != 0 ||
ctx->Dr6 != 0 ||
ctx->Dr7 != 0)
{
printf("Debugger Present - Hardware Breakpoints\n");
}
}
Hardware breakpoing를 저장하는 DR0 ~ DR7 register는
일반적으로 유저 모드에서 접근할 수 없지만
SEH에서 CONTEXT에 전달된다.
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
구조에 채우는 매크로인
GetExceptionInformation()는
filter expression에만 쓸 수 있어서 변수에 저장하고
handler 부분에서 ContextRecord를 꺼내고
ContextRecored에서 접근할 수 있는 DR1~DR7
값을 사용하여 탐지한다.