有人可以帮助我知道如何使用dlopen来处理libc内存分配函数?特别是,比如搜索libc路径然后获取句柄。应该使用哪些模式来调用dlsym?
想法是: 1)搜索libc路径 2)在上面调用dlopen 3)使用dlsym访问内存函数(malloc,calloc等)和 4)使用函数
请帮我解决上述4个步骤的代码段。
感谢advence。
答案 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()
。
可以在handle中指定两个特殊的伪句柄:
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
incorrectly 抱怨分配(gcc
在分配 void *
指针时会不正确地发出警告,但 C 标准规定 void *
指针可以安全地分配给任何指针...),