编译时如何禁用relro?

逆向工程 小精灵 编译器 安全
2021-07-02 08:59:52
#include <stdio.h>
#include <stdlib.h>


int main(int argc, int *argv[])
{
size_t *p = (size_t *) strtol(argv[1], NULL, 16);

p[0] = 0xDEADBEEF;

printf("RELRO: %p\n", p);

return 0;
}

在编译上面带参数的代码时
$ gcc -g -Wl,-z,relro -o test test.c

并在生成的二进制文件上运行 checksec
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH 69 Symbols No 0 1 test

使用以下命令运行
$ gcc -g -Wl,-z,relro,-z,now -o test test.c

并在生成的二进制文件上运行 checksec
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Full RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH 71 Symbols No 0 1 test-full

在使用命令编译 $ gcc -o test test.c
并在生成的二进制文件上运行检查时
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Full RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH 66 Symbols No 0 1 test

我的疑问是如何在没有 relro 的情况下编译二进制文件?以及为什么在我们不提供任何标志时启用 full-relro ?

1个回答

要启用完整的 relro:

-Wl, -z,relro,-z,now

这有什么作用?- 它为-z,relro,-z,now链接器提供标志作为参数。这将启用完整的 relro(通知-z,now标志)。

现代 gcc 编译器默认启用部分 relro。

如何禁用relro?通过以下标志

-Wl,-z,norelro

完整和部分 relro 之间的区别:部分 relro 使部分 .got 部分(非 .plt)部分只读并更改对齐顺序部分使.got部分出现在数据部分 ( .bss, '.data') 和 make 之前,而完整 relro 使完整的.got部分只读(包括 .got.plt)并且还像部分 relro 一样重新排序部分(产生启动开销)。