如何防止加载特定的动态库

时间:2017-12-02 18:47:29

标签: c linux shared-libraries ld dlopen

我想使用一个古老的软件(1999年的Unreal Tournament“Classic”,也称为UT99)。隐式加载动态库libtxc_dxtn.so,探测可选的S3纹理压缩(S3TC)支持。不幸的是,在加载库时,主应用程序崩溃并出现分段错误(崩溃也描述为here)。解决方法似乎是通过删除或移动libtxc_dxtn.so来删除Mesa的纹理压缩库。该应用程序运行完美,没有纹理压缩,但当然其他需要纹理压缩支持的应用程序现在已被打破。当然,我不想为一个特定的应用程序修改我的系统。

所以我的问题是:
我可以阻止(如“掩码”或“禁用”)特定动态库被特定应用程序加载吗?我希望找到与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]

1 个答案:

答案 0 :(得分:3)

有一个名为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覆盖,返回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);   
    }

}