破解调试程序偶尔需要快速找到VEH函数的入口地址,除了可以对RtlpAddVectoredHandler下断点外,也可以通过内存查找相关结构的方式来获取
异常处理过程VEH(进程有效)->SEH(线程有效)->VCH(进程有效)->UEF(进程有效)
1.PEB+28H有个是否安装了VEH和VCH的标志位:
+0x028 ProcessInJob : Pos 0, 1 Bit
+0x028 ProcessInitializing : Pos 1, 1 Bit
+0x028 ProcessUsingVEH : Pos 2, 1 Bit
+0x028 ProcessUsingVCH : Pos 3, 1 Bit
+0x028 ProcessUsingFTH : Pos 4, 1 Bit
+0x028 ReservedBits0 : Pos 5, 27 Bits
比如一个程序PEB+28H处的值是5H也就是二进制的:00000101
第三位为1,说明有VEH
2.如果发现有安装了VEH/VCH,在内存中快速找到VEH/VCH处理函数入口的办法:
首先要明白VEH链表和VCH链表的成员都是存在进程默认堆里边的,每安装一个就专门申请16字节的空间.而有一个全局变量LdrpVectorHandlerList中保存了VEH链表和VCH链表的入口位置.
0:000> d ntdll!LdrpVectorHandlerList
77774744 00 00 00 00 30 0e 8d 00-08 0e 8d 00 00 00 00 00 ....0...........
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这12字节中有VEH链表的入口,后面12后字节存有VCH链表的入口;
77774754 54 47 77 77 54 47 77 77-00 00 00 00 00 00 8a 00 TGwwTGww........
LdrpVectorHandlerList中其实保存的是2个相同的有三个DWORD成员的结构
typedef struct _VECTORED_LIST_ENTR//表链入口
{
DWORD dwUnknown;//没弄明白是干啥的
PVECTORED_LIST Head;//记录了VECTORED_LIST表链的第一个
PVECTORED_LIST Tail; //记录了VECTORED_LIST表链的最后一个
}VECTORED_LIST_ENTR,*PVECTORED_LIST_ENTR;
比如上面的008d0e30就是VEH双向链表的入口
0:000> db 008d0e30
008d0e30 08 0e 8d 00 48 47 77 77-01 00 00 00 bb af 78 41 ....HGww......xA
~~向后指针 ~~向前指针 ~~有效标志 ~~加密的VEH处理函数入口
注意如果是最前面的VEH,它的向前指针是指向LdrpVectorHandlerList中的.
008d0e40 ab ab ab ab ab ab ab ab-00 00 00 00 00 00 00 00 ................
008d0e50 b6 97 b9 01 fe 49 00 00-c4 00 8a 00 30 51 8a 00 .....I......0Q..
008d0e60 ee fe ee fe ee fe ee fe-ee fe ee fe ee fe ee fe ................
008d0e70 ee fe ee fe ee fe ee fe-ee fe ee fe ee fe ee fe ................
008d0e80 ee fe ee fe ee fe ee fe-ee fe ee fe ee fe ee fe ................
008d0e90 ee fe ee fe ee fe ee fe-ee fe ee fe ee fe ee fe ................
008d0ea0 ee fe ee fe ee fe ee fe-ee fe ee fe ee fe ee fe ................
3.由于函数是被调用了RtlEncodePointer编了码的,所以要调用RtldecodePointer来解码
找个空的代码节在调试器中直接调用解码函数,返回值在EAX中就是解码后的地址了
0:000> a 003e1963
003e1963 pushad
pushad
003e1964 push 4178afbb
push 4178afbb
003e1969 call rtldecodepointer
call rtldecodepointer
003e196e popad
popad
主要参考了:http://bbs.pediy.com/showthread.php?t=166472感谢作者
--------------------------------------------------------
附X32 SEH的快速查找:
0:000> dt ntdll!_EXCEPTION_REGISTRATION_RECORD -l next poi(7efdd000) (这个值是TEB的基址)
next at 0x14f644
---------------------------------------------
+0x000 Next : 0x0014f810 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x776e71f5 _EXCEPTION_DISPOSITION ntdll!_except_handler4+0
next at 0x14f810
---------------------------------------------
+0x000 Next : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x776e71f5 _EXCEPTION_DISPOSITION ntdll!_except_handler4+0
next at 0xffffffff
---------------------------------------------
+0x000 Next : ????
+0x004 Handler : ????
Memory read error 00000003
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界