首页 > 代码库 > VEH&VCH

VEH&VCH

本文99.9%的代码及内容作者:mengwuji

来自:http://www.mengwuji.net/forum.php?mod=viewthread&tid=1371

VEH:向量化异常处理,是对整个进程来说是全局的(SEH是针对线程的)异常捕获技术,只要通过简单的设置,只要当前进程发送了异常,都能被我们设置好的VEH捕获到。

#include<windows.h>

LONG __stdcall FirstVEHandler(
         EXCEPTION_POINTERS *ExceptionInfo
         )
{
        printf("FirstVEHandler\n");
        return EXCEPTION_CONTINUE_SEARCH;
}

LONG __stdcall LastVEHandler(
        EXCEPTION_POINTERS *ExceptionInfo
        )
{
        printf("LastVEHandler\n");
        ExceptionInfo->ContextRecord->Eip++;
        return EXCEPTION_CONTINUE_EXECUTION;
}

void seHandler()
{
        printf("seHandler\n");
}

void main()
{
    char* p=NULL;
    char c=a;
        AddVectoredExceptionHandler(0,FirstVEHandler);
        AddVectoredContinueHandler(0,LastVEHandler);

        __try{
                //__asm{        int 3        }
            *p=c;
        }__except(EXCEPTION_EXECUTE_HANDLER){
                seHandler();
        }

        getchar();
}

windows提供了两个API用来添加VEH和VCH的,分别是:

PVOID WINAPI AddVectoredExceptionHandler(
  _In_  ULONG FirstHandler,
  _In_  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

PVOID WINAPI AddVectoredContinueHandler(
  _In_  ULONG FirstHandler,
  _In_  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

FirstHandler-----这个参数,是当我们进程中添加了多个VEH或者VCH时才有效,比如调用了两次AddVectoredExceptionHandler,那么进程中存在两个向量化处理异常回调A和B,这时候此参数就决定了A先执行还是A后执行,如果FirstHandler等于零,那么A就代表最后执行,非零值就代表第一个执行。当然这种说法也不全对,要看B的FirstHandler参数具体是什么值
VectoredHandler------是一个回调函数,这个回调函数是我们提供的,当有异常发生时,windows就会把异常信息交给我们的这个回调函数去执行。
AddVectoredExceptionHandler是添加VEH,AddVectoredContinueHandler是添加VCH,区别在于AddVectoredExceptionHandler是执行在所有SEH的前面,AddVectoredContinueHandler是执行在所有SEH后面。

LastVEHandler函数是没有被执行到,原因是__except(EXCEPTION_EXECUTE_HANDLER)这样的写法会让异常在seHandler处理了,处理完成后就没有异常了,所以LastVEHandler没有被执行。
为了xiang办法让LastVEHandler也执行,我们把代码改成这样的:__except(EXCEPTION_CONTINUE_EXECUTION);

 

如果你把 *p=c;改成int 3,结果是这样的:

这里又不会执行seHandler了,原因是EXCEPTION_CONTINUE_EXECUTION是忽略了此异常所以就进不了seHandler,但是记住我们必须在LastVEHandler里让eip加1,这里就等于LastVEHandler把异常给处理掉了。
从上面两幅图,虽然不能直观的看出几个函数的执行顺序,但是总结一下,他们的顺序也就是我说的FirstVEHandler-----seHandler-----LastVEHandler.
为了弄明白AddVectoredExceptionHandler和AddVectoredContinueHandler到底做了什么,我们可以看它们的反汇编代码。