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

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

bxc 活跃值
6
2014-6-22 19:04
21762
1
LONG NTAPI ExceptionHandler(struct _EXCEPTION_POINTERS[CODE]
1
2
3
4
5
6
EXCEPTION_DISPOSITION __cdecl _except_handler ( 
    _In_ struct _EXCEPTION_RECORD *_ExceptionRecord,  //异常记录结构指针
    _In_ void * _EstablisherFrame,             //指向EXCEPTION_REGISTRATION结构,即SEH链
    _Inout_ struct _CONTEXT *_ContextRecord,      //Context结构指针 (线程上下文)
    _Inout_ void * _DispatcherContext           //无意义 (调度器上下文?)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/* 浮点寄存器 */
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;
1
2
3
push handler    // 异常处理函数的地址
push fs:[0]     // 前一个异常处理函数函数的地址
mov fs:[0], esp     // 装入新的SEH链结构
1
2
3
4
5
6
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,      //0
    ExceptionContinueSearch,          //1
    ExceptionNestedException,        //2
    ExceptionCollidedUnwind            //3
} EXCEPTION_DISPOSITION;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#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;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 5
支持
分享
赞赏记录
参与人
雪币
留言
时间
飘零丶
为你点赞~
2024-5-31 02:59
shinratensei
为你点赞~
2024-5-31 02:43
PLEBFE
为你点赞~
2023-3-5 04:09
Re_Upper
为你点赞~
2023-1-2 23:48
CalvinMcCain
为你点赞~
2019-1-21 15:54
最新回复 (25)
雪    币: 116
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
目前感觉简单的总结最全的 收藏了!!!
2014-6-22 19:42
0
雪    币: 1555
活跃值: (948)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
3
比较通俗易懂,果断mark之
2014-6-22 19:45
0
雪    币: 223
活跃值: (516)
能力值: ( LV13,RANK:520 )
在线值:
发帖
回帖
粉丝
4
不错, 学习了.
2014-6-22 19:48
0
雪    币: 7068
活跃值: (3552)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
5
你才是大牛哇
2014-6-22 20:09
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
MARK一下
2014-6-22 21:23
0
雪    币: 55923
活跃值: (21575)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
7
通俗易懂,感谢分享~
2014-6-22 21:54
0
雪    币: 7701
活跃值: (4491)
能力值: ( 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
雪    币: 1321
活跃值: (4804)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
thank you for share,mark.
2014-6-23 16:54
0
雪    币: 2672
活跃值: (3475)
能力值: ( 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
雪    币: 7068
活跃值: (3552)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
14
我不是啥子大神,如果想关注我:
CSDN博客:http://blog.csdn.net/mycsersoft
腾讯微博:http://t.qq.com/CserSoft
2014-6-24 21:48
0
雪    币: 29
活跃值: (127)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢楼主,复习了,以前也想写篇,写篇从R0漫游到R3再穿越回R0的异常机制文章,后来没时间了
2014-6-25 12:02
0
雪    币: 541
活跃值: (669)
能力值: ( 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
活跃值: (453)
能力值: ( 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
活跃值: (523)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
有问题,只有32位的。没有64位的向量化异常处理机制。
2015-6-4 17:21
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册