windows内核基础-2异常处理程序的安全性

1.SafeSEH机制

(1)编译器的工作 如果编译时打开这个开关,那么编译器就会在PE头的DllCharacteristics中加入一个标志,并在编译阶段提取所有异常处理程序的相对虚拟地址(RVA ),并将它放置在一个表中。这个表的位置是由PE头部的IMAGE_OPTIONAL_HEADER结构中数据目录的第10项指定的,相关定义如下。 (2)操作系统的验证 系统在对栈及栈中的EXCEPTION_REGISTRATION_RECORD结构进行初步验证之后,会调用RtlIsValidHandler对异常回调函数的有效性进行验证。

2.SEHOP机制 核心要点:

  • 检测SEH链的完整性,即每一个节点都必须在栈中,并且都可以正常访问
  • 检测最后一个节点的异常处理函数是不是位于ntdll中的ntdll!FinalExceptionHandler()。

一般在使用SEH攻击执行shellcode时,通常是用“jmp 06 pop pop ret”命令来覆盖SEH结构的,此时从当前SEH节点已经无法正确指向下一个SEH节点,所以此时完整性遭到了破坏,就可以检测出异常。

(3)SHEOP与顶层异常处理

开启SEHOP保护后,在SEH链的最后增加了一个节点,此时倒数第二个节点是前面介绍的线程顶层异常处理函数所在的节点,其实最后一个节点根本不会发生任何作用,它出现的意义,仅仅是为了检测。

向量异常化处理:

VEH和SEH的异同

当异常发生时,VEH会优先于SEH获得控制权(但如果有调试器,调试器会优先于VEH回调函数),系统会自动调用AddVectoredExceptionHandler注册的VEH回调函数。如果回调函数修复了异常,则返回EXCEPTION_CONTINUE_EXECUTION,在异常发生处以CONTEXT指定的线程环境继续运行,此时SEH处理过程将会被跳过。如果回调函数不能处理异常,就交给SEH。

  • 注册机制不同。SEH的相关信息主要保存在栈中,而且后注册的回调函数总是处于SEH链的前端,也就是说,当异常发生时,异常总是由内层回调函数先处理,只有在内层回调函数不处理异常时,外层回调函数才有机会获得控制权。而VEH不同,它的相关信息保存在独立的链表中(实际存储在ntdll)中,在注册VEH时可以指定回调函数是位于前端还是尾端。
  • 优先级不同,VEH优先于SEH被调用。
  • 作用范围不同。SEH机制是基于线程的,也就是说,同一进程内的A线程无法捕获和处理B线程产生的异常,并且对特定的SEH处理程序来说,它的作用范围更是局限在安装它的那个函数内部。而VEH在整个进程范围内都是有效的。
  • VEH不需要栈展开。由于SEH的注册和使用依赖于函数调用的栈帧,在调用SEH回调函数时会涉及栈展开的问题,这样SHE就有2次被调用的机会,因为SEH 的实现不依赖栈,所以在调用VEH回调函数前不需要进行栈展开。

 

posted @ 2024-05-07 14:40  robot__i  阅读(42)  评论(0)    收藏  举报