我一直在寻找一种方法来访问在发生异常时调用的 VEH 处理程序(由被反转的应用程序指定)。我已经阅读了这个问题,它很好地解释了一些事情,但我的情况略有不同。我正在执行/执行的代码引发异常:

在这种情况下,我该怎么做才能获得处理程序代码并与 Olly 一起执行(除了静态分析可执行文件并寻找AddVectoredExceptionHandler朋友)?
我一直在寻找一种方法来访问在发生异常时调用的 VEH 处理程序(由被反转的应用程序指定)。我已经阅读了这个问题,它很好地解释了一些事情,但我的情况略有不同。我正在执行/执行的代码引发异常:

在这种情况下,我该怎么做才能获得处理程序代码并与 Olly 一起执行(除了静态分析可执行文件并寻找AddVectoredExceptionHandler朋友)?
_LdrpVectorHandlerList 似乎没有记录,在 xp 中也可能不可用
我什至无法找到关于其内部运作的半真实的谷歌
我能找到的关于 _LdrpVectorHandlerList 的一点点似乎指出它是一个 EncodedPointer 而不是实际的处理程序
DecodePointer 是每个进程,在调试器(带有插件/扩展等)中执行 DecodePointer 不会解码被调试对象 EncodedPointer 可以读取进程内存以获取被调试对象 EncodedPointer HandlerList。
ollydbg 1.10 是在 VEH 存在之前,所以它只知道在 view->SEH 链窗口中的 SEH
ollydbg 2.01 将在 view->seh 链窗口中显示编码的指针链接而不是实际的处理程序,如下所示
VEH/SEH chain of main thread
Index Type Link Handler
1 Vectored 00153848 Invalid
2 Vectored 001537F8 Invalid
3 Vectored 00153820 Invalid
4 SEH 0013FF60 00401880 _except_handler4
5 SEH 0013FFB0 00401880 _except_handler4
6 SEH 0013FFE0 7C839AD8 _except_handler3
为了找到实际的 veh 处理程序,我制作了一个使用 Windbg 本地内核调试的 bat 文件(在 xp sp3 中使用,只是不确定这是否仍然适用于较新的操作系统),您可以查看一下
:type c:\findveh.bat
kd -kl -c "$$>a< c:\findveh.txt %1 ;q" | findstr /I eval
:type c:\findveh.txt
.foreach /pS 1 /ps 200 (place { !process 0 0 ${$arg1} } ) {.process /p /r place}
!list -t ntdll!_SINGLE_LIST_ENTRY.Next -x "? poi( @$extret+8 ) ^ @@(@$proc->Cookie)" @@masm(ntdll!RtlpCalloutEntryList);
!list -t ntdll!_SINGLE_LIST_ENTRY.Next -x "? poi( @$extret)" @@masm(ntdll!RtlpCalloutEntryList);
bat 文件的输出(添加第二个 !list 命令只是为了显示链接的 EncodedPointers 进行比较,它不是必需的)
脚本解释
设置我们想要查找 veh 处理程序的相关进程的进程上下文遍历 SINGLE_LIST_ENTRY 并通过使用特定 ProcessCookie 对 EncodedPointer 进行异或来打印实际处理程序
veh.exe 的代码是使用 veh 处理程序复制粘贴的 msdn 文档示例
:findveh.bat veh.exe
:kd -kl -c "$$>a< c:\findveh.txt veh.exe ;q" | findstr /I eval
Evaluate expression: -169753474 = f5e1c47e
Evaluate expression: -4290768896 = ffffffff`00401000
Evaluate expression: -4290768848 = ffffffff`00401030
Evaluate expression: -4290768800 = ffffffff`00401060
Evaluate expression: 1390664 = 00153848
Evaluate expression: 1390584 = 001537f8
Evaluate expression: 1390624 = 00153820
Evaluate expression: 2090329024 = 7c97e3c0
如果您只使用导出表符号(默认),那么最好的办法可能是在ntdll!KiUserExceptionDispatcher(). 当它被调用时,您可以跟踪它以找到向量处理程序列表。另一方面,如果您有 ntdll.dll 的公共符号 PDB,那么您可以通过查看_LdrpVectorHandlerList.
老实说,设置日志断点AddVectoredExceptionHandler()并在添加每个 VEH 条目时记录它可能更容易。