ELF的代理共享库(sharedlib、shlib、so)?

问题描述 投票:8回答:2

在Windows上,创建 "代理DLL "是很常见的,它可以代替原来的DLL,并转发对它的调用(在进行任何必要的附加操作后)。你可以阅读一下 此处此处 比如说。

然而,Linux下的shlib munging文化却完全不同。首先,LD_PRELOAD是Linux下ld.so的内置功能,它只是简单地将单独的shlib注入到进程中,并使用它定义的任何符号作为覆盖。而这种 "注入 "技术似乎定义了整个思路的方向--这里是 典型的ELF黑客工具这个问题这位先生似乎和我有相同的使用情况,但他一开始就问如何能给现有的二进制文件打补丁。

不,谢谢。我不想注入或修改一些不属于我的东西,我只想做一个独立的代理shlib。我想做的只是做一个独立的代理shlib,它可以调用原始的。理想的情况是,有一个工具可以与原版的.so一起使用,并创建一个C源码,它可以重定向到原版的函数,同时让我轻松地覆盖任何我想要的东西。那么,这样的工具在哪里呢? ;-) 谢谢。

c dll proxy shared-libraries elf
2个回答
1
投票

使用 "代理DLL "的方法 LD_PRELOAD 并不真正涉及到修改一些不属于你的东西,而且注入的东西和普通的动态库加载并没有什么不同。ERESI项目中的 "典型的ELF黑客工具 "与以下内容无关 LD_PRELOAD. 你不应该害怕它。一个好的写作入门 LD_PRELOAD-可 "代理 "是 此处.

这就是说,如果你想为某个库创建一个全系统的代理,你可能会认为,全局设置 LD_PRELOAD (从而将您的代理加载到系统上运行的每个二进制文件中)是不可取的。它通常用于覆盖glibc中的函数,如 libeatmydata袜业但如果你要覆盖一个比glibc更大或更不广泛的库中的函数,那么尝试找到另一种方法是有意义的,真正为那个库创建一个代理。

其中一种方法是使用 patchelf --replace-needed--add-needed 来硬编码原始库的完整路径名,然后通过设置 LD_LIBRARY_PATH¹. 所以,完整的程序是

  1. 创建一个 LD_PRELOAD-可覆盖原有库的一些功能的库(测试它是否只用了 LD_PRELOAD 在继续进行之前!)
  2. 编译并将这个库与原库链接起来,这样就可以使 ldd libwrapper-foo.so 包括这样的内容。libfoo.so.0 => /usr/lib/x86_64-linux-gnu/libfoo.so.0 (0x0000deadbeef0000)
  3. 硬编码完整的路径,使用 patchelf: patchelf --replace-needed libfoo.so.0 /usr/lib/x86_64-linux-gnu/libfoo.so.0 libwrapper-foo.so
  4. 符号链接 libwrapper-foo.solibfoo.so.0
  5. 现在 LD_LIBRARY_PATH=. ldd $(which program-that-uses-libfoo) 应包括这些行。libfoo.so.0 => ./libfoo.so.0 (0x0000dead56780000) /usr/lib/x86_64-linux-gnu/libfoo.so.0 (0x0000dead1234000000)
  6. 设置 LD_LIBRARY_PATH 的完整路径。.bashrc 或其他地方

这种代理库的一个实际例子是 我的libpango包装器 可以实现所有应用的子像素定位。


¹)也可以将这个代理库放入到 /usr/local/libldconfig (更新共享库缓存的工具)拒绝使用硬编码绝对路径的库。


0
投票

拒绝使用带有硬编码绝对路径的库。 是一个工具,它涵盖了一些平台的图形类库(OpenGL、DirectX)调用的详细跟踪。它可能过于详细和复杂,不适合通用解决方案,但至少提供了一些参考和亲和力。

© www.soinside.com 2019 - 2024. All rights reserved.