首页 > 解决方案 > ***检测到堆栈粉碎***:终止 Aborted (core dumped) 错误只发生在有时?

问题描述

我正在完成一项家庭作业(因此我无法发布代码),并且我很少收到此运行时错误:

*检测到堆栈粉碎*:终止中止(核心转储)

当我再次运行可执行文件时,一切正常。这个错误有时只出现是有原因的吗?作为参考,我试图完成的任务是让我们将文件中的数据加载到两个向量中,并对数据进行二进制和线性搜索,以查看向量 1 中的数据是否出现在向量 2 中。

谢谢!

编辑:附加信息:当我收到此错误时,输入数据没有任何变化。我可以运行完全相同的可执行文件,使用完全相同的输入数据一次并让它工作,第二次运行它,得到堆栈粉碎错误,然后运行完全相同的东西,让它再次正常工作。

标签: c++c++11buffer-overflow

解决方案


*** stack smashing detected ***顾名思义,当您粉碎堆栈时会发生错误,这意味着您有缓冲区溢出并且金丝雀被不同的值覆盖。这是 gcc/g++ 实现的一种安全机制,用于防止使用 -fstack-protector.

为避免此错误,fstack-protector请在编译代码时在 gcc 中禁用

g++ myProgram.c -o myProgram -fno-stack-protector

编辑 1
但是,禁用堆栈保护将消除此错误,但您可能会segmentation fault因为覆盖堆栈而得到。

如果这是一个计算机安全任务,您正在处理缓冲区溢出漏洞,那么您需要弄清楚绕过这些安全机制,如果您不熟悉它,那么您会以某种方式溢出缓冲区并且不查看代码我可以' t 评论太多问题究竟出在哪里。

要查看向量 1 中的数据是否出现在向量 2 中,这确实看起来像是一种缓冲区溢出分配,您需要相互覆盖数组的内容。这个错误的事实并不一致,因为有时金丝雀没有被覆盖(程序的正常运行)或被相同的确切值覆盖,有时金丝雀被不同的值覆盖,导致此错误。

您需要配置编译器以使缓冲区溢出更容易。

编辑 2

您的程序行为是随机的,因为您可能没有禁用 ASLR(地址空间布局随机化)。当您编译您的程序时,您的编译器 gcc/g++ 会针对安全机制优化您的可执行文件,以防止缓冲区溢出漏洞。

地址空间布局随机化 (ASLR) 是一种计算机安全技术,用于防止利用内存损坏漏洞。为了防止攻击者可靠地跳转到例如内存中的特定被利用函数,ASLR 随机排列进程关键数据区域的地址空间位置,包括可执行文件的基址以及堆栈、堆的位置和图书馆。

这意味着地址空间分配是随机的,并且向量之间的字节每次都不同。有时溢出的缓冲区不会到达金丝雀,有时会。要每次都获得一致的行为,您还需要禁用 ASLR。ASLR 支持由您的操作系统提供。要禁用 ASLR,在 linux 上通过设置randomize_va_space为 0 来禁用它。可以通过以下方式实现

echo 0 > /proc/sys/kernel/randomize_va_space

推荐阅读