【问题标题】:Using dlopen to get handle of libc memory allocation functions使用 dlopen 获取 libc 内存分配函数的句柄
【发布时间】:2011-10-14 01:18:14
【问题描述】:

有人可以帮助我了解如何使用 dlopen 来处理 libc 内存分配函数吗?尤其是搜索 libc 路径然后获取句柄之类的东西。调用 dlsym 应该使用什么模式?

想法是:

  1. 搜索 libc 路径
  2. 对其调用 dlopen
  3. 使用 dlsym 访问内存函数(malloc、calloc 等)和
  4. 使用函数

请帮我写出上述4个步骤的sn-p代码。

【问题讨论】:

    标签: c linux memory-management dlopen


    【解决方案1】:

    这是一个代码 sn-p, HTH

    #include <dlfcn.h>
    #include <stdio.h>
    int main()
    {  
       void *handle; 
    
       // dlopen will search the path for you
       // /usr/lib/libc.so is a linker script, not an elf file
       // so it won't work with dlopen. 
       handle = dlopen("libc.so.6", RTLD_LAZY); 
    
       if(handle){
             void* (*mallocptr)(size_t);
             void (*freeptr)(void*);
    
             // Locate symbols
             *(void**)(&mallocptr) = dlsym(handle, "malloc");
             *(void**)(&freeptr) = dlsym(handle, "free");
    
             if(!mallocptr || !freeptr){
                printf("%s\n", dlerror());
                return 1;
             }
    
             // Allocate and use memory
             char *ptr = (*mallocptr)(4);
             ptr[0] = 'H'; ptr[1] = 'i'; ptr[2] = '\n'; ptr[3] = '\0';
             printf(ptr);
    
             // Free it
             (*freeptr)(ptr);
       }
       else{
          printf("%s\n", dlerror());
          return 1;
       }
       return 0;
    }
    

    【讨论】:

    • -bash-3.2# ./a.out dlopen 失败
    • 请注意,我在代码中使用的是 libc.so.6 - 如果您使用的是不同版本的 libc,则必须更改它。查看您的 /lib 文件夹,是否有一个名为 libc.so.? 的文件
    • 我有 libc.so.6,我已经导出了它...不知道为什么 dlopen 仍然失败。
    • 我的意思是它在 LD_LIBRARY_PATH 中导出
    • RTM。无需调用dlopen() 并将结果句柄传递给dlsym()dlsym( RTLD_NEXT, "malloc" ); 将在“搜索顺序”中找到“下一次出现”malloc()
    【解决方案2】:

    这是一个老问题,但问题本身似乎基于一个错误的假设,即必须使用dlopen() 来定位系统标准libc 中的对象。

    没有必要使用dlopen(),除非您有意从不是默认libc 的特定共享对象加载您的函数。正如其他答案的 cmets 中所指出的那样,为可能只是默认的 libc 强制指定特定路径并不总是有效。因为默认的libc 几乎肯定已经加载到您的进程的地址空间中,并且它不必位于相同的位置,甚至不必具有相同的名称。

    例如,只需使用dlsym( RTLD_NEXT, "malloc" ) 来查找malloc()

    the Linux dlsym() man page:

    有两个特殊的伪句柄可以在句柄中指定:

    RTLD_DEFAULT

    使用 默认共享对象搜索顺序。搜索将 在可执行文件及其中包含全局符号 依赖关系,以及共享对象中的符号 使用 RTLD_GLOBAL 标志动态加载。

    RTLD_NEXT

    在 当前对象之后的搜索顺序。这允许一个人 在另一个共享的函数中提供一个包装器 对象,例如,定义一个函数 在预加载的共享对象中(参见 ld.so(8) 中的 LD_PRELOAD) 可以找到并调用提供的“真实”功能 另一个共享对象(或就此而言,“下一个” 在有的情况下定义函数 多层预加载)。

    必须定义_GNU_SOURCE 功能测试宏,以便 获取 RTLD_DEFAULTRTLD_NEXT 的定义 &lt;dlfcn.h&gt;.

    这就是所有必要的:

         void* (*mallocptr)(size_t);
         void (*freeptr)(void*);
    
         // Locate symbols
         mallocptr = dlsym(RTLD_NEXT, "malloc");
         freeptr = dlsym(RTLD_NEXT, "free");
    
         if(!mallocptr || !freeptr){
            printf("%s\n", dlerror());
            return 1;
         }
    
         // Allocate and use memory
         char *ptr = mallocptr(4);
         ptr[0] = 'H'; ptr[1] = 'i'; ptr[2] = '\n'; ptr[3] = '\0';
         printf(ptr);
    
         // Free it
         freeptr(ptr);
    

    请注意,我删除了 *(void**)(&amp;mallocptr) 演员表 - 不需要这些演员表。如果gcc 不正确 抱怨分配(gcc 将在分配 void * 指针时不正确地发出警告,但 C 标准指定 void * 指针可以安全地分配给任何指针.. .),

    【讨论】:

    • 这个可以用来查找共享对象中的局部符号吗?还是只会找到全局的?
    • @SRobertJames 也许——这取决于共享对象是如何构建和链接的,以及共享对象是否has been stripped。在 Linux 上,您可能会看到 nm -D libXXX.sonm -a libXXX.so 的输出存在显着差异。见stackoverflow.com/questions/435352/…
    猜你喜欢
    • 2013-05-18
    • 2014-01-04
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多