zoukankan      html  css  js  c++  java
  • 0day2安全——笔记3

    第二章

    函数调用约定

    不同的操作系统,语言和编译器调用函数的原理差不多,但是具体的调用约定有差异。

    C语言VC++编译的函数传参顺序如下图所示(默认使用__stdcall调用约定)

    函数调用步骤(__stdcall约定)
    1. 参数入栈:将参数从右向左依次压入系统栈中
    2. 返回地址入栈:将当期代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行
    3. 代码区跳转:处理器从当前代码区跳转到被调用函数的入口处
    4. 栈帧调整:

    • 保存当前栈帧状态值:已被后面回复本栈帧使用(EBP入栈)
    • 将当前栈帧切换到新栈帧(将ESP值装入EBP,更新栈帧底部)
    • 给新栈帧分配空间(把ESP减去所需要空间的大小,抬高栈帧)

    ASM

    push 参数3      ;从右到左依次传参
    push 参数2
    push 参数1
    call 函数地址    ;1.向栈中压入当前指令在内存中的位置,即保存返回地址
                    ;2.跳转到所调用函数的入口地址
    push ebp        ;保存旧栈帧的底部
    mov ebp,esp        ;设置新栈帧的底部(栈帧切换)
    sub esp,xxx        ;设置新栈帧的顶部(抬高栈帧,为新栈帧开辟空间)

     函数调用时系统栈发生的变化

    函数返回步骤(__stdcall约定)

    1. 保存返回值:通常将函数的返回值保存在寄存器EAX(累加寄存器)中
    2. 弹出当前栈帧,恢复上一个栈帧

    • 在堆栈平衡的基础上,给ESP加上栈帧的大小,降低栈顶,回收当前栈帧的空间
    • 将当期栈帧底部保存的前栈帧ESP值弹如EBP寄存器,恢复出上一个栈帧
    • 将函数返回地址弹给EIP(指令寄存器)

    ASM

    add esp,xxx ;降低栈顶,回收当前栈帧
    pop ebp     ;将上一个栈帧底部位置恢复到ebp
    retn        ;1.弹出当前栈帧元素,即弹出栈帧中的返回地址,至此栈帧的恢复工作完成
                ;2.让处理器跳转到弹出的返回地址,恢复到调用前的代码区
  • 相关阅读:
    BZOJ1042: [HAOI2008]硬币购物
    BZOJ1089: [SCOI2003]严格n元树
    BZOJ1060: [ZJOI2007]时态同步
    BZOJ2697: 特技飞行
    BZOJ2464: 中山市选[2009]小明的游戏
    BZOJ1430: 小猴打架
    BZOJ3675: [Apio2014]序列分割
    BZOJ2453: 维护队列
    BZOJ2120: 数颜色
    BZOJ4547: Hdu5171 小奇的集合
  • 原文地址:https://www.cnblogs.com/luocodes/p/11882576.html
Copyright © 2011-2022 走看看