Carlo Kok Carlo Kok - 1 year ago 202
C Question

How to properly call rtlunwind from within an x86_64 windows exception handler

I'm trying to implement a win64 exception personality and can't find much documentation on the subject.

I've already got a working win32 version but the win64 one crashes on

(access violation) in the "catch" part of a win64 exception handler, to unwind to the catch handler frame and 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

Basically, I'm trying to find the parameters to
for a given catch.

Can anyone point me to information on what I can try or a sample implementation of seh for win64?

Answer Source

turns out this can be done by passing a new exception object to rtlUnwind with a CallCatch method as first info parameter, with STATUS_UNWIND_CONSOLIDATE as code. This will unwind the whole thing (retriggering the personality for any cleanup/finally)

  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);

Call catch should take a function with EXCEPTION_RECORD* as parameter, call the actual catch and returning the continuation address for this catch.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download