有人可以帮我知道如何使用 dlopen 来处理 libc 内存分配函数吗?尤其是像搜索 libc 路径然后获取句柄之类的东西。应该使用哪些模式来调用 dlsym?
想法是:
- 搜索 libc 路径
- 在它上面调用 dlopen
- 使用 dlsym 访问内存函数(malloc、calloc 等)和
- 使用函数
请帮助我提供上述 4 个步骤的代码片段。
有人可以帮我知道如何使用 dlopen 来处理 libc 内存分配函数吗?尤其是像搜索 libc 路径然后获取句柄之类的东西。应该使用哪些模式来调用 dlsym?
想法是:
请帮助我提供上述 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;
}
这是一个老问题,但问题本身似乎是基于一个错误的假设,该假设dlopen()
必须用于在系统标准中定位对象libc
。
dlopen()
除非您故意从不是默认的特定共享对象加载函数,否则无需使用libc
。正如对另一个答案的评论中所指出的那样,为可能只是默认值的路径强制使用特定路径libc
并不总是有效。因为libc
几乎可以肯定默认值已经加载到您的进程的地址空间中,并且它不必位于同一位置,甚至不必具有相同的名称。
例如,只需使用dlsym( RTLD_NEXT, "malloc" )
to find 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 *
指针可以安全地分配给任何指针......),