%20%E5%92%8C%E2%80%9CLSB%20%E5%85%B1%E4%BA%AB%E5%AF%B9%E8%B1%A1%E2%80%9D(ET_DYN)%20%E4%B9%8B%E9%97%B4%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F.png)
有两个文件,一个编译并链接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,因为它们可以随机化,就像共享库一样。
我已经对此进行了更详细的探索,并且: