如何防止加载特定的动态库
How to prevent specific dynamic library from being loaded
我想用一个古老的软件(1999 年的 Unreal Tournament "Classic",也称为 UT99)。动态库 libtxc_dxtn.so
被隐式加载,探测可选的 S3 纹理压缩 (S3TC) 支持。不幸的是,在加载库时,主应用程序因分段错误而崩溃(崩溃也描述为 here)。解决方法似乎是通过删除或移动 libtxc_dxtn.so
来移除 Mesa 的纹理压缩库。该应用程序在没有纹理压缩的情况下运行得非常好,但当然其他需要纹理压缩支持的应用程序现在已损坏。当然,我不想为某一特定应用修改我的系统。
所以我的问题是:
我可以阻止(如 "mask" 或 "disable")特定动态库被特定应用程序加载吗?我希望找到与LD_PRELOAD
相反的东西。
更新:libtxc_dxtn.so
被隐式加载, 间接 加载。修改应用程序二进制文件是不可行的。
initialize program: ut-bin
file=libSDL-1.1.so.0 [0]; needed by ut-bin [0]
file=libGL.so.1 [0]; dynamically loaded by libSDL-1.1.so.0 [0]
file=i965_dri.so [0]; dynamically loaded by libGL.so.1 [0]
file=libtxc_dxtn.so [0]; dynamically loaded by i965_dri.so [0]
有一个名为 patchelf 的实用程序,它应该允许您从可执行文件中删除 DSO 依赖项。
这是一个从虚拟可执行文件中删除 libpthread
依赖项的示例:
echo 'int main(){}' |
gcc -x c - -Wl,--no-as-needed -lpthread &&
ldd a.out &&
patchelf --remove-needed libpthread.so.0 a.out &&
echo ====== &&
ldd a.out
我的输出:
linux-vdso.so.1 => (0x00007ffeced67000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f21560f1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2155d28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f215630f000)
======
linux-vdso.so.1 => (0x00007fffac536000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6235c0d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6235fd6000)
更新:
如果 libtxc_dxtn.so
使用 dlopen
加载,您可以预加载 (LD_PRELOAD
) 一个迷你库,它提供 dlopen
覆盖,return NULL
如果
它的文件名参数是例如 "libtxc_dxtn.so"
(ltrace
应该可以帮助您找到您需要防范的实际文件名参数)。类似于:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
void *dlopen(char const *Fnm, int Flg)
{
void *(*real_dlopen)(char const *, int);
*(void**)(&real_dlopen) = dlsym(RTLD_NEXT, "dlopen");
if(0==strcmp("libtxc_dxtn.so", Fnm)){
return NULL;
}else{
return real_dlopen(Fnm, Flg);
}
}
我想用一个古老的软件(1999 年的 Unreal Tournament "Classic",也称为 UT99)。动态库 libtxc_dxtn.so
被隐式加载,探测可选的 S3 纹理压缩 (S3TC) 支持。不幸的是,在加载库时,主应用程序因分段错误而崩溃(崩溃也描述为 here)。解决方法似乎是通过删除或移动 libtxc_dxtn.so
来移除 Mesa 的纹理压缩库。该应用程序在没有纹理压缩的情况下运行得非常好,但当然其他需要纹理压缩支持的应用程序现在已损坏。当然,我不想为某一特定应用修改我的系统。
所以我的问题是:
我可以阻止(如 "mask" 或 "disable")特定动态库被特定应用程序加载吗?我希望找到与LD_PRELOAD
相反的东西。
更新:libtxc_dxtn.so
被隐式加载, 间接 加载。修改应用程序二进制文件是不可行的。
initialize program: ut-bin
file=libSDL-1.1.so.0 [0]; needed by ut-bin [0]
file=libGL.so.1 [0]; dynamically loaded by libSDL-1.1.so.0 [0]
file=i965_dri.so [0]; dynamically loaded by libGL.so.1 [0]
file=libtxc_dxtn.so [0]; dynamically loaded by i965_dri.so [0]
有一个名为 patchelf 的实用程序,它应该允许您从可执行文件中删除 DSO 依赖项。
这是一个从虚拟可执行文件中删除 libpthread
依赖项的示例:
echo 'int main(){}' |
gcc -x c - -Wl,--no-as-needed -lpthread &&
ldd a.out &&
patchelf --remove-needed libpthread.so.0 a.out &&
echo ====== &&
ldd a.out
我的输出:
linux-vdso.so.1 => (0x00007ffeced67000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f21560f1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2155d28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f215630f000)
======
linux-vdso.so.1 => (0x00007fffac536000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6235c0d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6235fd6000)
更新:
如果 libtxc_dxtn.so
使用 dlopen
加载,您可以预加载 (LD_PRELOAD
) 一个迷你库,它提供 dlopen
覆盖,return NULL
如果
它的文件名参数是例如 "libtxc_dxtn.so"
(ltrace
应该可以帮助您找到您需要防范的实际文件名参数)。类似于:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
void *dlopen(char const *Fnm, int Flg)
{
void *(*real_dlopen)(char const *, int);
*(void**)(&real_dlopen) = dlsym(RTLD_NEXT, "dlopen");
if(0==strcmp("libtxc_dxtn.so", Fnm)){
return NULL;
}else{
return real_dlopen(Fnm, Flg);
}
}