与位置无关的可执行文件和 ptrace
Position-independent executables and ptrace
我想在 Linux 上追踪 PIE,例如在给定的指令地址中断。从反汇编中,我得到了指令的相对地址——如何找出可执行文件的加载位置,以便获得绝对地址?
GDB 能够跟踪 PIE - 它是如何处理的?
how does it deal with this?
在 Linux 上,动态加载器 ld-linux...
有一个特殊函数:_dl_debug_state()
,加载器在加载共享库之前和之后以及设置全局变量之后调用它变量:_r_debug.r_state
到 RT_ADD
或 RT_CONSISTENT
.
调试器可以在该函数上设置断点,检查 .r_state
和 _r_debug.r_map
,并在此过程中发现在哪个地址加载了哪些 ELF 二进制文件。
这个机制被用来发现在哪里。 libc.so.6
在支持 PIE
二进制文件之前很久就已加载。 PIE
二进制文件只是共享库的一个特例,因此完全相同的机制也适用于它。
这引出了一个问题:GDB 如何发现 ld-linux
本身被加载的位置(因此可以设置 _dl_debug_state()
上的断点)。内核 通过辅助向量 AT_BASE
条目告诉 它。有关辅助向量的更多信息 here.
我想在 Linux 上追踪 PIE,例如在给定的指令地址中断。从反汇编中,我得到了指令的相对地址——如何找出可执行文件的加载位置,以便获得绝对地址?
GDB 能够跟踪 PIE - 它是如何处理的?
how does it deal with this?
在 Linux 上,动态加载器 ld-linux...
有一个特殊函数:_dl_debug_state()
,加载器在加载共享库之前和之后以及设置全局变量之后调用它变量:_r_debug.r_state
到 RT_ADD
或 RT_CONSISTENT
.
调试器可以在该函数上设置断点,检查 .r_state
和 _r_debug.r_map
,并在此过程中发现在哪个地址加载了哪些 ELF 二进制文件。
这个机制被用来发现在哪里。 libc.so.6
在支持 PIE
二进制文件之前很久就已加载。 PIE
二进制文件只是共享库的一个特例,因此完全相同的机制也适用于它。
这引出了一个问题:GDB 如何发现 ld-linux
本身被加载的位置(因此可以设置 _dl_debug_state()
上的断点)。内核 通过辅助向量 AT_BASE
条目告诉 它。有关辅助向量的更多信息 here.