异常处理流程

     

     对于CPU级的异常,CPU会通过IDT表寻找异常的处理函数,也就是KiTrapXX例程,会调用CommonDispatchException准备参数,然后调用内核分发函数KiDispatchException进行异常分发。

     下面的图是内核异常分发总管KiDispatchException处理的流程。

内核态异常的分发过程:
  1.如果PreviousMode为KernelMode(0),那么对于第一轮处理机会,KiDispatchException会试图先通知内核调试器来处理该异常。
  2.内核变量KiDebugRoutine用来标识内核调试引擎交互的接口函数。当内核调试引擎启用时,KiDebugRoutine指向内核调试引擎KdpTrap,这个函数会进一步把异常信息封装为数据包发送给内核调试器,当调试内核调试引擎没有启用时,KiDebugRoutine指向KdpStub函数,简单处理后返回
  3.如果KiDebugRoutine返回TRUE,也就是内核引擎处理了异常,那么KiDispatchException便停止继续分发,准备返回。如果KiDebugRoutine返回FALSE,也就是没有处理该异常,那么KiDispatchException会调用RtlDispatchException函数,试图寻找已经注册的结构化异常处理器(SEH)。会遍历异常登记链表,依次执行每个异常处理器。如果某个处理器除了了,RtlDispatchException返回TRUE,否则返回FALSE
  4.RtlDispatchException返回FALSE,KiDispatchException会试图给内核调试器第二次机会,如果KiDebugRoutine仍然返回FALSE,那么KiDispatchException会认为这是无人处理的异常,会调用KeBugCheckEx

用户态异常的分发过程:
  1.如果前一模式是用户模式,即PreviousMode参数等于UserMode(1),对于第一次处理机会,KiDispatchException会试图将异常分发给用户态的调试器,如果DebugPort不为空,将异常发送给调试子系统,调试子系统将异常发送给调试器,如果处理了异常分发结束。
  2.如果调试器没有处理该异常,KiDispatchException修改用户态栈,返回用户层之后执行KiUserExceptionDispatcher,此函数会调用RtlDispatchException来寻找异常处理器,首先遍历VEH,然后遍历SEH,。如果RtlDispatchException返回FALSE,并且当前进程在被调试,那么KiUserExceptionDispatcher会调用ZwRaiseException并将FirstChance设置为FALSE,进行第二轮分发。如果没有被调试,结束进程。
  3.ZwRaiseException会通过内核服务NtRaiseException把异常传递给KiDispatchException来进行分发。第二次,将异常传递给调试器,如果没有处理将异常分配给ExceptionPort异常端口监听者处理,如果返回FALSE,结束进程。

转载于:https://www.cnblogs.com/aliflycoris/p/5744539.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值