简单栈溢出
C语言中,每一个函数调用都会有自己的栈空间,WIN32下用2个寄存器来标识位于栈顶的工作单元:EBP:指向当前工作栈区的底部
ESP:指向当前工作栈区的顶部
函数调用步骤为:
(1) 参数从右至左依次入栈
(2) 返回地址入栈
(3) 代码区跳转
(4) 更改EBP,ESP寄存器,开辟新的栈工作区
一个函数调用时的指令大致为
! push arg2;
push arg1;
push arg0;
push 返回地址;
push ebp; //保存旧的栈区底部
mov ebp,esp; //栈区单元切换
sub esp,xxx; //抬高栈顶,开辟新栈区
注:栈在内存中是从高地址向低地址延伸的,即栈顶位于低地址单元。一个函数开始时,ebp指向返回地址.
实例:
一个C函数如下:
int verify(char* key)
{
int right;
char buf[8];
right = strcmp(“12345”, key);
strcpy(buf, key);
return right;
}
则工作栈区如图,此时,若构造key为 “1234123412341234xxxx”总共20字节,后面xxxx为4字节的16进制地址,则strcpy函数后xxxx将覆盖原来的返回地址,即可将程序流程定位到任何位置。
在本机上调试之后发现,老EBP和第一个变量之间还有2个单元被占用,因此我将key修改为28个字节,恰好覆盖返回地址。(个人猜测是编译器不同造成的,原文作者采用的是VC6,我用的是gcc)
补充:综合编程 , 安全编程 ,