逆向学习笔记-基于EBP的栈帧
程序的OEP,一开始以 push ebp 和mov ebp esp这两句开始。
原因:c程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:1.让EBP保存ESP的值。
2.在程序运行完毕的时候调用
mov esp,ebp
pop ebp
retn
或者是
leave
retn
通过EBP保存程序运行前ESP的值,那么程序运行过程中,不管ESP被Push还是Pop多少次,最终都可以通过EBP还原最开始的值。
我们下面使用gcc编译的stackframe函数为例:
.text:0040153C ; =============== S U B R O U T I N E =======================================.text:0040153C.text:0040153C ; Attributes: bp-based frame.text:0040153C.text:0040153C _text_40153C proc near ; CODE XREF: _text_40157A.text:0040153C.text:0040153C var_60= dword ptr -60h ;z.text:0040153C var_5C= dword ptr -5Ch ;y.text:0040153C var_58= dword ptr -58h ;buffer.text:0040153C var_C= dword ptr -0Ch ;x.text:0040153C arg_4= dword ptr 0Ch ;b.text:0040153C arg_8= dword ptr 10h ;c.text:0040153C.text:0040153C push ebp.text:0040153D mov ebp, esp.text:0040153F sub esp, 78h.text:00401542 mov eax,[ebp+arg_8].text:00401549 mov [ebp+var_C],eax.text:0040154B mov eax,[ebp+arg_4].text:0040154F mov [ebp+var_5C],eax.text:00401551 mov [ebp+var_60],0Ah.text:00401554 mov [ebp+var_58],41h.text:00401557 mov eax,[ebp+var_5C].text:0040155A mov [esp+4],eax ;y入栈.text:0040155D mov eax,[ebp+var_60].text:00401561 mov [esp],eax ;z入栈
从 var_60= dword ptr -60h开始,IDA提供了一个摘要栈视图,其中与指针EBP偏移距离为负的代表着四个局部变量x,buffer,y,z入栈,偏移距离为正的代表着用到的两个形参b,c入栈。之后就是push ebp 和mov ebp esp以及函数体内部的赋值操作。最后要说明的是函数体最后调用了bar(z,y),这里需要将z,y压栈到esp中,因为z在前,所以[esp]存放z,[esp+4]存放y,之后就是bar函数开始前的push ebp 和mov ebp esp操作了。