10

Practically everyone knows what Vectored Exception Handlers are, but I couldn't find a lot of information about the similar "Vectored Continue Handlers" and related functions I encountered today, such as AddVectoredContinueHandler and RemoveVectoredContinueHandler.

The prototype of AddVectoredContinueHandler is very similar to AddVectoredExceptionHandler's prototype:

PVOID WINAPI AddVectoredContinueHandler(
  _In_ ULONG                       FirstHandler,
  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

And to make things more confusing it accepts a PVECTORED_EXCEPTION_HANDLER, just as AddVectoredExceptionHandler does.

What is the purpose of Vectored Continue Handlers and how are they used?

10

Unfortunately MSDN and windows API documentation is really scarce here, and I had difficulties finding anything other than the minimal description in MSDN.

It turns out the Vectored Continue Handlers are maintained in a Linked list very similar to the one used for Vectored Exception Handlers. They are so similar, that the function's prototypes are practically identical.

Take a look at:

PVOID WINAPI AddVectoredExceptionHandler(
  _In_ ULONG                       FirstHandler,
  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

Compared to:

PVOID WINAPI AddVectoredContinueHandler(
  _In_ ULONG                       FirstHandler,
  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler
);

Luckily, Vectored Exception Handlers are more commonly used and documented. For example, MSDN has a page about VEHs, containing the following paragraph:

Vectored exception handlers are an extension to structured exception handling. An application can register a function to watch or handle all exceptions for the application. Vectored handlers are not frame-based, therefore, you can add a handler that will be called regardless of where you are in a call frame. Vectored handlers are called in the order that they were added, after the debugger gets a first chance notification, but before the system begins unwinding the stack.

The same page has only a laconic reference to the Add and Remove VCH APIs.

After some research and reverse engineering of ntdll, I realized VCHs and VEHs are quite similar in implementation. For example, see how AddVectoredExceptionHandler and AddVectoredContinueHandler are identical except for the VectoredListIndex, specifying they should be added to the second VectorHandlerList in the case of VCH:

AddVectoredExceptionHandler VS AddVectoredContinueHandler

Similarly, RemoveVectoredExceptionHandler and RemoveVectoredContinueHandler are identical except for the vectored handlers list index.

Inside RtlpAddVectoredHandler, the VectoredListIndex is used as an index in _LdrpVectorHandlerList, which is an array of size two of a linked list structure.

In the following picture we can see how VectoredListIndex is multiplied by the size of the list anchor object, and then added to _LdrpVectorHandlerList, which is the base offset of the array.

VectoredListIndex used as an array index

And now we're getting to the interesting part - where are VEH and VCH different?

If we walk up the cross references to _LdrpVectorHandlerList, we'll notice the two flows leading up to the add/remove functions are practically identical. Aside from those four APIs, we're left with only one other function, called RtlpCallVectoredHandlers which is undocumented.

It's pretty obvious from the name, but RtlpCallVectoredHandlers iterates over the vector (vector is selected according to the index) and calls all Handlers in a sequence. Once a Vectored Handler returns EXCEPTION_CONTINUE_EXECUTION the iteration is interrupted by prematurely returning from RtlpCallVectoredHandlers and execution resumes.

The sole function calling RtlpCallVectoredHandlers is RtlDispatchException, which is the main function dispatching exception handlers.

First, it executes all exception handlers, starting with the first Vectored Exception Handler to the last, and then going through all Structured Exception Handlers unfolding them through the stack. The first exception handler to return EXCEPTION_CONTINUE_EXECUTION (be it of type VEH or SEH) will stop the entire exception handlers execution process.

Like VEHs, when VCHs are called, they are called one by one until one of them returns EXCEPTION_CONTINUE_EXECUTION (just as when VEHs are called), which signals RtlpCallVectoredHandlers to break the Vectored Handlers calling loop. This is interesting because it means installing a Vectored Continue Handler as first lets you hide exceptions from subsequent VCHs.

Vectored Continue Handlers are called under the following circumstances:

  1. If an exception handler (either VEH or SEH) was called and returned EXCEPTION_CONTINUE_EXECUTION
  2. If for some reason SEH validation failed (See SafeSEH and related mechanisms), VCHs will also be called, but the execution will not continue afterwards. This can be seen in the many flows that lead to the second RtlpCallVectoredHandlers call without setting bl to 1 and leaving it equal to zero before moving it to al and returning false. The calling function, KiUserExceptionDispatcher will then call ZwRaiseException if the value returned by KiUserExceptionDispatcher is false. enter image description here
  • You say "If an exception handler (either VEH or SEH) was called and returned EXCEPTION_CONTINUE_EXECUTION". Did you EXCEPTION_CONTINUE_SEARCH? It does not make sense to call another handler after exception is handled. – Kentzo Nov 16 '17 at 22:51
  • @Kentzo that's precisely the point of vectored continue handlers. – NirIzr Nov 17 '17 at 2:53
  • The information I found on msdn (see a comment by MS employee) contradicts with that. – Kentzo Nov 17 '17 at 3:00
  • 1
    Nevermind: I think I misunderstood the comment. It's indeed only called as you state. – Kentzo Nov 18 '17 at 0:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.