栈溢出攻击c语言_栈溢出攻击

我们先来看下面的一个例子:

~~~

#include

int main(){

char str[10] = {0};

gets(str);

printf(“str: %s\n”, str);

return 0;

}

~~~

在 main() 函数内部定义一个字符数组,并通过 gets() 为它赋值。

在VS2010 Debug模式下运行程序,当输入的字符不超过10个时,可以正确输出,但是当输入的字符过多时,就会出现运行时错误。例如输入”12345678901234567890″,就会出现下面的错误:

![](https://box.kancloud.cn/9d939f22fab553d3bf701939f3c78ac8_623x154.png)

这是为什么呢?我们不妨先来看一下 main() 函数的栈:

![](https://box.kancloud.cn/94fc205f6aa42915645de5807db261e8_181x300.png)

局部数组也是在栈上分配内存,当输入”12345678901234567890″ 时,会发生数组溢出,占用“4字节空白内存”、“old ebp”和“返回地址”所在的内存,并将原有的数据覆盖掉,这样当 main() 函数执行完成后,会取得一个错误的返回地址,该地址上的指令是不确定的,或者根本就没有指令,所以程序在返回时出错。

C语言不会对数组溢出做检测,这是一个典型的由于数组溢出导致覆盖了函数返回地址的例子,我们将这样的错误称为“栈溢出错误”。

> 注意:这里所说的“栈溢出”是指栈上的某个数据过大,覆盖了其他的数据

局部数组在栈上分配内存,并且不对数组溢出做检测,这是导致栈溢出的根源。除了上面讲到的 gets() 函数,strcpy()、scanf() 等能够向数组写入数据的函数都有导致栈溢出的风险。

下面是使用 strcpy() 函数导致栈溢出的例子:

~~~

#include

#include

int main(){

char *str1 = “sfsdffffffffaeggggggg3r4t4nihfgi23ufhbu4bgui3beugb”;

char str2[6] = {0};

strcpy(str2, str1);

printf(“str: %s\n”, str2);

return 0;

}

~~~

将 str1 复制到 str2,显然超出了 str2 的接受范围,会发生溢出,覆盖返回地址,导致 main() 函数返回时出错。

栈溢出一般不会产生严重的后果,但是如果有用户精心构造栈溢出,让返回地址指向恶意代码,那就比较危险了,这就是常说的栈溢出攻击

    原文作者:戚琳
    原文地址: https://blog.csdn.net/weixin_42489088/article/details/114020123
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞