SEH相关数据结构(续)

继上一篇SEH相关数据结构,还有三个结构体很重要。

它们是EXCEPTION_POINTERS、EXCEPTION_RECORD、CONTEXT

当一个异常发生时,操作系统向引起异常的线程的堆栈里压入EXCEPTION_POINTERS结构:

typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

上篇文章的程序跟踪到此处时

00401017    8B06            mov eax,dword ptr ds:[esi]

Shift+F7进入异常刚发生时的系统代码处,EXCEPTION_POINTERS结构就在当前栈顶,那么当前堆栈的数据就是此结构的两个成员EXCEPTION_RECORD、CONTEXT。

EXCEPTION_RECORD结构

typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD;
这个结构包含有关最近发生异常的详细信息,这些信息独立于CPU。

这个ExceptionCode字段定义了产生异常的原因,下表列出了一些常见的异常原因:

异常原因

对应值

说明

STATUS_GUARD_PAGE_VIOLATION

080000001h

读写属性为PAGE_GUARD的页面

EXCEPTION_BREAKPOINT

080000003h

断点异常

EXCEPTION_SINGLE_STEP

080000004h

单步中断

EXCEPTION_INVALID_HANDLE

0C0000008h

向一个函数传递了一个无效句柄

EXCEPTION_ACCESS_VIOLATION

0C0000005h

读写内存冲突

EXCEPTION_ILLEGAL_INSTRUCTION

0C000001Dh

遇到无效指令

EXCEPTION_IN_PAGE_ERROR

0C0000006h

存取不存在的页面

EXCEPTION_INT_DIVIDE_BY_ZERO

0C0000094h

除零错误

EXCEPTION_STACK_OVERFLOW

0C00000FDh

堆栈溢出


00401017    8B06            mov eax,dword ptr ds:[esi]
这句会引发一个STATUS_GUARD_PAGE_VIOLATION异常,异常代码是0C0000005h

在堆栈中数据窗口跟随,发现如下:

0018FAD0  05 00 00 C0 00 00 00 00 00 00 00 00 17 10 40 00  ..?.......@.
0018FAE0  02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ...............

CONTEXT结构

CONTEXT结构是Win32API一个几乎唯一与处理器相关的结构,包括了线程运行时处理器各主要寄存器的完整镜像,用于保存线程运行环境。

其结构如下:

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;

我们可以看一下regEip处的内容,发现它正好是我们异常发生处的地址。又一个值得深入理解的结构~~~~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值