转自: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. 拓展 centos 7

    查看端口的占用情况 Centos6/contos7(ECS) 使用 netstat 查询系统上有多少TCP 多少UDP会话 netstat -tun -t: tcp -u: udp -a: all 表 ...

  2. SpringBoot2.0整合WebSocket,实现后端数据实时推送!

    之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下. 一.什么是 ...

  3. 剑指offer笔记面试题6----从未到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值.链表节点定义如下: struct ListNode{ int m_nKey; ListNode* m_pNext; } 测试用例: 功能测 ...

  4. LINE 项目总结

    前段时间做了一个“国外的公众号”,为什么说是国外的公众号呢,因为他和微信的公众号有很多共通之处.当然了也有很多不同的地方,第一个要说的就是,我在打印信息的时候,使用的alert()弹窗,但是后台才发现 ...

  5. MySQL 字符串分隔成行&子串统计

    利用help_topic表把字符串转换成行(分隔符号',') ),) as `id` FROM mysql.`help_topic`; 统计字符串每个子串出现次数(分隔符号',') ),) AS `s ...

  6. 【实习第十天】odoo开发基础整合

    前言 发文时间是2019年7月19日.提一下学习odoo的感受,odoo目前在国内并不是很流行,且主流是在企业型软件,所以导致目前odoo在网上的文献很少,学习相对来说比其他框架吃力.以下为大家总结1 ...

  7. iOS引导页(开局滚动效果)

    参考链接1:https://jingyan.baidu.com/article/4dc40848a341dfc8d846f152.html 参考链接2:https://www.cnblogs.com/ ...

  8. 1.2 菜单权限 ——MyRapid WinForm快速开发框架-功能介绍

    添加菜单后用户并不会看到菜单 需要经过授权后才能看到 授权界面如图 授权的数据逻辑可以理解为一个键值对 角色>>菜单 但是为了方便集中数据管理 我设计成了 角色>>资源 其中的 ...

  9. Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt

    最近安装python,已经安装好,cmd终端中输入python.pip等命令都有用 然而在配置requirements.txt文件过程中,执行语句 “pip install -r requiremen ...

  10. jmeter相关知识学习记录

    基于Jmeter5.2.1 断言之响应断言 响应断言:对服务器的响应接口进行断言校验,来判断接口测试得到的接口返回值是否正确. 测试字段就是指要断言的内容的匹配处. 响应文本:就是响应的body部分: ...