函数调用栈



博客网址:www.shicoder.top
微信:18223081347
欢迎加群聊天 :452380935

这个分栏我们开始学习PWN,当然PWN也是自己的兴趣爱好,所以可能博客更新较慢,不好意思啦

前置知识

每个函数都有自己的栈帧,栈底用 ebp,栈顶用 esp,还有一个 eip,表示即将执行的指令的地址,下面是栈的图示,是从高地址向低地址增长

函数调用栈

函数的栈帧包括

  • 函数的返回地址和参数
  • 本地变量
  • 调用前后上下文

因此比如一个 main函数执行时候, ebp指向其栈帧底部,然后在函数运行时候随时 pushpop,导致其 esp不断变化,当要调用子函数 func时候,会先 push子函数所需要的参数,然后进入 func之后,首先 push ebp,因为此时的 ebpmain函数的,为了在 func函数结束后,找到 main函数的 ebp,所以先保留,然后 mov ebp,esp,这时候 ebp就会被赋予新的值,这个值就是 func函数栈帧的底部,然后就是一些 func函数自己的操作,当要使用传进来的参数时候,就去当时在 main调用 funcpush的参数去取,当执行 func函数之后,需要返回到 main,此时分两种情况

  • func中没有使用过局部变量,则进入 func之后, ebpesp始终是一样的,所以直接 pop ebp,此时 ebp中就存放了 call调用前, mainebp
  • func中使用过局部变量,则进入 func之后,首先会 sub esp,一些空间来给 func使用,然后结束时候,使用 leave => mov esp,ebp、pop ebp,先将 esp值变为 ebp的值,此时两个一样,然后 pop ebp之后, ebp中就存放了 call调用前, mainebp

简单的就是如下代码

main:
    ...

    push arg2
    push arg1
    call func
    ...

; func函数内没有局部变量
func:
    push ebp
    mov ebp,esp
    将main的栈中的参数放到寄存器中
    一顿操作
    pop ebp
    retn

; func函数内有局部变量
func:
    push ebp
    mov ebp,esp
    sub esp,0x10(就是一段长度,存放局部变量)
    将main的栈中的参数放到寄存器中
    一顿操作
    leave
    retn

注意:

  • call => 等价 push 返回地址,然后eip跳转到sum开头的地方
  • leave => 等价 mov esp, ebp 然后 pop ebp
  • retn => 等价 pop eip

小试牛刀

以下面的c语言代码进行讲解

#include

int sum(int a,int b)
{
    return a + b;
}

int main(){
    sum(3,4);
    return 0;
}

push    ebp
mov     ebp, esp
push    4
push    3
call    sum
add     esp, 8
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
pop     ebp
retn

下面一段视频就是其过程,可以看下

后面还有两段有局部变量的,大家也可以自己推导下。

#include

int sum(int a,int b)
{
    int c;
    c = a + b;
    return c;
}

int main(){
    int ret;
    ret = sum(3,4);
    return 0;
}
push    ebp
mov     ebp, esp
sub     esp, 10h
push    4
push    3
call    sum
add     esp, 8
mov     [ebp-4], eax
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
sub     esp, 10h
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
mov     [ebp-4], eax
mov     eax, [ebp-4]
leave
retn
#include

int sum(int a,int b)
{
    return a + b;
}

int main(){
    int ret;
    ret = sum(3,4);
    return 0;
}
push    ebp
mov     ebp, esp
sub     esp, 10h
push    4
push    3
call    sum
add     esp, 8
mov     [ebp-4], eax
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
pop     ebp
retn

Original: https://www.cnblogs.com/shilinkun/p/16272423.html
Author: 小坤学习园
Title: 函数调用栈

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607255/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [Linux]利用ping给端口加密,限制访问

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月26日
    0313
  • 精品收藏:GitHub人工智能AI开源项目

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月30日
    0293
  • 面试复盘(1)

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月7日
    043
  • CentOS7下安装python3.7

    以原码编译的方式安装 1.官网下载python3.7软件包 2.上传至Linux中,并解压 tar -zxvf python-3.7.2.tgz 3.安装gcc和python所需依…

    Linux 2023年6月6日
    042
  • Linux 硬盘工具之hdparm

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月26日
    0223
  • C++ Linux Window

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月26日
    0192
  • ubuntu查看和修改PATH环境变量的方法

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月26日
    0265
  • NoteOfMySQL-11-权限管理

    一、权限系统 MySQL数据库中使用3种不同类型的安全检查:登录验证、授权、访问控制。 二、权限表 MySQL权限表存储在名为mysql的数据库中,常用的表有user、db、tab…

    Linux 2023年6月14日
    037
  • 聊聊redis单线程为什么能做到高性能和io多路复用到底是个什么鬼

    1:io多路复用epoll io多路复用简单来说就是一个线程处理多个网络请求。 我们知道epoll in 的事件触发是可读了,这个比较好理解,比如一个连接过来,或者一个数据发送过来…

    Linux 2023年5月28日
    040
  • Git 分支管理

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年8月30日
    0216
  • PHP array_values()

    array_values array_values() 函数返回一个包含给定数组中所有键值的数组,但不保留键名。 示例: function arrayValues() { $dat…

    Linux 2023年6月7日
    048
  • 离线版centos8安装docker笔记

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年11月8日
    0148
  • 用shell抓取某考试试题

    一、背景 最近公司组织考信息安全,但考试机构没有整理出试题,只给了以下几个在线练习的链接,想着用博客整理下题库题型,奈何这个只能用拍照图片,然后用图片转文字的方式太慢,累死个人了,…

    Linux 2023年6月6日
    045
  • 如何在EMACS 设置格式

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年11月7日
    0231
  • 转:多线程环境下调用 HttpWebRequest 并发连接限制

    .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows 7 下默认…

    Linux 2023年6月13日
    044
  • js之数据类型(1)

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Linux 2022年11月7日
    0138
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球