8.1 SafeSEH对异常处理的保护原理

        SafeSEH的原理:在程序调用异常处理函数前,对要调用的异常处理函数进行一系列的有效性校验,当发现异常处理函数不可靠时将终止异常处理函数的调用。

        safeSEH的实现需要操作系统编译器的双重支持,二者缺一都会降低SafeSEH的保护能力。

1、编译器所做工作

        首先看下编译器在SafeSEH机制中所做的工作。通过启用/SafeSEH连接选项可以让编译好的程序具备SafeSEH功能,这一链接选项在VS2003之后默认开启。

        启用该链接选项之后,编译器在编译程序的时候将程序所有的异常处理函数地址提取出来,编入一张安全SEH表,并将这张表放在程序的映像里面。当程序调用异常处理函数的时候,会将函数地址与安全SEH表进行匹配,检查调用的异常处理函数是否位于安全SEH表中。

        下图是同一段代码在VC++6.0和VS2008分别编译后安全SEH表的区别:

         注:具有SafeSEH编译能力的VS 2008在编译程序时将程序中的异常处理函数的地址提取出来放到安全S.E.H表中。

 

 2、操作系统所做工作

        (1)检查异常处理链是否位于当前程序的栈中。如果不在当前栈中,程序将终止异常处理函数的调用;

        (2)检查异常处理函数指针是否指向当前程序的栈中。如果指向当前栈中,程序将会终止异常处理函数的调用;

        (3)在前面两项检查都通过后,程序将会调用一个全新的函数RtlIsValidHandler(),来对异常处理函数的有效性进行验证。

3、关于函数RtlIsValidHandler()流程

        该函数判断异常处理函数是不是在加载模块的内存空间,如果属于加载模块的内存空间,校验函数将依次进行如下校验:

        (1)判断程序是否设置了IMAGE_DLLCHARACTERISTICS_NO_SET标识。如果设置了这个标识,这个程序内的异常将会被忽略。所以当这个标志被设置时,函数直接返回校验失败;

        (2)检测程序是否包含安全SEH表。如果程序包含安全SEH表,则将当前的异常处理函数地址与该表进行匹配,匹配成功则返回校验成功,匹配失败则返回校验失败;

        (3)判断程序是否设置ILonly标识。如果设置了这个标识,说明该程序只包含.NET编译人中间语言,函数直接返回校验失败;

        (4)判断异常处理函数地址是否位于不可执行页上。当异常处理函数地址位于不可执行页上时,校验函数将检测DEP是否开启,如果系统未开启DEP则返回校验成功,否则程序抛出访问违例的异常;

        如果异常处理函数的地址没有包含在加载模块的内存空间,校验函数将直接进行DEP相关检测,函数依次进行如下校验:
        (1)判断异常处理函数是否位于不可执行页上。当异常处理函数位于不可执行页上时,校验函数将检测DEP是否开启,如果系统未开启DEP则返回校验成功,否则程序抛出访问违例的异常;

        (2)判断系统是否允许跳转到加载模块的内存空间外执行,如果允许则返回校验成功,否则返回校验失败。

        RtlIsValidHandler()函数的校验流程如下图所示:

 

        S.E.H终极特权——如果S.E.H中的异常函数指针指向堆区,即使安全校验发现了S.E.H可能不可信,仍然会调用其已经被修改过的异常处理函数。因此只要将shellcode布置到堆区就可以直接跳转执行。

        注:这节所有的有关绕过safeS.E.H机制的讨论都不考虑DEP的影响。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值