程序的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. ios警告:Category is implementing a method which will also be implemented by its primary class 引发的相关处理

    今天在处理项目中相关警告的时候发现了很多问题,包括各种第三方库中的警告,以及各种乱七八糟的问题  先说说标题中的问题  Category is implementing a method which ...

  2. 银联接口测试——详细(JAVA)

    准备材料 1.注册账号 https://open.unionpay.com/ajweb/register?locale=zh_CN 2.▼登录账号 -->帮助中心--> 下载,选择网关支付 ...

  3. Redhat/Centos6.x-Samba配置

    安装: yum -y install samba samba-common samba-client 设置samba帐号 useradd smb passwd smb smbpasswd -a smb ...

  4. Linux platform设备简介

    Technorati 标签: Linux platform     Linux在2.6内核中,针对一系列设备驱动,提供新的管理框架,成为platform机制,推出的目的,在于隔离驱动的资源和实现,使得 ...

  5. (栈)栈 给定push序列,判断给定序列是否是pop序列

    题目: 输入两个整数序列.其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序.为了简单起见,我们假设push序列的任意两个整数都是不相等的. 比如输入的push序列是1.2. ...

  6. .NET中变量的类型问题

    1.JAVA和C# Byte的不同. java里一个byte取值范围是-128~127, 而C#里一个byte是0~255. 首位不同. 但是底层I/O存储的数据是一样的, 比如, 十进制的100, ...

  7. Nginx+Keepalived实现高可用站点

    Keepalived是一个基于VRRP协议来实现的服务高可用方案,可以利用其来避免IP单点故障,类似的工具还有heartbeat. corosync.pacemaker.但是它一般不会单独出现,而是与 ...

  8. MongoDB与php的配合使用 【windows版】

    通过学习了如何使用和部署MongoDB,尝试了一下如何将mongodb应用到php的程式中去. 1.预备工作 首先得准备好mongodb,并按照相关方法部署以及服务能正常运行中. 对于初学者,可以参考 ...

  9. PHP中文URL编解码(urlencode()rawurlencode()

    PHP中对于URL进行编码,可以使用 urlencode() 或者 rawurlencode(),二者的区别是前者把空格编码为 '+',而后者把空格编码为 '%20',不过应该注意的是,在编码时应该只 ...

  10. Ubuntu下PHP开发配置(新增redis、sphinx、sqlserver相关配置)

    由于本人比较懒,所以一般都是用xampp的直接拿来改的…………(当然xampp中一般php版本都是比较新的用的过程中请大家注意哈,可能会和老版本冲突) 此次除了使用xampp外,还扩展了sphinx, ...