我们知道在我们对溢出漏洞进行eXP的时候,经常要利用全局性的指针,利用异常处理。那么XP的SP2对此作了处理。使得我们无法运用以前的技巧来完成我们的工作。
.text:7C95779C ; __stdcall RtlCallVectoredExceptionHandlers(x,x)
.text:7C95779C _RtlCallVectoredExceptionHandlers@8 proc near
.text:7C95779C ; CODE XREF: RtlDispatchException(x,x)+14p
.text:7C95779C mov edi, edi
.text:7C95779E push ebp
.text:7C95779F mov ebp, esp
.text:7C9577A1 push ecx
.text:7C9577A2 push ecx
.text:7C9577A3 push edi
这里就比较VEH的链表是不是空的,也就是看自己是否指向自己。如果是空的就不用说了,非空就转向该指针的调用
.text:7C9577A4 mov edi, offset _RtlpCalloutEntryList
.text:7C9577A9 cmp _RtlpCalloutEntryList, edi
.text:7C9577AF jnz loc_7C962DA0
.text:7C962DA0 loc_7C962DA0: ; CODE XREF: RtlCallVectoredExceptionHandlers(x,x)+13j
.text:7C962DA0 mov eax, [ebp+arg_4]
.text:7C962DA3 push ebx
.text:7C962DA4 push esi
.text:7C962DA5 mov [ebp+var_8], eax
.text:7C962DA8 mov eax, [ebp+arg_8]
.text:7C962DAB mov ebx, offset _RtlpCalloutEntryLock
.text:7C962DB0 push ebx
.text:7C962DB1 mov [ebp+var_4], eax
.text:7C962DB4 call _RtlEnterCriticalSection@4 ; RtlEnterCriticalSection(x)
.text:7C962DB9 mov esi, _RtlpCalloutEntryList
.text:7C962DBF jmp short loc_7C962DD6
.text:7C962DC1 loc_7C962DC1: ; CODE XREF: RtlInitializeResource(x)+21C3Dj
.text:7C962DC1 push dword ptr [esi+8]
代码就不解释那么多了,可以看到指针在使用前必须先解码,这个函数前面已经讲解过了。
.text:7C962DC4 call _RtlDecodePointer@4 ; RtlDecodePointer(x)
.text:7C962DC9 lea ecx, [ebp+var_8]
.text:7C962DCC push ecx
.text:7C962DCD call eax
.text:7C962DCF cmp eax, 0FFFFFFFFh
.text:7C962DD2 jz short loc_7C962DEE
.text:7C962DD4 mov esi, [esi]
所以可以看到在sp2下无法利用这个覆盖VEH链表指针的技巧了。
给出XP sp1下通用的指针
XP sp1下
.text:77F60C26 ; __stdcall RtlCallVectoredExceptionHandlers(x,x)
.text:77F60C26 _RtlCallVectoredExceptionHandlers@8 proc near
.text:77F60C26 ; CODE XREF: RtlDispatchException(x,x)+Ep
.text:77F60C26 push ebp
.text:77F60C27 mov ebp, esp
.text:77F60C29 push ecx
.text:77F60C2A push ecx
.text:77F60C2B push edi
.text:77F60C2C mov edi, offset _RtlpCalloutEntryList
.text:77F60C31 cmp _RtlpCalloutEntryList, edi
;这里我们可以看到将77FC3210的值放入edi,然后和该地址的内容相比较,如果没有安装VEH,那么该地址
;的内容也是77FC3210,就不会跳转到77F7F485。如果用户安装了VEH,那么就会跳到77F7F485
.text:77F60C37 jnz loc_77F7F485
.text:77F60C3D xor al, al
.text:77F60C3F
.text:77F60C3F loc_77F60C3F: ; CODE XREF: RtlInitializeResource(x)+1B6CDj
.text:77F60C3F pop edi
.text:77F60C40 leave
.text:77F60C41 retn 8
.text:77F7F485 loc_77F7F485: ; CODE XREF: RtlCallVectoredExceptionHandlers(x,x)+11j
.text:77F7F485 mov eax, [ebp+8]
.text:77F7F488 push ebx
.text:77F7F489 push esi
.text:77F7F48A mov [ebp-8], eax
.text:77F7F48D mov eax, [ebp+0Ch]
.text:77F7F490 mov ebx, offset _RtlpCalloutEntryLock
.text:77F7F495 push ebx
.text:77F7F496 mov [ebp-4], eax
.text:77F7F499 call _RtlEnterCriticalSection@4 ; RtlEnterCriticalSection(x)
关键的下面这个部分,从77FC3210里面取出安装的处理函数地址
.text:77F7F49E mov esi, _RtlpCalloutEntryList
.text:77F7F4A4 jmp short loc_77F7F4B4
.text:77F7F4A6 loc_77F7F4A6: ; CODE XREF: RtlInitializeResource(x)+1B6BCj
.text:77F7F4A6 lea eax, [ebp-8]
.text:77F7F4A9 push eax
.text:77F7F4AA call dword ptr [esi+8]
;这里esi指向struct _VECTORED_EX