我用lt_dlopen
打开了一个shread库,并希望搜索与特定模式匹配的导出符号列表(函数名称与模式匹配)。
有没有简单的方法可以做到这一点?要么按模式搜索,要么只获取所有导出命名的列表。简单来说,我的意思是没有一个特殊的库只是为了加载符号。
主程序和库是C ++,但所有符号都是extern "C"
。
答案 0 :(得分:2)
您可以按照in this article概述的方法,如果您在我们自己的地址空间/通过dlopen()
加载的库中访问符号更简单:
reinterpret_cast<struct link_map*>(dlopen(...));
获取的“struct link_map *” - 因此无需解析“您自己的ELF”。请参阅sourcecode for __dlopen()
。ptrace()
来读取您自己的地址空间 - 只需直接转换指针。我将说明第二个找到符号表地址:
struct link_map *map = reinterpret_cast<struct link_map*>(dlopen(...));
int nchains = 0;
Elf32_Dyn *dyn = static_cast<Elf32_Dyn*>(map->l_ld);
Elf32_Sym *symtab = NULL;
char *strtab = NULL;
while (dyn->d_tag) {
switch (dyn->d_tag) {
case DT_HASH:
nchains = *static_cast<int*>(dyn->d_un.d_ptr + map->l_addr + 4);
break;
case DT_SYM:
symtab = static_cast<Elf32_Sym*>(dyn->d_un.d_ptr);
break;
case DT_STR:
strtab = static_cast<char*>(dyn->d_un.d_ptr);
break;
default:
break;
}
dyn++;
}
这是我链接到的文章中resolv_tables()
函数的内存等效内容。通过您自己的地址空间将find_sym_in_tables()
转换为模式搜索是留给读者的练习。
请注意,这是特定于Linux的(dlopen()
返回struct link_map*
)。对于其他系统,只要满足此条件(并且它们使用ELF),该技术就应该有效。
编辑:这是针对32位ELF的;如果您使用的是64位数据类型,我认为数据类型会更改(Elf64_Sym
/ Elf64_Dyn
和64位整数。我确信这可以抽象化(glibc源代码这样做......),它只是不会让代码更容易阅读。我再次将其作为练习留给读者。