LD_BIND_NOW对ELF PIE可执行文件无效,如何控制其动态符号解析时机?
能否控制ELF PIE可执行文件的共享库符号解析时机?
简单来说,不行——当Linux下的ELF可执行文件以PIE(位置无关可执行文件,Ubuntu 18.04默认编译选项)编译时,共享库(比如libc)的符号会在程序启动阶段就完成解析,即使设置LD_BIND_NOW=""也无法推迟这个过程;但如果用-no-pie标志编译非PIE可执行文件,就可以通过LD_BIND_NOW环境变量控制符号解析的时机。
测试环境
- Ubuntu版本:18.04
- 内核:
Linux 4.15.0-50-generic #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux - GCC版本:
gcc (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
测试代码
#include <stdio.h> int main() { printf("Hello world!\n"); }
实验验证过程
我用gdb-peda工具做了详细实验,核心思路是借助gdb的disp命令,让每次进程执行时自动打印puts的GOT条目地址——通过观察这个地址的变化,就能明确符号被替换为真实地址的时间点:
- 非PIE二进制测试:用
gcc -no-pie test.c -o test_no_pie编译后,设置LD_BIND_NOW=0时,符号解析会推迟到第一次调用printf(实际调用puts)时才完成;设置LD_BIND_NOW=1则会在程序启动阶段就完成解析,GOT地址的变化完全符合预期。 - PIE二进制测试:用默认选项
gcc test.c -o test_pie编译后,不管有没有设置LD_BIND_NOW="",puts的GOT条目地址在程序启动时就已经被替换为真实的共享库符号地址,完全没有推迟解析的空间。
内容的提问来源于stack exchange,提问作者Jiaming
相关产品推荐
相关产品推荐

