转自: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. laravel 框架源码分析

    laravel框架的文档中的例子很多时候不是很明显,所以想要真正的使用好这个框架,我们可以尝试去阅读它源码中的注释(不得不说laravel源码的注释还是很详细的). 我们先来看一下laravel 的文 ...

  2. 记一次ES查询数据突然变为空的问题

    基本环境 elasticsearch版本:6.3.1 客户端环境:kibana 6.3.4.Java8应用程序模块. 其中kibana主要用于数据查询诊断和查阅日志,Java8为主要的客户端,数据插入 ...

  3. 从零开始学vuejs

    最近一段时间都花在了学习vue上,还总是断断续续的,学习的效果不是很明显,思考了好久了,应该是没有进行一个系统的总结,导致很多知识点总是似是而非,而且也有一部分是思维还没有从java转变过来,废话不多 ...

  4. Python 基础语法-str

    字符串常见操作 find:检测str是否包含在 mystr 中,如果是返回开始的索引值,否则返回 -1 mystr.index(str, start=0, end=len(mystr)) count: ...

  5. SQL Server优化技巧——如何避免查询条件OR引起的性能问题

    之前写过一篇博客"SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析",里面介绍了OR可能会引起全表扫描或索引扫描的各种案例,以及如何优化查询条件中含有OR的SQL语句的 ...

  6. screen工具的安装与使用

    yum install screen    安装screen screen -S <作业名称>     创建新的页 screen -ls   查询已经存在的页面 screen -r < ...

  7. WASM 成为 HTML、CSS 与 JS 之后的第 4 门 Web 语言

    大家都知道,万维网联盟 W3C 认证的 Web 语言有 HTML.CSS 与 JavaScript,而近日联盟正式宣布 WebAssembly 核心规范(WebAssembly Core Specif ...

  8. Java之IO初识(字节流和字符流)

    IO概述 生活中,你肯定经历过这样的场景.当你编辑一个文本文件,忘记了 ctrl+s ,可能文件就白白编辑了.当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里.那么数据都是在哪些设备上的呢 ...

  9. 【Linux命令】磁盘分区,格式化,挂载命令,创建交换分区(fdisk,mkfs,mount,umount)

    友情链接 磁盘分区,格式化,挂载,创建交换分区:https://www.cnblogs.com/HeiDi-BoKe/p/11936998.html RAID工作级别:https://www.cnbl ...

  10. Exe4j 打包: this executable was created with an evaluation version of exe4j

    异常 this executable was created with an evaluation version of exe4j   异常.png 问题原因 当前打包使用exe4j未授权 解决方法 ...