Пример #1
0
int _except_handler3(PEXCEPTION_RECORD rec, MSVCRT_EXCEPTION_FRAME* frame, PCONTEXT context, void *dispatcher) {
  long retval;
  int trylevel;
  EXCEPTION_POINTERS exceptPtrs;
  PSCOPETABLE pScopeTable;

  //syslog(LOG_DEBUG, "msvcrt: exception %lx flags=%lx at %p handler=%p %p %p semi-stub",
  //       rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
  //       frame->handler, context, dispatcher);

  __asm cld;

  if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) {
    // Unwinding the current frame
     _local_unwind2(frame, TRYLEVEL_END);
    return ExceptionContinueSearch;
  } else {
    // Hunting for handler
    exceptPtrs.ExceptionRecord = rec;
    exceptPtrs.ContextRecord = context;
    *((DWORD *) frame - 1) = (DWORD) &exceptPtrs;
    trylevel = frame->trylevel;
    pScopeTable = frame->scopetable;

    while (trylevel != TRYLEVEL_END) {
      if (pScopeTable[trylevel].lpfnFilter) {
        //syslog(LOG_DEBUG, "filter = %p", pScopeTable[trylevel].lpfnFilter);

        retval = call_filter(pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp);

        //syslog(LOG_DEBUG, "filter returned %s", retval == EXCEPTION_CONTINUE_EXECUTION ?
        //      "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
        //      "EXECUTE_HANDLER" : "CONTINUE_SEARCH");

        if (retval == EXCEPTION_CONTINUE_EXECUTION) return ExceptionContinueExecution;

        if (retval == EXCEPTION_EXECUTE_HANDLER) {
          // Unwind all higher frames, this one will handle the exception
          _global_unwind2((PEXCEPTION_FRAME) frame);
          _local_unwind2(frame, trylevel);

          // Set our trylevel to the enclosing block, and call the __finally code, which won't return
          frame->trylevel = pScopeTable->previousTryLevel;
          //syslog(LOG_DEBUG, "__finally block %p",pScopeTable[trylevel].lpfnHandler);
          call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp);
          panic("Returned from __finally block");
       }
      }
      trylevel = pScopeTable->previousTryLevel;
    }
  }

  return ExceptionContinueSearch;
}
Пример #2
0
void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp)
{
    _local_unwind2((MSVCRT_EXCEPTION_FRAME*) jmp->Registration, jmp->TryLevel);
}