首页 > 其他分享 >关于软异常

关于软异常

时间:2022-12-28 17:22:05浏览次数:34  
标签:返回 EXCEPTION RaiseException RtlRaiseException ntdll 关于 异常

CPU执行指令时可能会触发异常,例如除0错误,内存访问错误,这种称为“硬异常”。

还有一种可以通过软件模拟异常,通过调用windows API函数 RaiseException可以主动触发异常。

如下:

RaiseException(EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_NONCONTINUABLE, 0, NULL);

第二个参数是dwExceptionFlags,如果为EXCEPTION_NONCONTINUABLE说明此异常 不可继续,也就是说异常过滤函数不可以返回EXCEPTION_CONTINUE_EXECUTION,不然会触发嵌套异常STATUS_NONCONTINUABLE_EXCEPTION,对应0xC0000025L

嵌套异常中EXCEPTION_RECORD结构体中变量struct _EXCEPTION_RECORD *ExceptionRecord指向了之前触发的异常。如果第二个参数传入0,那么代表异常处理后可以继续执行代码,过滤函数可以返回EXCEPTION_CONTINUE_EXECUTION。

RaiseException的调用函数大致流程如下

  RaiseException->RtlRaiseException->
        ntdll!RtlCaptureContext
        ntdll!NtRaiseException(之后还有 ntdll!RtlRaiseStatus )

  RtlRaiseException中会调用ntdll!RtlCaptureContext,获取上下文,Context中的EIP为RtlRaiseException的返回地址,如果可以继续,那么会直接返回到RaiseException中call RtlRaiseException的后面。

  接着RtlRaiseException调用ntdll!NtRaiseException
  正常情况下 调用ntdll!NtRaiseException之后是不会返回的
    //分几种情况

    1、如果捕获异常并EXCEPTION_EXECUTE_HANDLER长跳转 那么必定不会返回 也不会ntcontinue返回内核
    2、如果捕获异常处理异常了可以继续执行 那么会NtContinue返回内核 设置eip 返回到RaiseException中调用RtlRaiseException的后面 直接跳的 内核设置eip
    3、如果处理不了异常 那么肯定也不会返回了
    如果返回那么调用RtlRaiseStatus抛出异常 传入参数为上一个函数的返回值 可能传参出错,此时需要解决的不是原来的异常 而是此时的异常。

 

软异常存在嵌套异常,即_EXCEPTION_RECORD *ExceptionRecord可以不为空。

当异常触发时如果在过滤函数中再次触发了硬异常,那么还会由当前的SEH节点捕获到异常,造成递归,可能会导致栈上溢。

如果异常返回EXCEPTION_EXECUTE_HANDLER,那么在执行长跳转后执行代码时,此时上面的SEH框架所代表的那个节点已经从节点摘除了(在不存在形式SEH框架的情况下),如果在长跳转后的代码中出现异常,那么异常会由上一层SEH节点捕获到。

 

标签:返回,EXCEPTION,RaiseException,RtlRaiseException,ntdll,关于,异常
From: https://www.cnblogs.com/ps12345678/p/17010834.html

相关文章