zoukankan      html  css  js  c++  java
  • 内核层异常的收集与处理

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

    内核层异常的收集与处理

      前面我们分析过,存在两种异常,CPU异常与用户模拟异常,其异常触发时收集的线路是不同的,但是其最终走经过KiDispatchException函数。

      当走到KiDispatchException,CPU异常与用户模拟异常唯一的区别是CPU异常最高位置1(nt!KiRaiseException异常派发时的上一行代码),其余记录的都是一样的。

      而KiDispatchException的处理是按照其先前模式来处理的,也就是内核异常与用户异常两种,而不是按照CPU异常与用户模拟异常来进行处理。

     

    1.内核层异常的派发(Nt!KiDispatchException函数分析)

      这部分我们先看内核异常的处理流程,至于用户模式,其因为要返回三环执行,稍微复杂,等其分析完成之后再来一起进行汇总处理。

      如下图,我们截取一部分,其核心的执行流程为:

      ① 如果存在内核调试器则调用内核调试器;

      ② 如果不存在或者不成功,调用RtlDispatchException调用内核的SEH异常来进行处理;

      ③ 如果RtlDispatchException不成功,则再次尝试判断内核调试器;

      ④ 如果上面某一步成功,则直接返回正常退出;

      ⑤ 否则调用KeBugCheckEx触发蓝屏。

      

    2.内核层异常的处理(Nt!RtlDispatchException函数分析)

      该函数是处理内核异常的核心函数,如果没有内核调试器,则就使用这个函数来进行分析,其操作如下所示:

      其中,我们在分析前必须要有几个重要的数据结构:

      1)异常的标志位 flag

        #define EXCEPTION_NONCONTINUABLE 0x1    // Noncontinuable exception
        #define EXCEPTION_UNWINDING 0x2         // Unwind is in progress
        #define EXCEPTION_EXIT_UNWIND 0x4       // Exit unwind is in progress
        #define EXCEPTION_STACK_INVALID 0x8     // Stack out of limits or unaligned
        #define EXCEPTION_NESTED_CALL 0x10      // Nested exception handler call
        #define EXCEPTION_TARGET_UNWIND 0x20    // Target unwind in progress
        #define EXCEPTION_COLLIDED_UNWIND 0x40  // Collided exception handler call

      2)异常结果的返回值

          enum _EXCEPTION_DISPOSITION {
            ExceptionContinueExecution = 0,  // 异常处理成功
            ExceptionContinueSearch = 1,    // 异常没有处理,继续寻找
            ExceptionNestedException = 2,   // 二次异常,存在嵌套异常
            ExceptionCollidedUnwind = 3   // 发生嵌套的展开
          };

        注意:如果是SEH扩展的异常,我们使用这个,因为其使用SEH拓展结构,需要进行异常展开的操作,这些对程序员是不可见的。

        平时我们再手动写SEH异常,不需要操心异常的展开等额外操作,所以使用下面的结构:

         #define EXCEPTION_EXECUTE_HANDLER      1     // 异常被识别,_except模块中处理该异常
         #define EXCEPTION_CONTINUE_SEARCH      0    // 异常未被识别,继续调用下一个Handler来处理异常
         #define EXCEPTION_CONTINUE_EXECUTION (-1)   // 异常已被忽略或修复,不继续往下寻找

      该函数的核心操作如下:

      ① 通过KPCR获取异常链;

      ② 取出一个异常处理结点,ExceptionRegistrationRecord(next,handler);

      ③ 通过全局变量判断是否需要异常记录;

      ④ 执行对应的handler函数,获取返回结果;

      ⑤ 如果返回为 ExceptionContinueExecution并且eflags的EXCEPTION_NONCONTINUABLE位为0,则返回成功;

      ⑥ 否则继续找下一个,处理失败,或者引发二次异常。

       

    3.总结

      这里我们只是简单分析了一下内核层的SEH异常的大体流程,其中我们会发现二次异常的嵌套以及展开UnWind等操作,这里可能会让你感到头晕,

      没关系,我们在分析用户异常时会详细解释其编译器对于SEH异常的拓展,之后我们会讲解局部展开与全局展开等骚操作,之后你再看这里就能很好理解了。

  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12771544.html
Copyright © 2011-2022 走看看