【发布时间】:2011-10-14 01:18:14
【问题描述】:
有人可以帮助我了解如何使用 dlopen 来处理 libc 内存分配函数吗?尤其是搜索 libc 路径然后获取句柄之类的东西。调用 dlsym 应该使用什么模式?
想法是:
- 搜索 libc 路径
- 对其调用 dlopen
- 使用 dlsym 访问内存函数(malloc、calloc 等)和
- 使用函数
请帮我写出上述4个步骤的sn-p代码。
【问题讨论】:
标签: c linux memory-management dlopen
有人可以帮助我了解如何使用 dlopen 来处理 libc 内存分配函数吗?尤其是搜索 libc 路径然后获取句柄之类的东西。调用 dlsym 应该使用什么模式?
想法是:
请帮我写出上述4个步骤的sn-p代码。
【问题讨论】:
标签: c linux memory-management dlopen
这是一个代码 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;
}
【讨论】:
dlopen() 并将结果句柄传递给dlsym()。 dlsym( RTLD_NEXT, "malloc" ); 将在“搜索顺序”中找到“下一次出现”malloc()。
这是一个老问题,但问题本身似乎基于一个错误的假设,即必须使用dlopen() 来定位系统标准libc 中的对象。
没有必要使用dlopen(),除非您有意从不是默认libc 的特定共享对象加载您的函数。正如其他答案的 cmets 中所指出的那样,为可能只是默认的 libc 强制指定特定路径并不总是有效。因为默认的libc 几乎肯定已经加载到您的进程的地址空间中,并且它不必位于相同的位置,甚至不必具有相同的名称。
例如,只需使用dlsym( RTLD_NEXT, "malloc" ) 来查找malloc()。
有两个特殊的伪句柄可以在句柄中指定:
RTLD_DEFAULT
使用 默认共享对象搜索顺序。搜索将 在可执行文件及其中包含全局符号 依赖关系,以及共享对象中的符号 使用 RTLD_GLOBAL 标志动态加载。
RTLD_NEXT
在 当前对象之后的搜索顺序。这允许一个人 在另一个共享的函数中提供一个包装器 对象,例如,定义一个函数 在预加载的共享对象中(参见 ld.so(8) 中的 LD_PRELOAD) 可以找到并调用提供的“真实”功能 另一个共享对象(或就此而言,“下一个” 在有的情况下定义函数 多层预加载)。
必须定义
_GNU_SOURCE功能测试宏,以便 获取RTLD_DEFAULT和RTLD_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 * 指针可以安全地分配给任何指针.. .),
【讨论】:
nm -D libXXX.so 和 nm -a libXXX.so 的输出存在显着差异。见stackoverflow.com/questions/435352/…