基于EBP的栈帧

时间:2022-09-05 13:51:02

程序的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函数为例:
 
 
void stackframe(int a,int b,int c){  
    int x=c;  
    char buffer[64];  
    int y=b;  
    int z=10;  
    buffer[0]='A';  
    bar(z,y);  
}  
这个函数对应的反汇编代码如下:
 
.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操作了。

基于EBP的栈帧的更多相关文章

  1. X86-64寄存器和栈帧

    简介 通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果.除此之外,它们还各自具有一些特殊功能.通用寄存器的长度取决于机器字长,汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途, ...

  2. X86-64寄存器和栈帧--牛掰降解汇编函数寄存器相关操作

    X86-64寄存器和栈帧 概要 说到x86-64,总不免要说说AMD的牛逼,x86-64是x86系列中集大成者,继承了向后兼容的优良传统,最早由AMD公司提出,代号AMD64:正是由于能向后兼容,AM ...

  3. 汇编3栈帧,参数传递,串操作,混合汇编,x64,asm文件

    基础知识2 选择结构 通过判断 + 条件跳转指令来实现 循环结构 通过判断 + 条件跳转指令来实现(会有一个向上跳转的语句) 函数调用约定 C调用约定: 由外部平衡栈 标准调用约定 : 由函数内部平衡 ...

  4. 栈帧%ebp,%esp详解

    首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部( ...

  5. 使用gdb查看栈帧的情况,有ebp

    0x7fffffffdb30:    0x00000000    0x00000000    0xf7ffe700    0x0000001a0x7fffffffdb40:    0xffffdc98 ...

  6. [反汇编] 获取上一个栈帧的ebp

    使用代码 lea ecx, [ebp+4+参数长度] 就可以实现. 如下图,理解栈帧的结构,很好理解. 虽然也是 push param的,但这部分在恢复时被调用函数会恢复的,因此这并不算esp的值. ...

  7. 使用gdb查看栈帧的情况, 没有ebp

    0x7fffffffdb58: 0x004005ba  0x00000000  0x00000000  0x00000000 <-----funcb的栈帧 [0x7fffffffdb60, 0x ...

  8. c函数调用过程原理及函数栈帧分析

    转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...

  9. Linux - 函数的栈帧

    栈帧(stack frame),机器用栈来传递过程参数,存储返回信息,保存寄存器用于以后恢复,以及本地存储.为单个过程(函数调用)分配的那部分栈称为栈帧.栈帧其实是两个指针寄存器, 寄存器%ebp为帧 ...

随机推荐

  1. jquery文件上传控件 Uploadify

    (转自 http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html) 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同 ...

  2. 据说,每一个 iOSer 都想要一张 Swift 大会门票

    据说,每一个 iOSer 都想要一张中国首届 Swift 开发者大会的门票: 那么,福利来了-- fir.im 作为中国首届 Swift 大会的唯一钻石赞助商,有最后 2 张价值 600 多的门票(已 ...

  3. map与mapPartitions

    区别在于sc.map是将RDD下的所有行数据统计处理.而sc.mapPartitions是按RDD分区进行数据统计处理. 测试一下: val data = sc.parallelize(1 to 6, ...

  4. Linux查看系统信息&lpar;操作系统版本,进程,任务,CPU,内存,磁盘等信息&rpar;

    查看操作系统: cat /proc/version   # 内核版本 cat /etc/issue   # 发行版本 head -n 1 /etc/issue uname -a lsb_release ...

  5. js双向绑定和地址传递带来的痛苦解决方案之对象拷贝

    function cloneObj(obj) { var newObj = {}; if (obj instanceof Array) { newObj = []; } for (var key in ...

  6. python 备忘

    import jsonu='''{ "maps": [ { "id": "blabla", "iscategorical&quot ...

  7. android rc文件分析

    service vold /system/bin/vold \        --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:bl ...

  8. 何凯文每日一句打卡&vert;&vert;DAY12

  9. 2018&period;07&period;20 atcoder Largest Smallest Cyclic Shift(贪心)

    传送门 题意:给你x个a,y个b,z个c,显然这些字符可以拼成若干字符串,然后求这些字符串中最小表示法表示出来的最大的那一个. 解法:贪心思想,用multiset维护现在拼成的字串,每次取一个最小的和 ...

  10. Codeforces Round &num;381 &lpar;Div&period; 2&rpar; D&period; Alyona and a tree dfs序&plus;树状数组

    D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...