对于一个家庭作业,我进行了一系列的缓冲区溢出攻击。 我得到了一个程序来拆卸,在C源代码是不正确调用一个函数gets()
,并为我应该强制程序调用其他几个功能的源代码。 对于任务之一,我必须:
- 注入一些代码,变化的值,然后
- 回到前述的方法之一
我不明白的地方确定在哪里返回时,程序会在堆栈中的主要的事情。 在哪里保存在栈上的返回地址的方法?
该程序被编译为86。
对于一个家庭作业,我进行了一系列的缓冲区溢出攻击。 我得到了一个程序来拆卸,在C源代码是不正确调用一个函数gets()
,并为我应该强制程序调用其他几个功能的源代码。 对于任务之一,我必须:
我不明白的地方确定在哪里返回时,程序会在堆栈中的主要的事情。 在哪里保存在栈上的返回地址的方法?
该程序被编译为86。
你需要知道的:
当调用一个函数,参数,然后EIP(因此被调用函数知道在哪里返回)保存在栈上。
当编译器被告知(显式或隐式)使用帧指针,它然后保存在栈帧指针(在EBP寄存器)(所以它可以在以后恢复帧指针到了关于调用函数的值) ,然后设置帧指针指向堆栈的当前顶部。 这允许从参考(帧指针)的一个已知点容易访问参数和局部变量,并大大简化了调试。
在x86函数调用看起来是这样的:
...
int main() add $-0x8,%esp ; alignment
{ push $0x2 ; arg 2
... push $0x1 ; arg 1
func(1, 2); call func ; function call
... add $0x10,%esp ; pop args from stack
} ...
而调用的函数看起来是这样的:
void func(int arg1, int arg2) push %ebp ;\
{ mov %esp,%ebp ;/ create stack frame
int local1; sub $0x18,%esp ; reserves space
... ...
} mov %ebp,%esp ;\
pop %ebp ;/ destroys frame
ret ; returns
因此,堆栈将类似于:
: :
+-----------+
: alignment :
+-----------+
12(%ebp) | arg2 |
+-----------+
8(%ebp) | arg1 |
+-----------+
4(%ebp) | ret | -----> return address
+-----------+
(%ebp) | ebp | -----> previous ebp
+-----------+
-4(%ebp) | local1 | -----> local vars
+-----------+
: alignment :
+-----------+
: :
(下地址是下对ASCII艺术)