在缓冲区溢出/程序集 MOV 中覆盖堆栈异常处理程序 (SEH)

Overwriting stack exception handler (SEH) in buffer overflow / Assembly MOV

我正在尝试通过覆盖位于此处的堆栈异常处理程序 (SEH) 来遵循绕过堆栈 cookie 的解释:https://www.corelan.be/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/

PDF link 到同一页:https://repo.zenk-security.com/Reversing%20.%20cracking/%20Bypassing%20Stack%20Cookies,%20SafeSeh,%20HW%20DEP%20and%20ASLR.pdf

我有疑问的部分在Stack cookie bypass demonstration 2 : Virtual Function call 网站或 PDF 第 30 页

寄存器的初始状态:

post 然后说:

...these 4 instructions are executed, attempting to load the address of the function into 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]

The end result of these 4 instructions is

然后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) 值后列出的 post 不匹配。

我的解读出了什么问题? EDX == ECX 不应该吗?谢谢。

对,好像有误

理论

所描述的方法通过在函数 returns 之前转移执行流程来绕过 GS 保护(并检查金丝雀)。
这是通过缓冲区溢出对在堆栈中进一步分配的 C++ 对象的 vtable 进行污染来实现的。

具有虚拟成员的 C++ 对象的布局增加了指向 vtable 的隐藏指针。
这个指针是 class 在内存中布局的第一个成员,参见 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.vtableedx = 40211ch(指向此 C++ 对象的 vtable)。 对于 MOV EAX,DWORD PTR DS:[EDX],我们有 eax 持有指向 this.vtable[0] 的指针,即 &bareax = 401070h (ptr to bar).

MOV ECX,DWORD PTR SS:[EBP-10] 只是将 this 移动到 ecx,这是 thiscall(没有双关语意)调用约定。
这也是为什么我认识到 [ebp-10h]this 而不是指向另一个对象的指针。

实施

复制后堆栈是(与您发布的完全一样):

我们可以看到C++对象没有被触及,复制的缓冲区太短了。
攻击者还需要一个 DWORD,在缓冲区中包含一个指针,他们在其中制作了一个新的 vtable.