0

我的 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>

如何禁用它?

4

1 回答 1

2

以下是我的makefile
gcc -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,并且您应该能够从中猜测这些函数的来源。

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

于 2015-05-30T19:41:46.847 回答