《0day安全:软件漏洞分析技术》
我目前跨过了栈和堆的实践部分......因为......实践的时候遇到一些尴尬的问题,调试了很长时间,还是没有解决,所以我决定先到后面的章节看看。今天看的是第6章《形形色色的内存攻击技术》,内容基本都是书中原文,作者,写得真的太好了,虽然这本书有点老....但是我们需要了解历史,总结历史!
S.H.E概述
异常处理机制:为了保证系统在遇到错误时,不至于奔溃,仍能稳健地继续运行,Windows会对运行在其中的程序提供一次不久的机会来处理错误,这种机制,就是异常处理机制
S.E.H:是异常处理结构体(Structure Exception Handler),它是Windows异常处理机制所采用的重要数据结构。每个S.E.H包含两个DWORD指针:S.E.H链表指针和异常处理函数句柄,共8个字节,见下图。
基本知识点:
- S.E.H结构体存放在系统栈中。
- 当线程初始化时,会自动向栈中安装一个S.E.H,作为线程默认的异常处理。
- 如果程序源代码中使用了_try{}_except{}或者Assert宏等异常处理机制,编译器将最终通过向当前函数栈帧中安装一个S.E.H来实现异常处理。
- 栈中一般会同时存在多个S.E.H。
- 栈中的多个S.E.H通过链表指针在栈内由栈顶向栈底串成单向链表,位于链表最顶端的S.E.H通过T.E.B(线程环境块)0字节偏移处的指针表识。
- 当异常发生时,操作系统会中断程序,首先从T.E.B的0字节便宜处取出距离栈顶最近的S.E.H,使用异常处理函数句柄所知新的代码处理异常。
- 当离“事故现场”最近的异常处理函数运行失败时,将顺着S.E.H链表依次尝试其他的异常处理函数。
- 如果程序安装的所有异常处理函数都不能处理,系统将采用默认的异常处理函数。通常,这个函数会弹出一个错误对话框,然后强制关闭程序。
从程序设计的角度来讲,S.E.H就是系统在关闭程序之前,给程序一个执行预先设定的回调函数的机会。(So,想到什么了么,比如栈溢出淹没S.E.H中异常处理函数的入口地址,植入shellcode)
不同级别的S.E.H
异常处理的最小作用域是线程,每个线程都拥有自己的S.H.E链表。线程发生错误时,首先将使用自身的S.E.H进行处理。当线程无法解决异常的时候,进程S.E.H将发挥作用。当所有的异常处理函数都无法处理错误时,操作系统提供的默认的异常处理函数将会最终被调用。
uwind(截图自原书)