我正在尝试通过覆盖位于以下位置的堆栈异常处理程序(SEH)来绕过堆栈cookie的解释:https://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/
我有一个疑问的部分位于网站的堆栈cookie旁路演示2:虚拟函数调用下或PDF的第30页
寄存器的初始状态:
帖子然后说:
...这4条指令已执行,试图加载 函数的地址转换为eax ...
0040104D |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
00401050 |. 8B10 MOV EDX,DWORD PTR DS:[EAX]
00401052 |. 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
00401055 |. 8B02 MOV EAX,DWORD PTR DS:[EDX]
这4条指令的最终结果是
然后将调用CALL EAX
,在EAX中执行修改后的函数指针地址。
我的问题:
EAX和EDX如何在提到的4条指令后指向覆盖的字符串?
我的理解是第一条说明
之后的内容 MOV EAX,DWORD PTR SS:[EBP-10]
EBP(0012FF6C)减10(十六进制?)等于0012FF5C。位置0012FF5C的值为0012FF78。 0012FF78是SEH在作为参数传递的堆栈中更远的位置。
因此,EAX = 0012FF78。到目前为止一切顺利,因为0012FF78是指向SEH的指针的地址,位于堆栈的更远处。
第二条指令,
MOV EDX,DWORD PTR DS:[EAX]
EDX设置为EAX指向的位置的值。位置0012FF78处的值为0040211C。 EDX = 0040211C?
第三条指令,
MOV ECX,DWORD PTR SS:[EBP-10]
ECX设置为0012FF78,与第一条指令相同,但使用ECX代替EAX。此说明对这种情况有影响吗?
第四条指令
MOV EAX,DWORD PTR DS:[EDX]
EAX设置为EDX(0040211C)引用的值。 EAX = ???内存中该位置的任何内容。
我计算的EAX(???)和EDX(0040211C)与EAX(42424242)和EDX(0012FF78)的值后面所列的帖子不匹配。
我的解释出了什么问题? EDX == ECX不应该吗?谢谢。
答案 0 :(得分:3)
是的,看来有误
所描述的方法通过在函数返回之前转移执行流程(并检查canary)来绕过GS保护。
这是通过对缓冲区中溢出的C ++对象的vtable
进行污染来实现的。
带有虚拟成员的C ++对象的布局增加了指向vtable
的隐藏指针。
该指针是布置在内存中的类的第一个成员,请参见this。
该对象分配在堆栈中的某个位置,但指向它的指针存储在[ebp-10h]
(有效地址0x12FF5C)中,您可以通过查看指令10 00401010 894df0 mov dword ptr [ebp-10h],ecx
来看到此内容(下文有更多介绍)在PDF的第27页上可以找到,其中显示了受害者函数的反汇编。
使用MOV EAX,DWORD PTR SS:[EBP-10]
时,eax
持有指向C ++对象的指针,即this
,因为我们位于成员函数和[ebp-10h] = original ecx
中(见下文)。 eax = 12FF78h (ptr to this C++ object)
。
使用MOV EDX,DWORD PTR DS:[EAX]
,我们有edx
持有指向this[0]
的指针,即this.vtable
。 edx = 40211ch
(此C ++对象的vtable的ptr)。
使用MOV EAX,DWORD PTR DS:[EDX]
,我们有eax
持有指向this.vtable[0]
的指针,即&bar
。 eax = 401070h (ptr to bar)
。
MOV ECX,DWORD PTR SS:[EBP-10]
仅将this
移到ecx
中,这就是thiscall
(无双关语)的调用约定。
这也是为什么我认识到[ebp-10h]
是this
而不是指向另一个对象的指针的原因。
复制后的堆栈(与您发布的完全相同):
我们可以看到尚未触摸C ++对象,复制的缓冲区太短。
攻击者将需要一个DWORD,在缓冲区中包含一个指针,在那里他们可以制作新的vtable
。