S.E.H
操作系统或程序在运行时,难免会遇到各种各样的错误,如除零、非法内存访问、文件打 开错误、内存不足、磁盘读写错误、外设操作失败等。为了保证系统在遇到错误时不至于崩溃, 仍能够健壮稳定地继续运行下去, Windows 会对运行在其中的程序提供一次补救的机会来处理 错误,这种机制就是异常处理机制。
S.E.H 即异常处理结构体( Structure Exception Handler) ,它是 Windows 异常处理机制所采 用的重要数据结构。每个 S.E.H 包含两个 DWORD 指针: S.E.H 链表 指针和异常处理函数句柄,共 8 个字节
( 1) S.E.H 结构体存放在系统栈中。
(2)当线程初始化时,会自动向栈中安装一个 S.E.H,作为线程默认的异常处理。
(3)如果程序源代码中使用了__try{}__except{}或者 Assert 宏等异常处理机制,编译器将 最终通过向当前函数栈帧中安装一个 S.E.H 来实现异常处理。
(4)栈中一般会同时存在多个 S.E.H。
(5)栈中的多个 S.E.H 通过链表指针在栈内由栈顶向栈底串成单向链表,位于链表最顶端 的 S.E.H 通过 T.E.B(线程环境块) 0 字节偏移处的指针标识。
(6)当异常发生时,操作系统会中断程序,并首先从 T.E.B 的 0 字节偏移处取出距离栈顶 最近的 S.E.H,使用异常处理函数句柄所指向的代码来处理异常
(7)当离“事故现场”最近的异常处理函数运行失败时,将顺着 S.E.H 链表依次尝试其他
的异常处理函数。如果程序安装的所有异常处理函数都不能处理,系统将采用默认的异常处理函数。通 常,这个函数会弹出一个错误对话框,然后强制关闭程序。
从程序设计的角度来讲, S.E.H 就是在系统关闭程序之前,给程序一个执行预先设定的回 调函数(call back )的机会。大概明白了 S.E.H 的工作原理之后,聪明的读者朋友们可能已经 发现了问题所在。 S.E.H 存放在栈内,故溢出缓冲区的数据有可能淹没 S.E.H。
(2)精心制造的溢出数据可以把 S.E.H 中异常处理函数的入口地址更改为 shellcode 的起始 地址。 (3)溢出后错误的栈帧或堆块数据往往会触发异常。 4)当 Windows 开始处理溢出后的异常时,会错误地把 shellcode 当作异常处理函数而 执行。
以上就是利用 Windows 异常处理机制的基本思路。利用异常处理机制往往也是一些高级漏洞利用技 术的关键所在。
在栈溢出中利用 S.E.H
1 |
|
实验环境
windows 2000 release生成
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com