LD_PRELOAD 覆盖动态加载库中的函数

LD_PRELOAD to override functions from dynamically loaded library

我正在使用包装器库来跟踪使用 LD_PRELOAD 的函数,当我正在跟踪的函数在应用程序中被引用时,它确实有效。

包装器库使用 dlsym 填充它包装的符号。

但如果应用程序不直接引用函数而是通过 dlopen,则此方法无效。 包装器库是否应该与动态加载的库一起使用?如果不行,有什么办法让它起作用吗?

But this is not working if the application doesn't reference functions directly but through dlopen.

如果应用程序执行:

void *h = dlopen("libfoo.so", ...);
void *sym = dlsym(h, "symbol");

那么 symbol 将被解析为 libfoo.so,而不管任何 LD_PRELOADs(实际上也不管其他已经加载的库中的 symbol 的任何其他实例).这是按预期工作的。

Should the wrapper library work with dynamically loaded libraries?

没有

If not, is there a way to make it work?

是的,你可以让它发挥作用。您需要提供一个 replacement.so,它提供 所有 应用程序在 libfoo.so 中查找的符号,然后使其成为 replacement.so dlopend()ed 由应用程序。

一种方法是重命名 libfoo.so -> libfoo.so.orig,复制 replacement.so -> libfoo.so,并让 replacement.so 本身 dlopen("libfoo.so.orig", ...).

如果应用程序 dlopens libfoo.so 没有绝对路径,您可以安排 replacement.so 在搜索路径的前面,例如

mkdir /tmp/replacement
ln -s /path/to/replacement.so /tmp/replacement/liboo.so
LD_LIBRARY_PATH=/tmp/replacement /path/to/a.out

如果你走那条路,replacement.so 仍然需要知道如何 dlopen 原来的 libfoo.so(可以为此使用硬编码的绝对路径)。