用于链接的 gcc -fno-stack-protector 不起作用

Posted

技术标签:

【中文标题】用于链接的 gcc -fno-stack-protector 不起作用【英文标题】:gcc -fno-stack-protector for linking not work 【发布时间】:2015-05-29 14:34:27 【问题描述】:

我的 gcc 版本:gcc 版本 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

以下是我的makefile

all : main.o utility.o                                                                                                                                                                                       
    gcc -fno-stack-protector -Wl,-z,execstack -o binary main.o utility.o -lcrypto
main : main.c
    gcc -z execstack -fno-stack-protector main.c -c
utility: utility.c
    gcc  -z execstack -fno-stack-protector utility.c -c

文件 utility.o 和 main.o 没有堆栈保护 但是链接后有一些堆栈保护

objdump -D binary | grep chk
080488d0 <__stack_chk_fail@plt>:
 8048e30:   e8 9b fa ff ff          call   80488d0 <__stack_chk_fail@plt>
 80494dd:   e8 ee f3 ff ff          call   80488d0 <__stack_chk_fail@plt>
 80498e2:   e8 e9 ef ff ff          call   80488d0 <__stack_chk_fail@plt>
 8049b92:   e8 39 ed ff ff          call   80488d0 <__stack_chk_fail@plt>
 8049c9e:   e8 2d ec ff ff          call   80488d0 <__stack_chk_fail@plt>
 8049da2:   e8 29 eb ff ff          call   80488d0 <__stack_chk_fail@plt>
 804a137:   e8 94 e7 ff ff          call   80488d0 <__stack_chk_fail@plt>

如何禁用它?

【问题讨论】:

【参考方案1】:

以下是我的makefilegcc -z execstack -fno-stack-protector main.c -c

那个命令是假的;如果有的话,它应该有-Wl,-z,execstack。但是,由于这是一个链接器选项,并且您没有在此处链接,因此最好完全删除 -z exestack

但链接后有一些堆栈保护

__stack_chk_fail 的调用必须来自链接到您的二进制文件的某些代码。也许来自libcrypto.a,或者来自libgcc.a。您可以通过两种方式查看它们的来源:

gcc -fno-stack-protector -Wl,-z,execstack -o binary main.o utility.o \
 -lcrypto -Wl,-y,__stack_chk_fail

会产生这样的消息:

/some/libfoo.a(bar.o): reference to __stack_chk_fail  # you care about this one!
/usr/lib/libc.so.6: definition of __stack_chk_fail

或者你可以使用你已经构建的二进制文件:

objdump -d binary | egrep '>:$|__stack_chk_fail' | grep -B1 __stack_chk_fail

这应该告诉您二进制引用 __stack_chk_fail 中的哪些函数,并且您应该能够从中猜测这些函数的来源。

附:除非您正在研究缓冲区溢出利用技术,否则禁用堆栈保护器并与 -z,execstack 链接是一个非常糟糕的主意

【讨论】:

我不会称其为“伪造”,它是一个实际选项,它是documented,它直接传递给链接器,因此不需要-Wl

以上是关于用于链接的 gcc -fno-stack-protector 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 GCC 链接器命令?

gcc 生成动态链接库

是否有 GCC 编译器/链接器选项来更改 main 的名称? [复制]

gcc 将共享库与依赖库链接

如何在 AIX 中使用 GCC 编译器链接 *.so 文件

为啥 gcc 要我链接到 libgcc_ext.10.5.dylib?