34

我用 C 编写了一个应用程序,我试图了解-fno-stack-protector编译时命令的目的是什么。对于我的特定应用程序,是否使用此命令在防止缓冲区溢出方面没有区别。

我在网上读到-fstack-protectorand-fno-stack-protector命令分别启用和禁用堆栈粉碎保护器,但是如果我自己编译应用程序,如何事先启用保护器?该命令的使用是否可能取决于应用程序运行的系统?

4

5 回答 5

23

在标准/库存 GCC 中,堆栈保护器默认关闭。但是,一些 Linux 发行版已对 GCC 进行了修补以默认将其打开。在我看来,这是相当有害的,因为它破坏了编译任何未链接到标准用户空间库的内容的能力,除非 Makefile 专门禁用堆栈保护器。它甚至会破坏 Linux 内核构建,只是带有此 hack 的发行版向 GCC 添加了额外的 hack,以检测内核正在构建并禁用它。

于 2012-05-23T03:23:40.713 回答
17

如果您使用 编译-fstack-protector,那么在代码设置检查然后实际检查您是否已覆盖堆栈时,堆栈上将分配更多空间,并且在进入和返回函数时会产生更多开销功能。

它将对您的应用程序产生影响。如果启用,它将快速阻止堆栈溢出攻击。只有当您的代码中没有函数调用时,它才会使您的程序不受影响(并且由于您通常编写main(), 并且这是一个由启动代码调用的函数,它会对您的程序产生影响)。但是,堆栈溢出攻击并不是唯一可以使用的攻击,因此它不是万能的。但它是有用的保护,成本有限。

保护不依赖于系统本身;这取决于您使用的编译器的版本,仅此而已。

于 2012-05-23T03:26:08.823 回答
2

堆栈保护器是由编译器生成并放入您的程序的代码。它不是您的程序调用的外部程序或系统调用。

于 2012-05-23T03:29:57.500 回答
1

匹配默认编译器设置的选项可能有用的时间包括:

  • 当您使用的构建系统可能具有您想要调整的复杂配置时。它可以让您轻松地传递附加选项,而不是弄清楚它可能会选择在迷宫中的哪个位置使用fstack-protector(例如),这些选项只会被添加到选项列表的末尾。如果 GCC 在这组选项中都看到fstack-protectorfno-stack-protector,则命令行中的最后一个是生效的。

  • 另一次这种事情可能很方便(然而,这似乎不适用于-fstack-protector)是当您有一个选项可以打开一堆“子选项”时。例如,设置 -O2 会打开一系列-fxxx优化选项,您可能希望-O2大部分使用但不希望 GCC 的严格别名优化。因此,您可以指定-fno-strict-aliasing将该特定选项设置回其默认设置。(注:这个案例真的和上面的案例是等价的)

于 2012-05-23T06:23:23.907 回答
0

您可能要关闭此功能的三个原因,

  • 您正在构建一个共享库,这可能很重要,其他函数对堆栈进行假设。
  • 你关心性能。
  • 您想构建易受攻击的软件。这种情况经常发生在 Capture The Flag (CTF) 之类的情况下,例如,如果您想构建 Protostar 来展示一个您也不会容易受到攻击的漏洞利用。
于 2018-11-06T03:46:40.160 回答