zoukankan      html  css  js  c++  java
  • 第八章——Windows下异常处理-SEH的概念及基本知识

    1.SEH相关结构
        ①TIB
            TIB是保存线程基本信息结构体,它位于TEB头部,而TEB在FS:[0]处(0X7FFDE000)之前的笔记中提及过。具体的TIB结构如下:
            typedef struct _NT_TIB {            //sizeof 1ch
                     00h     struct _EXCEPTION_REGISTRATION *ExceptionList; //SEH链入口
                     04h     PVOID StackBase; //线程所使用的栈的栈底
                     08h     PVOID StackLimit; //线程所使用的栈的栈顶
                     0ch     PVOID SubSystemTib;
                       union {
                        PVOID FiberData;
                        10h DWORD Version;
                        };
                    14h     PVOID ArbitraryUserPointer;
                    18h     struct _NT_TIB *Self; //本NT_TIB结构自身的线性地址
            }NT_TIB;
    其中的第一个字段就是指向异常处理链的入口指针,它位于TIB位移0处,而TEB的偏移0处也是它。
     
        ②_EXCEPTION_REGISTRATION_RECORD
            这个结构体主要描述了TEB为0处的异常处理链
            typedef struct _EXCEPTION_REGISTRATION_RECORD {
            struct _EXCEPTION_REGISTRATION_RECORD *Next;      //指向下一个 EXCEPTION_REGISTRATION_RECORD,由此构成一个异常注册信息链表。
            PEXCEPTION_ROUTINE Handler;  //指向异常处理函数       //链表中的最后一个结点会将 Next 置为 EXCEPTION_CHAIN_END,表示链表到此结束。
    } EXCEPTION_REGISTRATION_RECORD;
            其中next指向下一个ERR指针,形成一链状,Handler为异常处理函数,当有异常发生的时候,系统会在fs:[0]处获取异常处理链的表头,然后依次查找各个异常处理回调函数,由于TEB是线程的私有数据结构,SEH的处理机制也是使用与当前线程
     
        ③_EXCEPTION_POINTERS结构
            typedef struct _EXCEPTION_POINTERS
            {
                PEXCEPTION_RECORD ExceptionRecord; //指向一个EXCEPTION_RECORD结构
                PCONTEXT ContextRecord;                     //指向向一个CONTEXT结构
            }
             当有异常发生时候,系统会将异常信息交给用户态的异常处理过程。但是在这个过程中,同一个线程在用户态和内核态使用的是两个不同的栈,为了让用户态能够处理和访问异常相关数据,操作系统就将   PEXCEPTION_RECORD和PCONTEXT封装在一个结构体中,这样用户态处理程序就能够取得异常的信息和发生异常时线程的状态来具体处理异常。
     
     
    2.SEH处理程序的安装与卸载
        由于FS:[0]指向异常处理的表头,所以这里只需要安装一个新的SEH异常处理程序,填写一个新的_EXCEPTION_REGISTRATION_RECORD结构,将其插入该链表的头部即可
        push  offset SEHandler
        push  fs:[0]
        push  fs:[0],esp
    上述三行意思为,现将新的异常回调函数以及fs:[0]构造出一个_EXCEPTION_REGISTRATION_RECORD结构,此时它的位置就在栈顶,就是esp的位置,在将esp保存到fs:[0]中,这样就构造好一个新的SEH表头
     
    卸载表头:
        mov esp , fs:[0]
        pop  fs:[0]
        先将链中第二个放入栈顶,接着将表头删除
     
  • 相关阅读:
    Sql server 经典常用函数
    Sql Server 时间格式化
    eval解析JSON中的注意点
    SQL Server 数据库try catch 存储过程
    SQL 添加索引
    sql中的begin catch 。。。end catch 的用法
    常用正则表达式
    css3实现背景渐变
    CacheHelper
    星座运势(等)接口控制器
  • 原文地址:https://www.cnblogs.com/Tempt/p/10236052.html
Copyright © 2011-2022 走看看