笔记 pwn入门1(c函数的调用和返回)

这是大佬Cyberangl的文章的笔记,原文链接pwn知识库

大佬懒我也好懒,先说一下,笔记里的%ebp都是使用的AT&T语法(这是啥我还不知道),指的是ebp寄存器。

c函数调用过程原理及函数栈帧分析(intel)

栈是什么

栈是一种LIFO(last-in,first-out)形式的数据结构,所有的数据都是后进先出。这种形式正好满足我们调用函数的方式:父函数调用子函数,父函数在前,子函数在后;返回时,子函数先返回,父函数后返回。栈支持两种基础操作,push和pop。push将数据压入栈中,pop将栈中数据弹出并存储到指定寄存器或内存中。
实例:假设有了一个栈,其中黄色部分是以经写入的区域,绿色部分是还未写入数据的区域。

push 0x50 //把0x50压入栈中

在这里插入图片描述
pop操作:

pop 寄存器名称 //将栈中 的0x50弹出到某个寄存器中

在这里插入图片描述
注意:
一、上面的例子中栈的生长方向是从高地址到低地址的,对应笔记图片中栈是向下生长的。
二、pop操作之后,栈中的数据没有被清空,只是该数据我们无法直接访问,但是还是可以访问的。
具有以上栈基础后,下面是x86-32bit系统下c语言的函数调用。

栈帧是什么

stack frame,本质是一种栈,该栈专门用于保存函数调用过程中的各种信息(参数(实参)、返回地址、本地变量)。栈帧有栈顶和栈底之分,栈顶的地址最低,栈底的地址最高,SP(栈指针)是一直指向栈顶的。 在下6
-32bit中,我们用ebp指向栈底、用esp指向栈顶。 下面是栈帧示意图:在这里插入图片描述
一般,我们将ebpesp之间的区域当作栈帧。并不是 整个栈空间只有一个栈帧,每调用一个函数,就会生成一个新的栈帧。 在函数调用中 ,调用函数的函数称为“调用者(caller)”,被调用的函数叫做“被调用者“(callee)”。
在函数调用过程中:
(1)”调用者“需要知道在哪里获取”被调用者“返回的值。
(2)”被调用者“需要知道传入的参数在哪。
同时还要保证”被调用者“返回后,ebpesp等寄存器的值应该和调用前一致。因此,我们需要用栈来存储这些数据。

函数调用实例

函数的调用

int MyFunction(int x,int y,int z)
{
int a,b,c;
a=10;
b-5;
c=2;
...
return;
}
int TestFunction()
{
MyFunction(1,2,3);
...
}

当调用这个函数时,MyFunction()的汇编代码大致如下:

_MyFunction:
		push ebp					;//保存ebp的值
		mov  ebp,esp				;//将esp的值赋给ebp,使新的ebo指向栈顶
		sub  esp,0x12				;//分配额外的空间给本地变量
		mov  qword ptr [ebp-4],10	;//对栈中内存进行赋值操作
		mov  qword ptr [ebp-8],5	;//对栈中内存进行赋值操作
		mov  qword ptr [ebp-12],2	;//对栈中内存进行赋值操作

图解:
此时调用者做了两件事,
第一,将被调用者函数的参数压入栈中。
第二、将返回地址压入栈中。
这两件使都是调用者负责的,因此压入的栈应该属于调用者的栈帧。
再看被调用者,同样做了两件事。
第一、将原来的(调用者的)ebp压入栈中,此时esp指向它/
第二、将esp的值赋给ebpebp就有了新的值,它也指向存放在原来ebp的栈空间。这时他成了是函数MyFunction()栈帧的栈底。这样,我们就保存了”调用者“函数的ebp,并建立了一个新的栈帧。
ebp更新后,物品们先分配出一块0x12字节的空间用于存放本地变量,这步使用sub实现。通过使用mov转移指令配合字节数 ptr [offset]我们便可以给abc赋值。
在这里插入图片描述

函数的返回

和函数调用时正好相反。当函数完成任务后,它会将esp移到ebp处,然后再弹出原来的ebp的值到ebp寄存器。这样ebp就恢复到了函数调用之前的状态了。

int MyFunction(int x,int y,int z)
{
int a,b,c;
a=10;
b-5;
c=2;
...
return;
}

其汇编大致如下:

_MyFunction:
	push ebp
	mov  ebp,esp
	...
	mov  esp,sbp
	pop ebp
	ret

ret指令的解释,这个指令相当于pop+jump,它先将数据(返回地址)弹出栈并保存到eip中,然后处理器根据这个地址无条件地跳转到相应位置获取新的指令。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值