有两个文件,一个编译并链接gcc
,另一个手动使用nasm
,我ld
得到
- ELF 32 位 LSB 共享对象...
- ELF 32 位 LSB 可执行文件...
这两件事有什么区别?我可以看到readelf -h
那个是
- 类型:
DYN (Shared object file)
- 类型:
EXEC (Executable file)
我可以看到这些记录在维基百科为ET_DYN
和ET_EXEC
。这两者之间有什么实际差异?
答案1
这似乎与位置无关可执行文件(PIE)有关。当 GCC 默认编译可执行文件时,它会使它们成为 PIE,从而将 ELF 标头上的输出标志更改为ET_DYN
.
您可以使用以下命令禁用 PIE 可执行文件的生成
gcc -no-pie
如果您看到此检查 gcc 配置的默认选项gcc -v
,您应该看到类似的内容--enable-default-pie
。
回答受到启发通过 StackOverflow 上的此提交。我打算在这里更多地使用它并解释更多。
答案2
看来 Linux 内核/动态加载器中 ET_EXEC 与 ET_DYN 的主要作用是通知可执行文件是否可以使用 ASLR 放置在随机内存位置。
正如您得出的结论,PIE 可执行文件是 DYN,因为它们可以随机化,就像共享库一样。
我已经对此进行了更详细的探索,并且: