如何从x86_64 windows异常处理程序中正确调用rtlunwind

时间:2016-09-27 17:37:09

标签: c windows

我试图实现win64异常个性,并且无法找到有关该主题的大量文档。

我已经有了一个正在运行的win32版本,但是win64一个在rtlunwind(访问冲突)中崩溃了#34; catch" win64异常处理程序的一部分,用于展开catch处理程序框架和continuation:

int ExceptionHandler(EXCEPTION_RECORD arec, uint64_t EstablisherFrame, PCONTEXT context, PDISPATCHER_CONTEXT dispatcher)
{
  if (0 == (arec->ExceptionFlags & ( rtl.EXCEPTION_UNWINDING | rtl.EXCEPTION_EXIT_UNWIND))) 
  {
     // check if this is a catch supported
     rtl.RtlUnwindEx(EstablisherFrame, NULL, arec, NULL, context, dispatcher->HistoryTable);
     // call catch & jump to continuation
  }
}

基本上,我尝试为给定的捕获项找到RtlUnwind / RtlUnwindEx的参数。

有人能指出我可以尝试的信息或win64的seh示例实现吗?

1 个答案:

答案 0 :(得分:0)

结果证明这可以通过将新的异常对象传递给rtlUnwind并使用CallCatch方法作为第一个info参数来完成,并将STATUS_UNWIND_CONSOLIDATE作为代码。这将解开整个事物(重新启动任何清理的个性/最终)

 EXCEPTION_RECORD EH;
  EH.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
  EH.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  EH.NumberParameters = 4;
  EH.ExceptionInformation[0] = (ULONG)CallCatch;
  EH.ExceptionInformation[1] = EstFrame;
  EH.ExceptionInformation[2] = dispatcher->ImageBase + aHandler->Handler;
  EH.ExceptionInformation[3] = aCatch->TryLow;
rtl.RtlUnwindEx(estFrame, dispatcher->ControlPc, @EH, NULL, Context, dispatcher->HistoryTable);

调用catch应该使用带有EXCEPTION_RECORD *的函数作为参数,调用实际的catch并返回此catch的延续地址。