反调试——VEH
VEH:向量化异常(vectored exception handle)
VEH和SEH的区别
SEH是基于线程的,而VEH是基于进程的。
因为很清楚的可以看到SEH的数据结构是保存在栈空间的,直接在函数体内用push来处理,而VEH是以双链表的形式保存在堆里面。
异常触发后的顺序:
优先顺序:调试器 > VEH > SEH
添加VEH异常
VEH有提供的API可以直接拿来添加VEH
AddVectoredExceptionHandler(ULONG First,//1表示添加到链表头部 0表示添加到链表尾部
PVECTORED_EXCEPTION_HANDLER Handler//异常处理器的地址
);
定义异常处理程序
LONG PvectoredExceptionHandler(
_EXCEPTION_POINTERS *ExceptionInfo
)
{...}
使用该函数定义,可以得到基于VEH的异常处理程序的函数原型
异常处理程序的参数
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;//记录着异常的信息
PCONTEXT ContextRecord; //PCONSTEXT表示寄存器的内容
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
返回值
To return control to the point at which the exception occurred, return EXCEPTION_CONTINUE_EXECUTION (0xffffffff). To continue the handler search, return EXCEPTION_CONTINUE_SEARCH (0x0).
有两种情况,一种是返回EXCEPTION_CONTINUE_EXECUTION ,另一种是返回EXCEPTION_CONTINUE_SEARCH。
EXCEPTION_CONTINUE_EXECUTION :表示继续执行
EXCEPTION_CONTINUE_SEARCH:表示查找下一个VEH来处理
代码编写VEH和SEH
#include<Windows.h>
#include<iostream>
EXCEPTION_DISPOSITION myExceptHandler(
struct _EXCEPTION_RECORD* ExceptionRecord,
PVOID EstablisherFrame,
PCONTEXT pcontext,
PVOID DispatcherContext
)
{
MessageBoxA(0, "SEH处理了异常", "异常报错", MB_OK);
pcontext->Eip = pcontext->Eip+ 4;
return ExceptionContinueExecution;
}
LONG WINAPI PvectoredExceptionHandler(
_EXCEPTION_POINTERS* ExceptionInfo
)
{
MessageBoxA(0, "VEH处理了异常", "异常处理", MB_OK);
ExceptionInfo->ContextRecord->Eip += 4;
return EXCEPTION_CONTINUE_EXECUTION;
}
int main()
{
AddVectoredExceptionHandler(1, PvectoredExceptionHandler);
DWORD execptionFuncAddr = (DWORD)myExceptHandler;//异常处理的函数地址
__asm
{
push execptionFuncAddr;
mov eax, fs: [0] ;
push eax;
mov fs : [0] , esp;
//添加异常,并且把异常放到异常链里面,并且把异常的头指针指向新的头结点
}
char* str = NULL;
str[0] = 'a';
printf("Sna1lGo\n");
system("pause");
return 0;
}#include<Windows.h>
#include<iostream>
EXCEPTION_DISPOSITION myExceptHandler(
struct _EXCEPTION_RECORD* ExceptionRecord,
PVOID EstablisherFrame,
PCONTEXT pcontext,
PVOID DispatcherContext
)
{
MessageBoxA(0, "SEH处理了异常", "异常报错", MB_OK);
pcontext->Eip = pcontext->Eip+ 4;
return ExceptionContinueExecution;
}
LONG WINAPI PvectoredExceptionHandler(
_EXCEPTION_POINTERS* ExceptionInfo
)
{
MessageBoxA(0, "VEH处理了异常", "异常处理", MB_OK);
ExceptionInfo->ContextRecord->Eip += 4;
return EXCEPTION_CONTINUE_EXECUTION;
}
int main()
{
AddVectoredExceptionHandler(1, PvectoredExceptionHandler);
DWORD execptionFuncAddr = (DWORD)myExceptHandler;//异常处理的函数地址
__asm
{
push execptionFuncAddr;
mov eax, fs: [0] ;
push eax;
mov fs : [0] , esp;
//添加异常,并且把异常放到异常链里面,并且把异常的头指针指向新的头结点
}
char* str = NULL;
str[0] = 'a';
printf("Sna1lGo\n");
system("pause");
return 0;
}
总结: