栈溢出概述
栈溢出是比较常见的一个安全漏洞,因为程序员的一些粗心大意使用了一些被微软淘汰的函数如:strcpy、sprintf 等,特别是在字符串拷贝时。正常情况出现栈溢出时程序会跳到不可执行的内存中从而导致查询崩溃。但是如果这个字符串是由外界输入(用户界面等)那么这其中就可以做许多手脚,微软在防止栈溢出漏洞也做了许多努力(gs-security cookie,变量重排,地址随机化等等),特别是在高版本的vs中编译时不允许使用以上提到的不安全函数。但是依然有一些老的项目和老平台(XP)存在这些漏洞。
栈溢出的原因
我们先看一下在函数调用时,栈上的数据变化(如下图)

比如一个C函数void add(3,4);的函数调用
void add (int 3,int 4)
{
char buf[10];
}
由于_cdecl 是C和C++默认的调用约定
- 所以系统先将参数从右到左依次入栈:

- 然后再将eip入栈(这个就是函数的返回地址),再将ebp入栈:

-
最后将局部变量入栈(因为局部变量是在栈中):
字节对齐后栈的变化如下:

此时栈顶指针距离我们的eip为16个字节
以上便是函数调用时栈的变化情况
试想一下当我们使用strcpy往局部变量拷贝数据大于16字节时,将eip覆盖成shellcode代码的地址,便可以完成一次栈溢出攻击
基于这个变化我们下一章将使用OD对一个栈溢出漏洞进行逆向调试分析
网友评论