与 Olly 一起寻找并步进 VEH 处理程序?

逆向工程 视窗 ollydbg
2021-06-30 22:05:24

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

在此处输入图片说明

在这种情况下,我该怎么做才能获得处理程序代码并与 Olly 一起执行(除了静态分析可执行文件并寻找AddVectoredExceptionHandler朋友)?

2个回答

_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 条目时记录它可能更容易