简单栈溢出
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)