【问题标题】:LD_BIND_NOW doesn’t take effect on ELF PIE executableLD_BIND_NOW 不会对 ELF PIE 可执行文件生效
【发布时间】:2019-06-08 23:26:36
【问题描述】:

观察

当 Linux 可执行文件被编译为 PIE(Position Independent Executable,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 中执行时,将显示存储在 GOT 条目中的 puts 的地址(通过 disp)。这样就很容易看出打了真实地址的阶段。

Outputs 用于-no-pie 二进制测试。
Outputs 用于pie 二进制测试。


顺便说一句,同样的问题最初发布在 Reverse Engineering Stack Exchange 中,answer 证实了上述观察结果。

【问题讨论】:

    标签: elf


    【解决方案1】:

    当 Linux 可执行文件被编译为 PIE(Position Independent Executable,Ubuntu 18.04 上的默认值)时,来自共享库(例如 libc)的符号将在程序开始执行时被解析,将 LD_BIND_NOW 环境变量设置为 null 不会推迟这个过程。

    但是,如果使用 -no-pie 标志编译可执行文件,则符号解析可以由 LD_BIND_NOW 控制。

    你错了:符号解析只在在程序开始执行时发生任何一种情况,不管LD_BIND_NOW是否被定义。

    LD_BIND_NOW 控制的是是否所有函数都被解析一次(在程序启动期间),或者这些符号是否被延迟解析(程序第一次调用给定的未解决函数)。更多关于惰性分辨率here.

    据我了解,上图中 PIE 和非 PIE 二进制文件之间没有任何变化。我很想知道您是如何得出结论的,即存在差异。

    【讨论】:

    • 添加了更多信息,你会发现那里有什么问题吗?
    猜你喜欢
    • 2018-06-15
    • 2015-09-10
    • 2012-12-09
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    相关资源
    最近更新 更多