• 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
    ");
            return EXCEPTION_CONTINUE_SEARCH;
    }
    
    LONG __stdcall LastVEHandler(
            EXCEPTION_POINTERS *ExceptionInfo
            )
    {
            printf("LastVEHandler
    ");
            ExceptionInfo->ContextRecord->Eip++;
            return EXCEPTION_CONTINUE_EXECUTION;
    }
    
    void seHandler()
    {
            printf("seHandler
    ");
    }
    
    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到底做了什么,我们可以看它们的反汇编代码。

  • 相关阅读:
    洛谷 1736 创意吃鱼法
    有多重限制的背包
    洛谷 1417 烹调方案
    2008 noip 传纸条
    环形石子合并 洛谷 1880 && hdu 3506 Monkey Party
    洛谷 1282 多米诺骨牌
    (金明的预算方案)依赖性的背包
    分组背包问题
    混合背包问题
    多重背包问题
  • 原文地址:https://www.cnblogs.com/qiangua/p/3710324.html
Copyright © 2020-2023  润新知