📄 762.html
字号:
.text:7C962DD4 mov esi, [esi]<br />
<br />
所以可以看到在sp2下无法利用这个覆盖VEH链表指针的技巧了。<br />
<br />
给出xp sp1下通用的指针<br />
<br />
xp sp1下<br />
.text:77F60C26 ; __stdcall RtlCallVectoredExceptionHandlers(x,x)<br />
.text:77F60C26 _RtlCallVectoredExceptionHandlers@8 proc near<br />
.text:77F60C26 ; CODE XREF: RtlDispatchException(x,x)+Ep<br />
.text:77F60C26 push ebp<br />
.text:77F60C27 mov ebp, esp<br />
.text:77F60C29 push ecx<br />
.text:77F60C2A push ecx<br />
.text:77F60C2B push edi<br />
.text:77F60C2C mov edi, offset _RtlpCalloutEntryList<br />
.text:77F60C31 cmp _RtlpCalloutEntryList, edi<br />
;这里我们可以看到将77FC3210的值放入edi,然后和该地址的内容相比较,如果没有安装VEH,那么该地址<br />
;的内容也是77FC3210,就不会跳转到77F7F485。如果用户安装了VEH,那么就会跳到77F7F485<br />
.text:77F60C37 jnz loc_77F7F485<br />
.text:77F60C3D xor al, al<br />
.text:77F60C3F<br />
.text:77F60C3F loc_77F60C3F: ; CODE XREF: RtlInitializeResource(x)+1B6CDj<br />
.text:77F60C3F pop edi<br />
.text:77F60C40 leave<br />
.text:77F60C41 retn 8<br />
<br />
.text:77F7F485 loc_77F7F485: ; CODE XREF: RtlCallVectoredExceptionHandlers(x,x)+11j<br />
.text:77F7F485 mov eax, [ebp+8]<br />
.text:77F7F488 push ebx<br />
.text:77F7F489 push esi<br />
.text:77F7F48A mov [ebp-8], eax<br />
.text:77F7F48D mov eax, [ebp+0Ch]<br />
.text:77F7F490 mov ebx, offset _RtlpCalloutEntryLock<br />
.text:77F7F495 push ebx<br />
.text:77F7F496 mov [ebp-4], eax<br />
.text:77F7F499 call _RtlEnterCriticalSection@4 ; RtlEnterCriticalSection(x)<br />
<br />
关键的下面这个部分,从77FC3210里面取出安装的处理函数地址<br />
<br />
.text:77F7F49E mov esi, _RtlpCalloutEntryList<br />
.text:77F7F4A4 jmp short loc_77F7F4B4<br />
.text:77F7F4A6 loc_77F7F4A6: ; CODE XREF: RtlInitializeResource(x)+1B6BCj<br />
.text:77F7F4A6 lea eax, [ebp-8]<br />
.text:77F7F4A9 push eax<br />
.text:77F7F4AA call dword ptr [esi+8] <br />
;这里esi指向struct _VECTORED_EXCEPTION_NODE结构,其0x08处为m_pfnVectoredHandler<br />
;看到这里我们也就明白了,如果我们可以控制该指针,那么我们就可以控制程序的流程了!<br />
.text:77F7F4AD cmp eax, 0FFFFFFFFh<br />
<br />
<br />
.text:77F7F4B4 loc_77F7F4B4: ; CODE XREF: RtlInitializeResource(x)+1B6AAj<br />
.text:77F7F4B4 cmp esi, edi<br />
.text:77F7F4B6 jnz short loc_77F7F4A6<br />
<br />
xp_sp0下<br />
<br />
_RtlpCalloutEntryList 位于77FC5BD0<br />
<br />
.data:77FC5BD0 _RtlpCalloutEntryList dd 0 ; DATA XREF: RtlCallVectoredExceptionHandlers(x,x)+6o<br />
.data:77FC5BD0 ; RtlCallVectoredExceptionHandlers(x,x)+Br ...<br />
<br />
4、堆块的cookie保护<br />
<br />
现在堆块的结构<br />
HEAP_ENTRY struc ; (sizeof=0X8)<br />
Size dw ?<br />
PrevSize dw ?<br />
Cookie db ?<br />
Flags db ?<br />
UnusedBytes db ?<br />
Index db ?<br />
HEAP_ENTRY ends<br />
<br />
空闲块管理结构<br />
_RTL_HEAP_FREE_BLOCK struc ; (sizeof=0X10)<br />
Entry _RTL_HEAP_ENTRY ?<br />
List LIST_ENTRY ?<br />
_RTL_HEAP_FREE_BLOCK ends<br />
<br />
对比一下以前的堆块结构<br />
typedef struct _HEAP_ENTRY {<br />
/*0x00*/ USHORT Size;<br />
/*0x02*/ USHORT PreviousSize;<br />
/*0x04*/ UCHAR SegmentIndex;<br />
/*0x05*/ UCHAR Flags;<br />
/*0x06*/ UCHAR UnusedBytes;<br />
/*0x07*/ UCHAR SmallTagIndex;<br />
} HEAP_ENTRY, *PHEAP_ENTRY;<br />
<br />
可以看到SmallTagIndex被舍弃了,SegmentIndex挪动到后面,而第5个字节更改为cookie。<br />
Cookie的计算公式:<br />
<br />
堆块头部地址除以8,然后跟Heap的总体管理结构中的cookie来异或就得到了cookie的值。<br />
代码如下<br />
.text:7C931487 mov edx, esi ;ESI指向HEAP_ENTRY<br />
.text:7C931489 shr edx, 3<br />
.text:7C93148C xor eax, eax<br />
.text:7C93148E mov al, [edi+4] ; 进行Cookie处理,此时edi指向堆管理结构分配头部<br />
.text:7C931491 xor eax, edx<br />
.text:7C931493 mov [esi+4], al<br />
<br />
那么我们可以看到cookie有256个可能的值,所以你也就不用费尽心思来想怎么覆盖cookie而不出错了。当然有很多办法绕过cookie的检测。<br />
xp sp2对于堆的管理并没有太大的变化,但是堆的管理结构,堆块,还有Lookaside表的某些字段发生了变化,比如说有的字段从dd变成了dw,因此加了几个字段。这些细节就不在这里罗嗦了。
</td>
</tr>
</table>
<div class="footer">
Copyright © 1998-2003 XFOCUS Team. All Rights Reserved
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -