简体   繁体   English

ELF 格式导入符号的源共享库名称

[英]Names of source shared libraries for imported symbols in ELF format

i'm working on program that will analyze object files in ELF and PE formats (kind of school/research project).我正在开发一个程序,该程序将分析 ELF 和 PE 格式的 object 文件(一种学校/研究项目)。 Right now i'm about to process dynamic import symbols in executable files.现在我要处理可执行文件中的动态导入符号。 I would like to find as much info about symbol as possible.我想尽可能多地找到有关符号的信息。

In PE format, imports are stored in .idata section.在 PE 格式中,导入存储在.idata部分中。 There are several tables with different information but what is interesting for me is, that there is no problem to find out in which library is symbol defined.有几个表包含不同的信息,但对我来说有趣的是,找出在哪个库中定义了符号是没有问题的。 There is always name of shared library and then names/ordinals of symbols imported from it.总是有共享库的名称,然后是从中导入的符号的名称/序数。

I would like to find out this kind of information in ELF files as well.我也想在 ELF 文件中找到这类信息。 All imports/exports are in .dynsym section - dynamic symbol table.所有导入/导出都在.dynsym部分 - 动态符号表。 Those symbols which are imported are marked as undefined, for example:那些被导入的符号被标记为未定义,例如:

00000000      DF *UND*  00000000  GLIBC_2.0   fileno

But there are no information, what is source file of this symbol.但是没有信息,这个符号的源文件是什么。 All needed shared libraries are listed in .dynamic section, for example:所有需要的共享库都列在.dynamic部分,例如:

Dynamic Section:
  NEEDED               libz.so.1

Only information about library in symbol is Version String = GLIBC_2.0 .符号中有关库的唯一信息是 Version String = GLIBC_2.0 I was thinking about getting to real library name through this, but when i look at output of objdump -p i found out that GLIBC_2.0 can be connected with more than one library:我正在考虑通过这个获得真正的库名称,但是当我查看objdump -p的 output 时,我发现GLIBC_2.0可以与多个库连接:

Version References:
  required from libm.so.6:
    0x0d696910 0x00 13 GLIBC_2.0
  required from libgcc_s.so.1:
    0x0b792650 0x00 12 GLIBC_2.0

If i understand ELF dynamic linking process correctly, it should not be possible to find out this information in ELF executable file.如果我正确理解 ELF 动态链接过程,则应该无法在 ELF 可执行文件中找到此信息。 Where exactly is the symbol imported from is determined by linker after it loads all symbol tables to memory. linker 在将所有符号表加载到 memory 后,确定从哪里导入符号。 But i would like to be sure about this before i move on, so my question is: Is there any way how can I find out name of symbols shared library from ELF executable file?但我想在继续之前确定这一点,所以我的问题是:有什么方法可以从 ELF 可执行文件中找出符号共享库的名称?

Thank you for any advice.谢谢你的任何建议。

A few months ago I was working on pretty similar stuff - I was able to answer all my questions by grabbing the source to nm and readelf.几个月前,我正在研究非常相似的东西——我能够通过获取 nm 和 readelf 的源来回答我所有的问题。 ( See http://ftp.gnu.org/gnu/binutils/ ) I found this useful as well -> http://www.skyfree.org/linux/references/ELF_Format.pdf (见http://ftp.gnu.org/gnu/binutils/ )我发现这也很有用-> http://www.skyfree.org/linux/references/ELF_Format.Z437175BA41912190EE0904

Ok, so it is probably generaly impossible to assign library name to each imported symbol.好的,因此通常不可能为每个导入的符号分配库名称。 But i may have found the solution through Symbol Versioning.但我可能已经通过符号版本控制找到了解决方案。 Of course sybol version sections do not have to be present in each ELF file.当然,sybol 版本部分不必存在于每个 ELF 文件中。

struct elf_obj_tdata *pElf = bfdFile->tdata.elf_obj_data;
for (long i = 0; i < dynNumSyms; i++)
{
    asymbol *dynSym = dynSymTab[i];

    // If there is version information in file.
    if (pElf->dynversym_section != 0
        && (pElf->dynverdef_section != 0
        || pElf->dynverref_section != 0))
    {
        unsigned int vernum;
        const char *version_string;
        const char *fileName;

        vernum = ((elf_symbol_type *) dynSym)->version & VERSYM_VERSION;

        if (vernum == 0)   // local sym
            version_string = "";
        else if (vernum == 1)   // global sym, defined in this object
            version_string = "Base";
        else if (vernum <= pElf->cverdefs)
            version_string = pElf->verdef[vernum - 1].vd_nodename;
        else
    {
        Elf_Internal_Verneed *t;

        version_string = "";
        fileName = "";

        // Iterate through all Verneed entries - all libraries
        for (t = pElf->verref; t != NULL; t = t->vn_nextref)
        {
            Elf_Internal_Vernaux *a;

            // Iterate through all Vernaux entries
            for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
            {
                // Find associated entry
                if (a->vna_other == vernum)
                {
                    version_string = a->vna_nodename;
                    fileName = t->vn_filename;
                    break;
                }
            }
        }

        // here we have got:
        // name of symbol  = dynSym->name
        // version string  = version_string
        // name of library = fileName
    }
    }
}

So what do you think, is this correct?那么你怎么看,这是正确的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM