实际上,每个人都知道什么是Vectored Exception Handler,但是我找不到关于今天遇到的类似“ Vectored Continue Handlers”和相关函数的大量信息,例如AddVectoredContinueHandler和RemoveVectoredContinueHandler。

原型AddVectoredContinueHandler的原型与AddVectoredExceptionHandler的原型非常相似:

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


并且更令人困惑的是,它接受PVECTORED_EXCEPTION_HANDLER,就像AddVectoredExceptionHandler一样。

矢量化连续处理程序的用途是什么?如何使用它们?

#1 楼

不幸的是,这里的MSDN和Windows API文档确实很稀少,除了在MSDN中的最小描述之外,我很难找到其他任何内容。

事实证明,矢量化继续处理程序保存在与一种用于矢量异常处理程序。它们是如此相似,因此该函数的原型实际上是相同的。

看一下:

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


与:
相比
PVOID WINAPI AddVectoredContinueHandler(
  _In_ ULONG                       FirstHandler,
  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler
);


幸运的是,矢量化异常处理程序更加常用和记录。例如,MSDN上有一个有关VEH的页面,其中包含以下段落:向量异常处理程序是对结构化异常处理的扩展。应用程序可以注册一个函数来监视或处理该应用程序的所有异常。向量处理程序不是基于框架的,因此,无论您位于调用框架中的何处,都可以添加将被调用的处理程序。在调试器获得第一个机会通知之后,但在系统开始展开堆栈之前,矢量处理程序将按添加顺序被调用。


同一页面上只有简单的引用

经过对ntdll的研究和反向工程,我意识到VCH和VEH在实现上非常相似。例如,查看AddVectoredExceptionHandlerAddVectoredContinueHandler(除了VectoredListIndex)如何相同,指定在VCH情况下应将它们添加到第二个VectorHandlerList

RemoveVectoredExceptionHandler相同,但矢量处理程序列表索引相同。

RemoveVectoredContinueHandler内,RtlpAddVectoredHandler用作VectoredListIndex中的索引,它是链接列表结构的大小为2的数组。

在下图中,我们可以看到如何将_LdrpVectorHandlerList乘以列表锚对象的大小,然后将其添加到VectoredListIndex,它是数组的基本偏移量。



现在我们进入有趣的部分-VEH和VCH在哪里不同?将会注意到,导致添加/删除功能的两个流程实际上是相同的。除了这四个API,我们只剩下另一个函数,称为_LdrpVectorHandlerList,未记录。

从名称上很明显,但是_LdrpVectorHandlerList遍历向量(向量根据索引)并按顺序调用所有处理程序。一旦向量处理程序返回RtlpCallVectoredHandlers,迭代就会因从RtlpCallVectoredHandlers过早返回而中断,并恢复执行。
EXCEPTION_CONTINUE_EXECUTION的函数是RtlpCallVectoredHandlers,这是分派异常处理程序的主要功能。 />首先,它执行所有异常处理程序,从第一个向量化异常处理程序开始到最后一个,然后遍历所有结构化异常处理程序,在堆栈中展开它们。第一个返回RtlpCallVectoredHandlers(类型为VEH或SEH)的异常处理程序将停止整个异常处理程序的执行过程。

像VEH一样,当调用VCH时,它们会被一个接一个地调用,直到一个它们返回RtlDispatchException(就像调用VEH时一样),这将向EXCEPTION_CONTINUE_EXECUTION发出信号通知矢量处理程序调用循环EXCEPTION_CONTINUE_EXECUTION。这很有趣,因为这意味着首先要安装Vectored Continue Handler,以便您可以隐藏后续VCH中的异常。

在以下情况下会调用Vectored Continue Handler:


如果调用了异常处理程序(VEH或SEH)并返回RtlpCallVectoredHandlers

如果由于某种原因SEH验证失败(请参阅SafeSEH和相关机制),也会调用VCH,但不会执行之后继续。
这可以在导致第二次break调用的许多流程中看到,而没有将EXCEPTION_CONTINUE_EXECUTION设置为RtlpCallVectoredHandlers并使它等于零,然后再将其移到bl并返回1。如果al返回的值是false,则调用函数KiUserExceptionDispatcher将调用ZwRaiseException




评论


您说“如果调用了异常处理程序(VEH或SEH)并返回了EXCEPTION_CONTINUE_EXECUTION”。您是EXCEPTION_CONTINUE_SEARCH吗?处理异常后,调用另一个处理程序是没有意义的。

–肯索(Kentzo)
17年11月16日在22:51

@Kentzo正是矢量化继续处理程序的重点。

– NirIzr
17年11月17日在2:53

我在msdn上找到的信息(请参阅MS员工的评论)与此相反。

–肯索(Kentzo)
17年17月17日3:00

没关系:我想我误解了此评论。实际上,仅在您声明时才调用它。

–肯索(Kentzo)
17年11月18日在0:35