使用dlopen来获取libc内存分配函数的句柄

时间:2011-07-27 08:14:06

标签: c linux memory-management dlopen

有人可以帮助我知道如何使用dlopen来处理libc内存分配函数?特别是,比如搜索libc路径然后获取句柄。应该使用哪些模式来调用dlsym?

想法是: 1)搜索libc路径 2)在上面调用dlopen 3)使用dlsym访问内存函数(malloc,calloc等)和 4)使用函数

请帮我解决上述4个步骤的代码段。

感谢advence。

2 个答案:

答案 0 :(得分:4)

这是一段代码片段,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;
}

答案 1 :(得分:0)

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

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

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

每个the Linux dlsym() man page

<块引用>

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

RTLD_DEFAULT

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

RTLD_NEXT

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

必须定义 _GNU_SOURCE 功能测试宏,以便 获取 RTLD_DEFAULTRTLD_NEXT 的定义 <dlfcn.h>.

这是所有必要的:

     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**)(&mallocptr) 强制转换 - 这些不是必需的。如果 gcc incorrectly 抱怨分配(gcc 在分配 void * 指针时会不正确地发出警告,但 C 标准规定 void * 指针可以安全地分配给任何指针...),