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_PRELOAD
s(实际上也不管其他已经加载的库中的 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", ...)
.
如果应用程序 dlopen
s 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
(可以为此使用硬编码的绝对路径)。
我正在使用包装器库来跟踪使用 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_PRELOAD
s(实际上也不管其他已经加载的库中的 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", ...)
.
如果应用程序 dlopen
s 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
(可以为此使用硬编码的绝对路径)。