共享库搜索图案名称

时间:2012-03-06 09:53:26

标签: c++ linux shared-libraries

我用lt_dlopen打开了一个shread库,并希望搜索与特定模式匹配的导出符号列表(函数名称与模式匹配)。

有没有简单的方法可以做到这一点?要么按模式搜索,要么只获取所有导出命名的列表。简单来说,我的意思是没有一个特殊的库只是为了加载符号。

主程序和库是C ++,但所有符号都是extern "C"

1 个答案:

答案 0 :(得分:2)

您可以按照in this article概述的方法,如果您在我们自己的地址空间/通过dlopen()加载的库中访问符号更简单:

  1. 您通过reinterpret_cast<struct link_map*>(dlopen(...));获取的“struct link_map *” - 因此无需解析“您自己的ELF”。请参阅sourcecode for __dlopen()
  2. 您不需要使用ptrace()来读取您自己的地址空间 - 只需直接转换指针。
  3. 我将说明第二个找到符号表地址:

    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源代码这样做......),它只是不会让代码更容易阅读。我再次将其作为练习留给读者。