gpt4 book ai didi

c - 动态链接器如何更改进程的文本段?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:24:20 24 4
gpt4 key购买 nike

如果我在用户尝试执行动态链接时理解正确可执行文件(使用 execve("foo", "", ""))而不是加载“foo”动态链接器的文本段(ld-linux.so.2)并执行。它必须加载程序(“foo”)运行和更改某些地址所需的库在“foo”中并将控制权传递给 foo,但这是如何完成的呢?

如何(它使用什么系统调用)和在哪里动态加载器加载库和内存中的“foo”代码和数据(我猜它不能简单地使用 malloc 或 mmap,然后跳转到代码,因为那应该是不可能的, 正确的?它似乎也不太可能创建完整的临时文件 可执行文件(如静态链接的)并再次调用 exceve。)。

最佳答案

实际实现相当复杂,因为它建立在 ELF 之上,ELF 非常复杂,因为它试图适应许多场景,但从概念上讲它非常简单。

基本上(在找到库依赖项并打开后)它是一对mmapmprotect,一些修改来实现通过绑定(bind)符号的链接(可以延迟),然后跳转到代码。

理想情况下,链接的共享库将使用 -fpic/-fPIC 进行编译,这将允许链接器将它们放置在进程地址空间中的任何位置,而无需编写到库的 .text 部分(= 可执行代码)。这样的库/可执行文件将通过可修改表调用其他库中的函数,链接器将修复(可能是懒惰地)以指向它加载依赖库的实际位置。从一个共享库到另一个共享库的变量访问同样是间接的。

尽可能限制修改库数据/代码允许将代码部分标记为只读(通过 MMU/mprotect 系统调用)并映射到所有进程共享的内存中使用该特定库的。


要了解在系统调用级别发生了什么,您可以尝试例如:

strace /bin/echo hello world

所有系统调用,直到 sbrk 包括在内(=设置堆/.data 段)应该是动态链接器的工作。


(malloc 确实对链接器不可用,因为 malloc 是 c 库的一个特性,而不是系统。malloc 是关于增长的并管理堆部分并可能 mmapping 其他单独的 block 并管理它们以及可写的“堆”,动态链接器不关心进程镜像的这些部分,主要只是它的可写的间接表及其映射库的位置)。

关于c - 动态链接器如何更改进程的文本段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37839865/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com