linker - 在运行时有条件地修改重定位
问题描述
TL;博士
我想覆盖 .got, .got.plt,...
以指向正确的地址,因为链接器做出错误的决定。
我需要在代码中使用两个不同的动态分配函数(即malloc(),...
)。在程序执行过程中,将根据某些条件选择合适的。因此,我提供了两个glibc
实例并使用了这个LD_PRELOAD
技巧。该LD_PRELOAD
值类似于以下内容:
LD_PRELOAD=multiplexer_library.so:glibc1.so:glibc2.so
其中,multiplexer_library.so
选择正确的库。glibc1.so
使用 访问dlsym(RTLD_NEXT, "malloc")
并且glibc2.so
使用dlopen()
后跟访问dlsym()
。这同样适用于calloc(),...
问题是第二个 malloc 会干扰第一个。发生这种情况是因为后者的所有动态重定位都将由链接器映射到前者。例如,当调用全局函数指针时,它将被映射到及其目标,即. 这个全局变量的重定位入口如下:glibc2.so
morecore
morecore
__default_morecore()
glibc1.so
glibc2.so
0000003addc0 085600000006 R_X86_64_GLOB_DAT 00000000003af4d8 __morecore@@GLIBC_2.2.5 + 0
我在Pin
. 在动态分配期间,在我的代码中访问了1370多个重定位条目中的125个。例如,一个重要的条目是确定动态分配边界的全局变量(请注意,我在系统调用级别为每个库提供了一个隔离的brk 区域)。这显然会破坏分配,因为两个分配器使用相同的. in的重定位条目如下所示:__curbrk
brk
__curbrk
__curbrk
glibc1.so
0000003adeb8 044400000006 R_X86_64_GLOB_DAT 00000000003b10b8 __curbrk@@GLIBC_2.2.5 + 0
我试图重命名这些冲突的名称,但125是一个巨大的数字,而且代码很难掌握。因为它充满了嵌套的宏,这使得手动重命名解决方案实际上是不可行的。
IIUC,对于每个重定位条目,都存在一个内存地址(例如,在 中的某处.got,...
),链接器将在其中放置目标重定位地址,并且该地址是每个共享库独有的。我将该地址称为目标持有人。例如,在这种情况下,链接器将变量的运行时地址放置在和的目标持有者中。如果这是正确的,在运行时,我将不得不更新__curbrk
__curbrk
glibc1.so
__curbrk
glibc1.so
glibc2.so
__curbrk
in的目标持有者glibc2.so
保存变量的运行时地址。为了彻底解决问题,应该对. _ _ 可能吗?__curbrk
glibc2.so
malloc(),...
任何帮助表示赞赏!
解决方案
推荐阅读
- sql - SQL Server - 范围号
- java - Keycloak 访问令牌
- python - 在 Pycharm 中的 for 循环中调试列表理解
- html - 如何根据需求将焦点设置在特定的 html 元素上(角度)
- php - 如何将事件插件添加到我的自定义主题?
- node.js - 写入文件并同时读取它以在 nodejs 中创建竞争条件
- python - 如果在成功连接到集群后所有提及的联系点都关闭了怎么办?
- javascript - 如何使用java脚本window.location将参数传递给play框架中的java方法?
- python - 如何使用 xlwings 通过 Python 在 Excel 上编辑 ActiveX TextBox 的文本?
- java - 关闭 http 输入流