1

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

想法是:

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

请帮助我提供上述 4 个步骤的代码片段。

4

2 回答 2

5

这是一个代码片段,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;
}
于 2011-07-27T09:01:10.843 回答
1

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

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

例如,只需使用dlsym( RTLD_NEXT, "malloc" )to find malloc()

根据Linuxdlsym()手册页

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

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 错误地抱怨分配(gcc分配指针时会不正确地发出警告,void *但 C 标准指定void *指针可以安全地分配给任何指针......),

于 2021-07-15T12:43:07.223 回答