首页
社区
课程
招聘
[原创]从TEB到PEB再到SEH(二)
发表于: 2018-1-9 18:45 12467

[原创]从TEB到PEB再到SEH(二)

2018-1-9 18:45
12467

什么是SEH?

Windows下各种异常处理的优先级 

认识SEH链及处理机制

SEH的注册及SEH的删除

异常的种类和常见的异常代码

SEH的异常处理

小结

SEH( Structured Exception Handling , 结构化异常处理 )

结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能。而Visual C++中的__try{}/__finally{}和__try{}/__except{}结构本质上是对Windows提供的SEH的封装

STATUS_ACCESS_VIOLATION(0xC0000005)

STATUS_BREAKPOINT(0x80000003

STATUS_ILLEGAL_INSTRUCTION(0xC000001D)

STATUS_INTEGER_DIVIDE_BY_ZERO(0xC0000094)

STATUS_SINGLE_STEP

  • 什么是SEH?

  • Windows下各种异常处理的优先级 

  • 认识SEH链及处理机制

  • SEH的注册及SEH的删除

  • 异常的种类和常见的异常代码

  • SEH的异常处理

  • 小结

上一章简单介绍了TEB PEB在fs寄存器中的位置及常用的结构体成员,接下来我们开始认识SEH:


(一)、 什么是SEH?

SEH( Structured Exception Handling , 结构化异常处理 )

结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能。而Visual C++中的__try{}/__finally{}和__try{}/__except{}结构本质上是对Windows提供的SEH的封装


在这里可以看到我们把EAX的值置为空指针,然后向空指针里写入值,引发 STATUS_ACCESS_VIOLATION(内存访问异常) ,然后在异常处理里面把
EAX的值设置为 变量dwTest的地址,然后返回 EXCEPTION_CONTINUE_EXECUTION 表示异常被处理,从异常处继续执行,这里是MSDN
对于异常处理( Exception Handling )返回值的定义:
#define EXCEPTION_EXECUTE_HANDLER       1        //表示异常被处理,从下一条指令开始执行
#define EXCEPTION_CONTINUE_SEARCH       0        //表示异常未被处理,交由下一个SEH
#define EXCEPTION_CONTINUE_EXECUTION    -1    //表示异常被处理,从异常处开始执行
对于上面这段定义,很多人给出的注释不同,以上注释是我对他们的实验结果和理解。

#define EXCEPTION_EXECUTE_HANDLER       1        //表示异常被处理,从下一条指令开始执行
#define EXCEPTION_CONTINUE_SEARCH       0        //表示异常未被处理,交由下一个SEH
#define EXCEPTION_CONTINUE_EXECUTION    -1    //表示异常被处理,从异常处开始执行
对于上面这段定义,很多人给出的注释不同,以上注释是我对他们的实验结果和理解。

(二)、 Windows下各种异常处理的优先级 
PVOID WINAPI AddVectoredExceptionHandler(
  _In_  ULONG FirstHandler,
  _In_  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);
PVOID WINAPI AddVectoredContinueHandler(
  _In_  ULONG FirstHandler,
  _In_  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

向进程里注册一个异常捕获函数,参数FirstHandler 决定插入到链表的位置(非0为头部, 0为底部 ) ,异常处理中最后执行

PVOID WINAPI AddVectoredContinueHandler(
  _In_  ULONG FirstHandler,
  _In_  PVECTORED_EXCEPTION_HANDLER VectoredHandler
);
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
  _In_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
TopLevelEH 为线程顶级异常处理器,通常可以处理到所有线程消息发生的异常。

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
  _In_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);
TopLevelEH 为线程顶级异常处理器,通常可以处理到所有线程消息发生的异常。

这里我们可以发现以上异常处理回调函数参数大都为 EXCEPTION_POINTERS 结构体,我们查询下它的结构:
typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
EXCEPTION_RECORD:
typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;          //异常码,以STATUS_或EXCEPTION_开头,可自定义。(sehdef.inc)
    DWORD ExceptionFlags;            //异常标志。0可修复;1不可修复;2正在展开,不要试图修复
    struct _EXCEPTION_RECORD *ExceptionRecord; //指向嵌套的异常结构,通常是异常中又引发异常
    PVOID ExceptionAddress;          //异常发生的地址
    DWORD NumberParameters;      //下面ExceptionInformation所含有的dword数目
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加消息,如读或写冲突
} EXCEPTION_RECORD;
CONTEXT:
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;
CONTEXT结构体大家应该都懂!
typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
EXCEPTION_RECORD:
typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;          //异常码,以STATUS_或EXCEPTION_开头,可自定义。(sehdef.inc)
    DWORD ExceptionFlags;            //异常标志。0可修复;1不可修复;2正在展开,不要试图修复
    struct _EXCEPTION_RECORD *ExceptionRecord; //指向嵌套的异常结构,通常是异常中又引发异常
    PVOID ExceptionAddress;          //异常发生的地址
    DWORD NumberParameters;      //下面ExceptionInformation所含有的dword数目
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加消息,如读或写冲突
} EXCEPTION_RECORD;
CONTEXT:
typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;          //异常码,以STATUS_或EXCEPTION_开头,可自定义。(sehdef.inc)
    DWORD ExceptionFlags;            //异常标志。0可修复;1不可修复;2正在展开,不要试图修复
    struct _EXCEPTION_RECORD *ExceptionRecord; //指向嵌套的异常结构,通常是异常中又引发异常
    PVOID ExceptionAddress;          //异常发生的地址
    DWORD NumberParameters;      //下面ExceptionInformation所含有的dword数目
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //附加消息,如读或写冲突
} EXCEPTION_RECORD;
CONTEXT:
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;
CONTEXT结构体大家应该都懂!
下面我们简单的写一个Demo,试验一下他们的处理顺序:
// SEHTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

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

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

//
LONG NTAPI TopLevelExcepFilter(EXCEPTION_POINTERS *pExcepInfo)
{
	printf("TopLevelEHandler\n");
	return EXCEPTION_CONTINUE_EXECUTION;
}
//
LONG NTAPI SEHander(EXCEPTION_POINTERS *ExceptionInfo){
	//异常处理
	printf("SEHandler\n");

	return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR* argv[])
{
	AddVectoredExceptionHandler(0,VEHandler);
	AddVectoredContinueHandler(0,VCHandler);
	SetUnhandledExceptionFilter(&TopLevelExcepFilter);
	__try
	{
		__asm int 3
	}
	__except (SEHander(GetExceptionInformation()))
	{
	}
	system("Pause");
	return 0;
}
我们分别注册了VEH、VCH、 TopLevalEH 、SEH,我们看下结果:
// SEHTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

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

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

//
LONG NTAPI TopLevelExcepFilter(EXCEPTION_POINTERS *pExcepInfo)
{
	printf("TopLevelEHandler\n");
	return EXCEPTION_CONTINUE_EXECUTION;
}
//
LONG NTAPI SEHander(EXCEPTION_POINTERS *ExceptionInfo){
	//异常处理
	printf("SEHandler\n");

	return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR* argv[])
{
	AddVectoredExceptionHandler(0,VEHandler);
	AddVectoredContinueHandler(0,VCHandler);
	SetUnhandledExceptionFilter(&TopLevelExcepFilter);
	__try
	{
		__asm int 3
	}
	__except (SEHander(GetExceptionInformation()))
	{
	}
	system("Pause");
	return 0;
}
我们分别注册了VEH、VCH、 TopLevalEH 、SEH,我们看下结果:

他们处理异常的优先级为:
  1. 调试器
  2. VEH
  3. SEH
  4. UEF
  5. VCH
为什么调试器在第一个呢?因为我们发现在VS里面调试直接接管了异常。(/手动滑稽)
为什么调试器在第一个呢?因为我们发现在VS里面调试直接接管了异常。(/手动滑稽)

(三)、 认识SEH链及处理机机制
ntdll!_TEB
   +0x000 NtTib            : _NT_TIB                //SEH链表头指针
   +0x01c EnvironmentPointer : Ptr32 Void
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : Ptr32 Void
   +0x02c ThreadLocalStoragePointer : Ptr32 Void
   +0x030 ProcessEnvironmentBlock : Ptr32 _PEB
   +0x034 LastErrorValue   : Uint4B
   +0x038 CountOfOwnedCriticalSections : Uint4B
   +0x03c CsrClientThread  : Ptr32 Void
   +0x040 Win32ThreadInfo  : Ptr32 Void
   +0x044 User32Reserved   : [26] Uint4B
   +0x0ac UserReserved     : [5] Uint4B
   +0x0c0 WOW32Reserved    : Ptr32 Void
   +0x0c4 CurrentLocale    : Uint4B
   +0x0c8 FpSoftwareStatusRegister : Uint4B
   +0x0cc SystemReserved1  : [54] Ptr32 Void
   +0x1a4 ExceptionCode    : Int4B
   +0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK
   +0x1bc SpareBytes1      : [24] UChar
   +0x1d4 GdiTebBatch      : _GDI_TEB_BATCH
   +0x6b4 RealClientId     : _CLIENT_ID
   +0x6bc GdiCachedProcessHandle : Ptr32 Void
   +0x6c0 GdiClientPID     : Uint4B
   +0x6c4 GdiClientTID     : Uint4B
   +0x6c8 GdiThreadLocalInfo : Ptr32 Void
   +0x6cc Win32ClientInfo  : [62] Uint4B
   +0x7c4 glDispatchTable  : [233] Ptr32 Void
   +0xb68 glReserved1      : [29] Uint4B
   +0xbdc glReserved2      : Ptr32 Void
   +0xbe0 glSectionInfo    : Ptr32 Void
   +0xbe4 glSection        : Ptr32 Void
   +0xbe8 glTable          : Ptr32 Void
   +0xbec glCurrentRC      : Ptr32 Void
   +0xbf0 glContext        : Ptr32 Void
   +0xbf4 LastStatusValue  : Uint4B
   +0xbf8 StaticUnicodeString : _UNICODE_STRING
   +0xc00 StaticUnicodeBuffer : [261] Uint2B
   +0xe0c DeallocationStack : Ptr32 Void
   +0xe10 TlsSlots         : [64] Ptr32 Void
   +0xf10 TlsLinks         : _LIST_ENTRY
   +0xf18 Vdm              : Ptr32 Void
   +0xf1c ReservedForNtRpc : Ptr32 Void
   +0xf20 DbgSsReserved    : [2] Ptr32 Void
   +0xf28 HardErrorsAreDisabled : Uint4B
   +0xf2c Instrumentation  : [16] Ptr32 Void
   +0xf6c WinSockData      : Ptr32 Void
   +0xf70 GdiBatchCount    : Uint4B
   +0xf74 InDbgPrint       : UChar
   +0xf75 FreeStackOnTermination : UChar
   +0xf76 HasFiberData     : UChar
   +0xf77 IdealProcessor   : UChar
   +0xf78 Spare3           : Uint4B
   +0xf7c ReservedForPerf  : Ptr32 Void
   +0xf80 ReservedForOle   : Ptr32 Void
   +0xf84 WaitingOnLoaderLock : Uint4B
   +0xf88 Wx86Thread       : _Wx86ThreadState
   +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
   +0xf98 ImpersonationLocale : Uint4B
   +0xf9c IsImpersonating  : Uint4B
   +0xfa0 NlsCache         : Ptr32 Void
   +0xfa4 pShimData        : Ptr32 Void
   +0xfa8 HeapVirtualAffinity : Uint4B
   +0xfac CurrentTransactionHandle : Ptr32 Void
   +0xfb0 ActiveFrame      : Ptr32 _TEB_ACTIVE_FRAME
   +0xfb4 SafeThunkCall    : UChar
   +0xfb5 BooleanSpare     : [3] UChar
typedef struct _NT_TIB {
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID SubSystemTib;
#if defined(_MSC_EXTENSIONS)
    union {
        PVOID FiberData;
        DWORD Version;
    };
#else
    PVOID FiberData;
#endif
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;
如上述代码所示 结构体成员 ExceptionList 即为SEH链的头部指针 
So、 fs:[0]即为SEH链的指针,我们接着看对于SEH链的定义:
typedef struct _EXCEPTION_REGISTRATION_RECORD {
    struct _EXCEPTION_REGISTRATION_RECORD *Next;
    PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD;
第一个成员 Next 为指向下一个链表的指针,直到遇到 0xFFFFFFFF 结束,而结构体成员 Handler 为SEH的异常处理函数指针,我们接着看它对于
SEH异常处理函数 EXCEPTION_ROUTINE 的定义:
typedef
_IRQL_requires_same_
_Function_class_(EXCEPTION_ROUTINE)
EXCEPTION_DISPOSITION
NTAPI
EXCEPTION_ROUTINE (
    _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,
    _In_ PVOID EstablisherFrame,
    _Inout_ struct _CONTEXT *ContextRecord,
    _In_ PVOID DispatcherContext
    );
可以看到它对于SEH定义了以 EXCEPTION_DISPOSITION 为返回值的回调函数,我们接着查看它们的定义:
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,        //继续执行异常代码
    ExceptionContinueSearch,            //运行下一个异常处理器
    ExceptionNestedException,           //在OS内部使用
    ExceptionCollidedUnwind             //在OS内部使用
} EXCEPTION_DISPOSITION;
接着我们整理下它的异常处理过程:

typedef struct _EXCEPTION_REGISTRATION_RECORD {
    struct _EXCEPTION_REGISTRATION_RECORD *Next;
    PEXCEPTION_ROUTINE Handler;
} EXCEPTION_REGISTRATION_RECORD;
第一个成员 Next 为指向下一个链表的指针,直到遇到 0xFFFFFFFF 结束,而结构体成员 Handler 为SEH的异常处理函数指针,我们接着看它对于
SEH异常处理函数 EXCEPTION_ROUTINE 的定义:
typedef
_IRQL_requires_same_
_Function_class_(EXCEPTION_ROUTINE)
EXCEPTION_DISPOSITION
NTAPI
EXCEPTION_ROUTINE (
    _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,
    _In_ PVOID EstablisherFrame,
    _Inout_ struct _CONTEXT *ContextRecord,
    _In_ PVOID DispatcherContext
    );
可以看到它对于SEH定义了以 EXCEPTION_DISPOSITION 为返回值的回调函数,我们接着查看它们的定义:
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,        //继续执行异常代码
    ExceptionContinueSearch,            //运行下一个异常处理器
    ExceptionNestedException,           //在OS内部使用
    ExceptionCollidedUnwind             //在OS内部使用
} EXCEPTION_DISPOSITION;
接着我们整理下它的异常处理过程:
typedef
_IRQL_requires_same_
_Function_class_(EXCEPTION_ROUTINE)
EXCEPTION_DISPOSITION
NTAPI
EXCEPTION_ROUTINE (
    _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,
    _In_ PVOID EstablisherFrame,
    _Inout_ struct _CONTEXT *ContextRecord,
    _In_ PVOID DispatcherContext
    );
可以看到它对于SEH定义了以 EXCEPTION_DISPOSITION 为返回值的回调函数,我们接着查看它们的定义:
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,        //继续执行异常代码
    ExceptionContinueSearch,            //运行下一个异常处理器
    ExceptionNestedException,           //在OS内部使用
    ExceptionCollidedUnwind             //在OS内部使用
} EXCEPTION_DISPOSITION;
接着我们整理下它的异常处理过程:
typedef enum _EXCEPTION_DISPOSITION {
    ExceptionContinueExecution,        //继续执行异常代码
    ExceptionContinueSearch,            //运行下一个异常处理器
    ExceptionNestedException,           //在OS内部使用
    ExceptionCollidedUnwind             //在OS内部使用
} EXCEPTION_DISPOSITION;
接着我们整理下它的异常处理过程:


(四)、 SEH的注册及SEH的删除
EXCEPTION_DISPOSITION NTAPI _except_handler(
	_Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,    //指向包含异常信息的EXCEPTION_RECORD结构
	_In_ PVOID EstablisherFrame,        //指向该异常相关的EXCEPTION_REGISTRATION结构
	_Inout_ struct _CONTEXT *ContextRecord,    //指向线程环境CONTEXT结构的指针
	_In_ PVOID DispatcherContext)
push @_except_handler    ;异常处理器
push dwod ptr fs:[0]     ;取出 SEH链表头
mov dwod ptr fs:[0],esp  ;添加链表

卸载SEH:
push @_except_handler    ;异常处理器
push dwod ptr fs:[0]     ;取出 SEH链表头
mov dwod ptr fs:[0],esp  ;添加链表

pop dword ptr fs:[0]    ;还原链表头
add esp,4    ;删除 异常处理器
这些操作很简单,很多前辈们帖子里都有,代码可能不一样,反正是一个意思就行。
pop dword ptr fs:[0]    ;还原链表头
add esp,4    ;删除 异常处理器
这些操作很简单,很多前辈们帖子里都有,代码可能不一样,反正是一个意思就行。

(五)、 异常的种类和常见的异常代码 


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

上传的附件:
收藏
免费 5
支持
分享
最新回复 (9)
雪    币: 697
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
mark,有时间认真学习下。
2018-1-10 15:46
0
雪    币: 221
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
楼主问一下,CPU通过中断描述符表(IDT)来处理中断和异常和seh的关系,两个的异常处理函数是一个吗,是一个的话,调用过程是一样吗,还是说seh就是通过IDT寻找处理函数的?谢谢
2018-1-11 14:44
0
雪    币: 697
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
Mark
2018-2-20 11:32
0
雪    币: 184
活跃值: (161)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
学习了
2018-3-20 09:40
0
雪    币: 0
活跃值: (198)
能力值: ( LV8,RANK:125 )
在线值:
发帖
回帖
粉丝
6
学习了
2018-3-31 21:57
0
雪    币: 9
活跃值: (175)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
很好了    谢谢分享
2018-5-8 23:56
0
雪    币: 8902
活跃值: (5121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jgs
8
2018-7-28 21:30
0
雪    币: 35
活跃值: (612)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢 学习了  看完这 我想到 最后的代码 E语言 是不是也用这汇编 来实现 异常模块的
2018-9-21 00:53
0
游客
登录 | 注册 方可回帖
返回
//