转自:https://blog.csdn.net/lhl_blog/article/details/70193865

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/linux_embedded/article/details/70193865
GCC “stack smashing detected”机制
相信使用C/C++语言开发软件的程序猿们都经历过‘栈溢出’的问题。‘栈溢出’问题通常十分的隐蔽,有的时候问题复现也十分的困难。每当软件出现莫名其妙的问题时,总是有人怀疑是不是栈溢出了,但是问题的排查又十分的困难,所以,‘栈溢出’就是广大C/C++开发者的噩梦。大家不禁要问有没有通用的方法来避免或者来检测’栈溢出‘问题呢?其实,’栈溢出‘问题有的时候是没有办法避免的,即使是经验丰富的程序猿同样可以陷入’栈溢出‘的陷阱,相信大家都听说过很多知名的软件系统由于‘栈溢出’而导致的各类安全问题。为了减少‘栈溢出’的出现几率,我们平时在编写代码的时候要时刻注意栈上的缓冲区的使用方式,熟悉关于栈缓冲区的各种操作API(使用最为频繁的就是字符串操作函数)的正确使用方式。但是,人总有犯错误的时候,那有没有一种机制来检测‘栈溢出’呢?今天要说的就是gcc编译器提供关于stack保护的各种机制。
首先,来看一个比较明显的栈溢出的代码段,本段代码的编译平台为:Ubuntu14.04 Gcc的版本为4.8.4。代码内容如下:

#include <string.h>
#include <stdio.h>

int main(void)
{
char array[5] = {0};

strcpy(array, "stackoverflow");

return 0;
}

该段代码,首先定义了一个char型数组,数组大小为5,然后我们使用strcpy函数拷贝字符串“stackvoerflow”到array缓冲区,很明显array缓冲区溢出了,稍后会介绍strcpy的使用方式。

然后,我们编译运行,结果如下:

lhl@lhl-Aspire-4930:~/技术总结/linux/gcc$ ./buscore
*** stack smashing detected ***: ./buscore terminated
已放弃 (核心已转储)

可以看到程序崩溃了,而且还有一些提示信息:

*** stack smashing detected ***: ./buscore terminated
1
该提示信息就是gcc提供的栈溢出保护机制在检测到程序存在缓冲区溢出时所打印出来的提示信息。那gcc提供栈溢出保护机制是什么呢?

通过查看gcc的使用手册,我们可以知道该报机制为gcc的-fstack-protector一系列选项所提供的缓冲区溢出检测机制。下面为该机制的原理介绍:

当-fstack-protector启用时,当其检测到缓冲区溢出时(例如,缓冲区溢出攻击)时会立即终止正在执行的程序,并提示其检测到缓冲区存在的溢出的问题。这种机制是通过在函数中的易被受到攻击的目标上下文添加保护变量来完成的。这些函数包括使用了allcoa函数以及缓冲区大小超过8bytes的函数(此处不是很明白,上面的例子缓冲区大小为5同样触发了该机制)。这些保护变量在进入函数的时候进行初始化,当函数退出时进行检测,如果某些变量检测失败,那么会打印出错误提示信息并且终止当前的进程。

注意:在测试过程中,当缓冲区的大小小于8bytes同样触发了该机制。在函数中使用了alloca函数后,缓冲区溢出后但没有触发该机制,不知为何?
>

char *stack_ptr = alloca(0);

char *str = "hello, world";

strcpy(stack_ptr, str);

printf("stack_ptr = %s\n", stack_ptr);
上面的代码并不能触发该机制?

那问题来了,-fstack-protector真的是万能的吗?它真的可以检测一切栈溢出的问题吗?我们可以通过下面的例子测试一下:

#include <alloca.h>
#include <string.h>
#include <stdio.h>

typedef struct
{
char str[2];
}overflow_t;
int main(void)
{
char *str = "welcom to China";

overflow_t v;

printf("sizoef(v) = %d\n", sizeof(v));

memcpy(&v, str, strlen(str));

printf("v.str = %s\n", v.str);
}

gcc buscore.c -o buscore,我们编译运行结果如下:
sizoef(v) = 2
v.str = welcom to China

我们看到程序正常执行了,并没有触发栈溢出检测?这是为什么呢?通过进一步查阅gcc手册,发现其还提供一个-fstack-protector-all选项,其解释为:

其功能类似于-fstack-protector,但是其为所有的函数都进行栈溢出检测。重新编译程序,并加上-fstack-protector-all选项,然后运行结果如下:

sizoef(v) = 2
v.str = welcom to China
* stack smashing detected *: ./buscore terminated
已放弃 (核心已转储)。可以看到进程成功的检测到了栈溢出。

所以,我们在开发软件时,最好加上-fstack-protector-all选项,这很大一部分栈溢出问题就会被探测到。

同时我们也应该注意到,当进程由于栈溢出崩溃时,会产生coredump文件,对于coredump的配置可以参见
Android系统coredump这篇文章。
那怎么根据coredump文件定位问题呢?上面介绍-fstack-protector机制的原理时,说过其会在函数退出时进行检测,这样我们就可以根据coredump中的函数栈信息定位到发送栈溢出的函数,这样问题的范围就大大缩小了,我们可以专注于查看出问题的函数,然后定位出哪里存在栈溢出。
————————————————
版权声明:本文为CSDN博主「奔跑的码仔」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lhl_blog/article/details/70193865

gcc-stack-protector机制【转】的更多相关文章

  1. gcc栈溢出保护机制:stack-protector

    关键词:stack-protector.stack-protector-strong.stack-protector-all等等. 1. gcc栈保护机制stack-protector简介 gcc提供 ...

  2. 编译驱动模块时,出现“stack protector enabled but no compiler support”[解决办法]【转】

    转自:http://blog.chinaunix.net/uid-26847859-id-3297170.html 原文地址:编译驱动模块时,出现“stack protector enabled bu ...

  3. Using gcc stack debug skill

    The stack error is hard to debug, but we can debug it assisted by the tool provided by GCC. As we kn ...

  4. linux提权辅助工具(一):linux-exploit-suggester.sh

    来自:https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh ...

  5. c c++ 函数入口和出口的hook(gcc 编译选项),然后打印出函数调用关系的方法

    GCC Function instrumentation机制可以用来跟踪函数的调用关系,在gcc中对应的选项为“-finstrument-functions”.可查看gcc的man page来获取更详 ...

  6. 了解甚少的GNU C的__attribute__ 机制

    平时忙着赶项目,很多东西都是不求甚解,当工作中遇到的一些比较刁钻的问题时,才发现自己和那些大牛的 差距---内功.熟练码农和码神的最大区别估计就是内功是否深厚了.在自我反思的过程中,也要逐渐的积累一些 ...

  7. link options and how g++ is invoked gcc g++

    yum install gcc yum install gcc-c++ yum reinstall gcc gcc-c++ Downloading packages:(1/2): gcc-c++-4. ...

  8. 使用gcc的-finstrument-functions选项进行函数跟踪【转】

    转自:http://blog.csdn.net/jasonchen_gbd/article/details/44044899 版权声明:本文为博主原创文章,转载请附上原博链接. GCC Functio ...

  9. 结合python版本安装python-devel gcc和g++的区别 安装前做yum搜索

    [test@ecs autocloudservices]# yum install python-develLoaded plugins: fastestmirrorLoading mirror sp ...

随机推荐

  1. Android odex,oat文件的反编译,回编译

    现在,许多Android手机的ROM包在生成过程中都启用优化,把jar文件抽空,生成odex/oat和vdex文件,以在运行时省掉编译时间.如果想对这些jar进行修改,就要修改它们所对应的odex或者 ...

  2. pctfree和pctused

    pctfree 是指一个数据块保留的空间百分比,表示数据块在什么情况下可以被insert 默认是10,表示当数据块的可用空间低于10%后,就不可以被insert了,只能被用于update了 即:当使用 ...

  3. Python用pip安装第三方库时换源下载

    pip默认是从Python官网下载第三方库,从国外下载当然不如从国内下载来得快 豆瓣:https://pypi.doubanio.com/simple 还有其它源,阿里云等等,一个就够用了 用pip安 ...

  4. Create a Report in Visual Studio 在Visual Studio中创建报表

    In this lesson, you will learn how to create reports in the integrated reporting system. This system ...

  5. JS---DOM---为元素绑定事件的引入,为元素绑定多个代码,兼容代码

    1. 为元素绑定事件的引入: 用src直接绑定多个,只实现最后一个(programmer2.js) <input type="button" value="按钮&q ...

  6. Dynamics 365中开发和注册插件介绍

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  7. 挖掘Dark Sky Maps(热的要死后,疯传的一个气温地图网站)

    最近,各种朋友圈,社会媒体,都在疯传一张图,这张图显示的全球的气温图,本没有什么特别的,但是这张图的网站来源所展示的数据与气象局或者各种天气预报的温度值相差倒是不少,引来一片网友的吐槽. 但是,作为专 ...

  8. QT--吃月亮小游戏

    QT--吃月亮小游戏 简介: 该设计使用了鼠标事件.键盘事件.绘图事件,可通过鼠标或者方向键控制人物移动吃到月亮 代码: 1.widget.h文件: #ifndef WIDGET_H #define ...

  9. 【计算机网络】ISO/OSI 网络体系结构

    ISO/OSI 网络体系结构 计算机网络是相当复杂的系统,相互通信的两个计算机系统必须高度协调才能正常工作.为了设计这样复杂的计算机网络,人们提出了将网络分层的方法.分层可将庞大而复杂的问题转换为若干 ...

  10. apache storm基本原理及使用总结

    什么是Apache Storm Apache Storm是一个分布式实时大数据处理系统.Storm设计用于在容错和水平可扩展方法中处理大量数据.它是一个流数据框架,具有最高的摄取率.虽然Storm是无 ...