首页
社区
课程
招聘
[原创]VEH,VCH,UEF Windows向量化异常处理机制详解
发表于: 2014-6-22 19:04 21353

[原创]VEH,VCH,UEF Windows向量化异常处理机制详解

bxc 活跃值
6
2014-6-22 19:04
21353
LONG NTAPI ExceptionHandler(struct _EXCEPTION_POINTERS[CODE]
EXCEPTION_DISPOSITION __cdecl _except_handler (  
    _In_ struct _EXCEPTION_RECORD *_ExceptionRecord,  //异常记录结构指针
    _In_ void * _EstablisherFrame,             //指向EXCEPTION_REGISTRATION结构,即SEH链
    _Inout_ struct _CONTEXT *_ContextRecord,      //Context结构指针 (线程上下文)
    _Inout_ void * _DispatcherContext           //无意义 (调度器上下文?)
);  
typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;  //异常记录(EXCEPTION_RECORD)的指针
    PCONTEXT ContextRecord;  //线程上下文的指针
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;   //异常代码,说明是什么异常,比如单步、除零、断点等等
    DWORD ExceptionFlags;      //异常标志
    struct _EXCEPTION_RECORD *ExceptionRecord;   //指向下一个异常记录(EXCEPTION_RECORD)的指针
    PVOID ExceptionAddress;   //发生异常的地址
    DWORD NumberParameters;  //异常信息的个数(即数组ExceptionInformation的个数)
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];  //异常信息数组
    } EXCEPTION_RECORD;

typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
/* 浮点寄存器 */
typedef struct _FLOATING_SAVE_AREA {
    DWORD   ControlWord;
    DWORD   StatusWord;
    DWORD   TagWord;
    DWORD   ErrorOffset;
    DWORD   ErrorSelector;
    DWORD   DataOffset;
    DWORD   DataSelector;
    BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
    DWORD   Spare0;
} FLOATING_SAVE_AREA;

typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;

typedef struct _CONTEXT {

    //
    // The flags values within this flag control the contents of
    // a CONTEXT record.
    //
    // If the context record is used as an input parameter, then
    // for each portion of the context record controlled by a flag
    // whose value is set, it is assumed that that portion of the
    // context record contains valid context. If the context record
    // is being used to modify a threads context, then only that
    // portion of the threads context will be modified.
    //
    // If the context record is used as an IN OUT parameter to capture
    // the context of a thread, then only those portions of the thread's
    // context corresponding to set flags will be returned.
    //
    // The context record is never used as an OUT only parameter.
    //

    DWORD ContextFlags;

    //
    // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
    // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
    // included in CONTEXT_FULL.
    //

    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
    //

    FLOATING_SAVE_AREA FloatSave;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_SEGMENTS.
    //

    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_INTEGER.
    //

    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_CONTROL.
    //

    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

    //
    // This section is specified/returned if the ContextFlags word
    // contains the flag CONTEXT_EXTENDED_REGISTERS.
    // The format and contexts are processor specific
    //

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

typedef CONTEXT *PCONTEXT;
push handler 	// 异常处理函数的地址
push fs:[0] 	// 前一个异常处理函数函数的地址
mov fs:[0], esp 	// 装入新的SEH链结构
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,      //0
    ExceptionContinueSearch,          //1
    ExceptionNestedException,        //2
    ExceptionCollidedUnwind            //3
} EXCEPTION_DISPOSITION;
#include <SDKDDKVer.h>
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>

#define DISABLE_SEH     0         //是否禁用线程SEH
#define VEH_INT3        0         //配置是VEH还是VCH处理断点异常
#define ENABLE_UEF      1         //是否启用UEF
#define UEF_HANDLE      0         //UEF是否处理掉异常,ENABLE_UEF为0时,该值无效
#define UEF_C_SEARCH    0         //UEF_HANDLE非0时,该值无效,为0时返回EXCEPTION_EXECUTE_HANDLER,非0时返回EXCEPTION_CONTINUE_SEARCH

LONG NTAPI F_ExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
  printf("VEH!");
  switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
  {
#if VEH_INT3 
  case EXCEPTION_BREAKPOINT:
    printf("√F_ECODE:%08X  Int3!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->Eip++;
    return EXCEPTION_CONTINUE_EXECUTION;
#else
  case EXCEPTION_SINGLE_STEP:
    printf("√F_ECODE:%08X  SingleStep!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->EFlags &= 0xFFFFFEFF;
    return EXCEPTION_CONTINUE_EXECUTION;
#endif
  default:
    printf("×F_ECODE:%08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    return EXCEPTION_CONTINUE_SEARCH;
  }
}

LONG NTAPI L_ExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
  printf("VCH!");
  switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
  {
#if VEH_INT3
  case EXCEPTION_SINGLE_STEP:
    printf("√L_ECODE:%08X  SingleStep!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->EFlags &= 0xFFFFFEFF;
    return EXCEPTION_CONTINUE_EXECUTION;
#else
  case EXCEPTION_BREAKPOINT:
    printf("√L_ECODE:%08X  Int3!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->Eip++;
    return EXCEPTION_CONTINUE_EXECUTION;
#endif
  default:
    printf("×L_ECODE:%08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    return EXCEPTION_CONTINUE_SEARCH;
  }
}

#if ENABLE_UEF
LONG NTAPI MyUEF(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
  printf("UEF!");
  switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
  {
#if VEH_INT3
  case EXCEPTION_SINGLE_STEP:
#if UEF_HANDLE
    printf("√U_ECODE:%08X  SingleStep!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->EFlags &= 0xFFFFFEFF;
    return EXCEPTION_CONTINUE_EXECUTION;
#else
    printf("×U_ECODE:%08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
#if UEF_C_SEARCH
    return EXCEPTION_CONTINUE_SEARCH;
#else
    return EXCEPTION_EXECUTE_HANDLER;
#endif
#endif
    
#else
  case EXCEPTION_BREAKPOINT:
#if UEF_HANDLE
    printf("√U_ECODE:%08X  Int3!\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
    ExceptionInfo->ContextRecord->Eip++;
    return EXCEPTION_CONTINUE_EXECUTION;
#else
    printf("×U_ECODE:%08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
#if UEF_C_SEARCH
    return EXCEPTION_CONTINUE_SEARCH;
#else
    return EXCEPTION_EXECUTE_HANDLER;
#endif
#endif

#endif
  default:
    printf("×U_ECODE:%08X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
#if UEF_C_SEARCH
    return EXCEPTION_CONTINUE_SEARCH;
#else
    return EXCEPTION_EXECUTE_HANDLER;
#endif
  }
}
#endif

int _tmain(int argc, _TCHAR* argv[])
{
  AddVectoredExceptionHandler(0, F_ExceptionHandler);
  AddVectoredContinueHandler(0, L_ExceptionHandler);

#if DISABLE_SEH
  __asm   xor eax,eax
  __asm   mov dword ptr fs : [0], eax

#endif

#if ENABLE_UEF
  /* 设置uef */
  SetUnhandledExceptionFilter(MyUEF);
#endif

  printf("准备抛出单步异常\n");
  /* 激活TF标志位 */
  __asm   pushfd
  __asm   or dword ptr [esp],0x100
  __asm   popfd
  __asm   nop               //此处单步异常
  printf("准备抛出断点异常\n");
  /* 触发int3断点 */
  __asm   int 3             //此处断点异常
  __asm   nop

	return 0;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (25)
雪    币: 116
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
目前感觉简单的总结最全的 收藏了!!!
2014-6-22 19:42
0
雪    币: 1556
活跃值: (883)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
3
比较通俗易懂,果断mark之
2014-6-22 19:45
0
雪    币: 223
活跃值: (516)
能力值: ( LV13,RANK:520 )
在线值:
发帖
回帖
粉丝
4
不错, 学习了.
2014-6-22 19:48
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
5
你才是大牛哇
2014-6-22 20:09
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
MARK一下
2014-6-22 21:23
0
雪    币: 47147
活跃值: (20445)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
7
通俗易懂,感谢分享~
2014-6-22 21:54
0
雪    币: 7373
活跃值: (4075)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
定LZ,收下啦
2014-6-23 10:02
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
etc
9
学习了123456
2014-6-23 15:53
0
雪    币: 734
活跃值: (3802)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
thank you for share,mark.
2014-6-23 16:54
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
11
标记收藏...
2014-6-24 11:45
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
路过,留个mark
2014-6-24 11:57
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
我想知道大神csdn链接,膜拜一下
2014-6-24 21:44
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
14
我不是啥子大神,如果想关注我:
CSDN博客:http://blog.csdn.net/mycsersoft
腾讯微博:http://t.qq.com/CserSoft
2014-6-24 21:48
0
雪    币: 29
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢楼主,复习了,以前也想写篇,写篇从R0漫游到R3再穿越回R0的异常机制文章,后来没时间了
2014-6-25 12:02
0
雪    币: 541
活跃值: (654)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
16
MARK
2014-6-27 13:39
0
雪    币: 95
活跃值: (119)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
写得好精彩呀
2014-6-28 09:36
0
雪    币: 299
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
确定通俗易懂?为什么都看不懂啊
2014-6-29 10:15
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
。。。。
2014-6-29 13:15
0
雪    币: 45
活跃值: (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
mark 一下 很好理解的帖子
2014-7-7 07:23
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
学习学习
2014-8-8 16:49
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
顶一个。
2015-6-2 09:52
0
雪    币: 18
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
很详细的简文
2015-6-4 16:05
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
mark下
2015-6-4 16:06
0
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
有问题,只有32位的。没有64位的向量化异常处理机制。
2015-6-4 17:21
0
游客
登录 | 注册 方可回帖
返回
//