PWN菜鸡入门之函数调用栈与栈溢出的联系

栈溢出(一)—— 函数调用栈

一、函数调用栈过程总结

PWN菜鸡入门之函数调用栈与栈溢出的联系

Fig 1. 函数调用发生和结束时调用栈的变化

PWN菜鸡入门之函数调用栈与栈溢出的联系

Fig 2. 将被调用函数的参数压入栈内

PWN菜鸡入门之函数调用栈与栈溢出的联系

Fig 3. 将被调用函数的返回地址压入栈内

PWN菜鸡入门之函数调用栈与栈溢出的联系

Fig 4. 将调用函数的基地址(ebp)压入栈内,并将当前栈顶地址传到 ebp 寄存器内

PWN菜鸡入门之函数调用栈与栈溢出的联系

Fig 5. 将被调用函数的局部变量压入栈内

二、函数调用栈实例说明

首先我们来看看以下程序调用栈的过程:

int sum(int a,int b)
{
    int temp = 0;
    temp = a+b;
    return temp;
}
int main()
{
    int a = 10;
    int b = 20;
    int ret = 0;
    ret = sum(a,b);
    cout<<ret<<endl;
​
    return 0;
}

 

如下调用过程:

每个函数在调用前都会做一件事情。 (1)把调用方的ebp入到自己的栈里去 (2)用esp指向新的栈顶位置,把esp的值赋给ebp,产生新的ebp (3)开辟空间,初始0XCCCCCCCC。 ebp入栈,实参入栈,形参入栈,调用call指令。call有两步,把下一行指令的地址入栈,跳转到调用的函数执行。形参内存主调方开辟,主调方释放。

main函数栈帧

PWN菜鸡入门之函数调用栈与栈溢出的联系

开辟sum函数栈帧

PWN菜鸡入门之函数调用栈与栈溢出的联系

sum函数内存布局

PWN菜鸡入门之函数调用栈与栈溢出的联系

 

三、函数调用栈在栈溢出中的难点

栈溢出的shellcode中经常会出现:

payload : padding1 + address of shellcode + padding2 + shellcode

PWN菜鸡入门之函数调用栈与栈溢出的联系

payload: padding1 + address of system() + padding2 + address of “/bin/sh”

PWN菜鸡入门之函数调用栈与栈溢出的联系

这几种payload,很多教程对于padding2这个没有解释的很清楚,ctf wiki上是这样说的 :“如果是正常调用 system 函数,我们调用的时候会有一个对应的返回地址”

因为不用考虑相应的getshell的结束,我们可以从之前的介绍得知这是main函数调用后的下一条指令的地址,也就是return完system后我们将要继续执行的指令,也就是说如果我们还想继续调用的话这个padding2可以放下一个要执行的地址。

上一篇:攻防世界pwn新手练习(CGfsb)


下一篇:PWN入门