我已经知道的:
ELF 可执行文件有许多部分,显然 .text 和 .data 部分被加载到内存中,因为它们是程序的主要部分。但要使程序正常运行,它需要更多信息,尤其是动态链接时。
我感兴趣的是 .plt、.got、.dynamic、.dynsym、.dynstr 等部分。 ELF 中负责将函数链接到地址的部分。
到目前为止我已经了解到,像 .symtab 和 .strtab 这样的东西不会被加载(或不会保留)在内存中。但是链接器使用 .dynsym 和 .dynstr 吗?他们还留在记忆中吗?我可以从程序代码访问它们吗?
可执行文件的任何部分是否驻留在内核内存中?
我对此的兴趣主要是法医学,但有关此主题的任何信息都会有所帮助。我读过的有关这些表和动态链接的资源更加高级,它们仅解释了工作原理,而不是有关内存中内容的任何实用内容。
如果我的问题还有任何不清楚的地方请告诉我。
答案1
以下是一个非常好的参考:http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/。它包含不同级别的各种不同参考文献末尾的参考书目。如果您想了解每一个血淋淋的细节,您可以直接访问源代码:http://www.akkadia.org/drepper/dsohowto.pdf。 (Ulrich Drepper 编写了 Linux 动态链接器。)
通过运行“objdump -h myexe”或“readelf -S myexe”等命令,您可以很好地了解可执行文件中的所有部分。
.interp 部分包含动态加载器的名称,该加载器将用于动态链接该对象中的符号。 .dynamic 部分是程序头的精炼,其格式被设置为易于动态加载程序读取。 (所以它有指向所有其他部分的指针。)
.got(全局偏移表)和.plt(过程链接表)是动态链接器操作的两个主要结构。 .got 是变量的间接表,.plt 是函数的间接表。每个可执行文件或库(称为“共享对象”)都有自己的 .got 和 .plt,这些是该共享对象引用的符号表,这些符号实际上包含在其他共享对象中。
.dynsyn 包含有关共享对象中符号的所有信息(包括您定义的符号和需要引用的外部符号)。.dynsyn 不包含实际的符号名称。这些包含在 .dynstr 中,并且 .dynsyn 具有指向 .dynstr 的指针。 .gnu.hash 是一个哈希表,用于按名称快速查找符号。它还仅包含指针(指向 .dynstr 的指针,以及用于创建存储桶链的指针。)
当您的共享对象取消引用某个符号“foo”时,动态链接器必须在您链接的所有动态对象中查找“foo”,以找出哪个包含您正在查找的“foo”(然后是相对的) “foo”的地址在该共享对象内部。)动态链接器通过搜索所有链接的共享对象的 .gnu.hash 部分(或没有 .gnu 的旧共享对象的 .hash 部分)来实现此目的。一旦它在链接的共享对象中找到正确的地址,它就会将其放入共享对象的 .got 或 .plt 中。
答案2
如果您运行readelf -e
该文件,您将看到LOAD
在 下以类型形式列出的各种段Program Headers
。这些是加载到内存中的 ELF 文件的部分。
各个部分(例如,.text
、.got.plt
、.dynsym
)均位于一个段内。输出readelf -e
包含一个Section to Segment mapping
部分,该部分将各部分与其段相匹配。使用该信息,您可以确定加载了哪些部分。