Level1
Level1是和level0一样调用完getbuf以后我们不返回getbuf的调用者test而是去执行fizz函数,区别就是这个fizz函数要求我们传入参数,而且传入的参数必须是我们的cookie。所以在level0的方法我们轻松的知道了如何去执行fizz,就是用fizz函数的入口地址去覆盖返回地址,这里的关键就是找到fizz函数的参数从栈中的什么地方传入的,然后我们把我们的cookie写进这个fizz会获取参数的地方。一般参数都是从调用者的栈传到被调用者的栈中的,由实参传递给函数的形参,在我的文章底层实现理解函数传参,实参,形参中有讲解,可以去看看。
首先我们来看看一般函数调用的传参的底层汇编代码是实现:图片就是我之前那个文章中的图:为了方便就直接分析这个好了。可以看出一般函数的实参都是从栈顶指针开始保存的,esp开始,然后依次向上4i+4个地址,函数如果只有一个参数那么就是放在esp,如果有三个,第一个就放在esp,第二个放在esp+4,第三个在esp+8。然后参数有实参传递给形参的传参过程也就是,被调用的函数去调用者的函数中去取实参的值(参数从寄存器中压入了调用者的栈中了)再压入到自己的栈中,所以看到ebp都是加多少的,而不是减多少中取的,原第一个参数在原调用者函数的esp中,在被调用着栈中就是esp+8的位置处。
把这个函数传参的栈画出来:
在这里黄色是调用者函数的栈,蓝色的被调用者函数的栈,可以看到参数x在原调用者栈的esp处,y在esp+4,k在esp+8.然后红色代表被调用者func4函数的esp和ebp,可以看到第一个参数x在ebp+8,第二个y在ebp+c处等。ebp+4为调用者函数执行call指令后压入的返回地址。