动态加载Linux共享库?

问题描述:

我想创建可在两种不同的方式加载到目标共享库:动态加载Linux共享库?

  1. LD_PRELOAD通过dlsym

我的共享库

  • 动态加载看起来是这样的:

    #include "stdio.h" 
    
    void __attribute__ ((constructor)) my_load(void); 
    
    void my_load(void) { 
        printf("asdf"); 
    } 
    
    void someFunc(void) { 
        printf("someFunc called"); 
    } 
    

    我正在像这样编译它:

    all: 
        gcc -fPIC -g -c -Wall MyLib.c 
        gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 
    

    我不希望与ldconfig安装等目标的过程是这样的:

    #include <stdio.h> 
    #include <dlfcn.h> 
    
    void func1() { 
        printf("%d\n", 1); 
    } 
    
    void func2() { 
        printf("%d\n", 2); 
    } 
    
    void func3() { 
        printf("%d\n", 3); 
    } 
    
    int main() { 
        void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1", 
             RTLD_NOW|RTLD_GLOBAL); 
    
        if(lib_handle == NULL) { 
        printf("Failed loading lib\n"); 
        } else { 
        printf("Loaded lib successfully\n"); 
    
        void (*some_func)() = dlsym(lib_handle, "someFunc"); 
        printf("%p\n", some_func); 
    
        dlclose(lib_handle); 
        } 
    
        func1(); 
        func2(); 
        func3(); 
    
        return 0; 
    } 
    

    目标被编译为这样:

    all: 
        gcc TestProg.c -ldl -o TestProg 
    

    我的问题是:

    1. 如上所述动态加载dlopen为什么my_load似乎不被称为?
    2. 使用相同的方法,即使dlopen返回非空,为什么dlsym始终返回nil?同样,nm不会列出my_loadsomeFunc作为.so的符号。
    3. 是否可以使用LD_PRELOAD加载库?我试图将.so复制到与目标相同的目录中,然后调用LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg,但似乎还没有调用my_load
  • 你的目标文件没有被链接到你的库:

    gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 
    

    更改它包含目标文件MyLib.o:

    gcc MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 
    

    更新:只是tryed本地的命令(不任何MyLib.c或MyLib.o):

    $ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok 
    ok 
    $ nm MyLib.so.1.0.1 
    xxxxxxxx a _DYNAMIC 
    xxxxxxxx a _GLOBAL_OFFSET_TABLE_ 
         w _Jv_RegisterClasses 
    xxxxxxxx A __bss_start 
         w [email protected]@xxxxxxxxxxx 
    xxxxxxxx d __dso_handle 
         w __gmon_start__ 
    xxxxxxxx t __i686.get_pc_thunk.bx 
    xxxxxxxx A _edata 
    xxxxxxxx A _end 
    xxxxxxxx T _fini 
    xxxxxxxx T _init 
    

    它是一个空的动态库。

    +0

    完美地工作。它按照LR_PRELOAD以及动态的方式加载。在这两种情况下也调用my_load。谢谢! –

    +1

    其实它不是空的,它包含一些libc的东西。如果你没有指定'-lc',链接将失败。 :) – ninjalj