观察
当Linux可执行文件编译为PIE(位置独立可执行文件,在Ubuntu 18.04上默认)时,共享库(例如libc)中的符号将在程序开始执行时解析,将LD_BIND_NOW环境变量设置为null不会延迟此操作。过程。
但是,如果可执行文件是使用-no-pie
标志编译的,则符号解析可以由LD_BIND_NOW控制。
问题
是否可以控制何时在ELF PIE可执行文件上解析共享库中的符号?
下面是我测试中的代码和系统信息,
ubuntu: 18.04
kernel: 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-peda
,将显示用于每个步骤的命令。
每当执行在gdb中进行时,将显示puts
上存储在disp
的GOT条目中的地址。因此,可以很容易地发现修补实际地址的阶段。
Outputs用于-no-pie
二进制测试。
Outputs用于pie
二进制测试。
顺便说一句,相同的问题最初发布在逆向工程堆栈交换中,并且answer证实了上述观察结果。
答案 0 :(得分:1)
当Linux可执行文件编译为PIE(位置独立可执行文件,在Ubuntu 18.04上默认)时,共享库(例如libc)中的符号将在程序开始执行时解析,将LD_BIND_NOW环境变量设置为null不会延迟此操作。过程。
但是,如果可执行文件是使用-no-pie标志编译的,则符号解析可以由LD_BIND_NOW控制。
您误会了:无论程序是否定义为LD_BIND_NOW
,在 情况下开始执行程序时,符号解析仅发生在 。>
LD_BIND_NOW
控制的是所有功能是否一次被解析 (在程序启动期间),还是这些符号是否被懒散地解析(第一次a程序调用给定的未解析函数)。有关延迟解析here的更多信息。
据我了解,在上图中,PIE和非PIE二进制文件之间没有任何变化。我很想知道如何您得出的结论是有区别的。