2014年8月26日 星期二

SEH和VEH







先说结论吧:
VEH可以在修复问题后继续执行产生异常的代码 ,SEH不行
SEH比起VEH更方便简洁直观因为VEH一旦注册handler,任何位置的任何异常都会走到handler里。
VEH比SEH触发更早,VEH如果将问题处理完毕,可以阻止SEH的触发,如果VEH认为问题没法处理好也可以继续触发SEH。
VEH可以拿来做很多事,比如说内存修改器之类的

下面是两组实验代码:

int *pb = 0;

LONG CALLBACK VectoredHandler(
    _In_  PEXCEPTION_POINTERS ExceptionInfo
    )
{
    *pb = 1;//b = 1
   
    printf("veh\n");
    return EXCEPTION_CONTINUE_EXECUTION;
    return EXCEPTION_CONTINUE_SEARCH;
}

int _tmain(int argc, _TCHAR* argv[])
{
    AddVectoredExceptionHandler(1, VectoredHandler);
    __try
    {
        int b = 0;
        pb = &b;
        printf("before\n");
        int a = 1 / b;//exception
        printf("after\n");
    }
    __except (1)
    {
        printf("seh");
    }
    getchar();
    return 0;
}

-----------------------------------------------------------------------------------

DWORD offset_of_b = 0;

LONG CALLBACK VectoredHandler(
    _In_  PEXCEPTION_POINTERS ExceptionInfo
    )
{
    *(int*)(ExceptionInfo->ContextRecord->Ebp + offset_of_b) = 1;//b = 1
   
    printf("veh\n");
    return EXCEPTION_CONTINUE_EXECUTION;
    return EXCEPTION_CONTINUE_SEARCH;
}

int _tmain(int argc, _TCHAR* argv[])
{
    AddVectoredExceptionHandler(1, VectoredHandler);
    __try
    {
        int b = 0;
        offset_of_b = (DWORD)&b;
        __asm{
            sub offset_of_b,ebp
        }
        printf("before\n");
        int a = 1 / b;
        printf("after\n");
    }
    __except (1)
    {
        printf("seh");
    }
    getchar();
    return 0;
}

沒有留言:

張貼留言