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

Import ELF格式导入符号的源共享库名称,import,symbols,elf,portable-executable,Import,Symbols,Elf,Portable Executable,我正在开发一个程序,该程序将分析ELF和PE格式的目标文件(类似于学校/研究项目)。现在我要处理可执行文件中的动态导入符号。我想找到尽可能多的有关符号的信息 在PE格式中,导入存储在.idata节中。有几个表具有不同的信息,但我感兴趣的是,找出在哪个库中定义了符号并没有问题。共享库总是有名称,然后是从中导入的符号的名称/序号 我也想在ELF文件中找到这类信息。所有导入/导出都位于.dynsym部分-动态符号表中。导入的符号标记为未定义,例如: 00000000 DF *UND* 00

我正在开发一个程序,该程序将分析ELF和PE格式的目标文件(类似于学校/研究项目)。现在我要处理可执行文件中的动态导入符号。我想找到尽可能多的有关符号的信息

在PE格式中,导入存储在
.idata
节中。有几个表具有不同的信息,但我感兴趣的是,找出在哪个库中定义了符号并没有问题。共享库总是有名称,然后是从中导入的符号的名称/序号

我也想在ELF文件中找到这类信息。所有导入/导出都位于
.dynsym
部分-动态符号表中。导入的符号标记为未定义,例如:

00000000      DF *UND*  00000000  GLIBC_2.0   fileno
Dynamic Section:
  NEEDED               libz.so.1
但没有信息,这个符号的源文件是什么。
.dynamic
部分列出了所有需要的共享库,例如:

00000000      DF *UND*  00000000  GLIBC_2.0   fileno
Dynamic Section:
  NEEDED               libz.so.1
符号中关于库的唯一信息是Version String=
GLIBC_2.0
。我本想通过这个来获得真正的库名,但当我查看
objdump-p
的输出时,我发现
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
若我正确理解ELF动态链接过程,那个么就不可能在ELF可执行文件中找到这些信息。从中导入的符号的确切位置由链接器在将所有符号表加载到内存后确定。 但在我继续之前,我想确定这一点,所以我的问题是:有什么方法可以从ELF可执行文件中找到符号共享库的名称


谢谢你的建议。

几个月前,我正在研究非常类似的东西——我能够通过将源代码抓取到nm和readelf来回答我的所有问题。(见附件)
我发现这也很有用->

好的,所以通常不可能为每个导入的符号指定库名称。但我可能已经通过符号版本控制找到了解决方案。当然,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
    }
    }
}
struct elf_obj_tdata*pElf=bfdFile->tdata.elf_obj_data;
对于(长i=0;idynversym_段)=0
&&(pElf->dynverdef_段!=0
||pElf->dynverref_段!=0)
{
无符号整数;
常量字符*版本字符串;
常量字符*文件名;
vernum=((elf_符号类型*)dynSym)->版本和VERSYM_版本;
if(vernum==0)//本地符号
version_string=“”;
else if(vernum==1)//全局符号,在此对象中定义
version_string=“Base”;
否则如果(vernum cverdefs)
version_string=pElf->verdef[vernum-1].vd_nodename;
其他的
{
Elf_Internal_Verneed*t;
version_string=“”;
fileName=“”;
//遍历所有Verneed条目-所有库
对于(t=pElf->verref;t!=NULL;t=t->vn_nextref)
{
Elf_Internal_Vernaux*a;
//遍历所有Vernax条目
对于(a=t->vn_auxptr;a!=NULL;a=a->vna_nextpttr)
{
//查找关联条目
如果(a->vna_other==vernum)
{
版本字符串=a->vna节点名称;
fileName=t->vn\u文件名;
打破
}
}
}
//我们有:
//符号名称=dynSym->name
//版本字符串=版本字符串
//库的名称=文件名
}
}
}

那么,你认为这是正确的吗?

我研究了objdump和少量BFD的来源。我确实读过ELF规范。基于此,我认为不可能将库名称分配给动态符号表中的符号,除非它实际上是动态链接的。但我不能说我对这一点绝对肯定,在我继续之前,我想和比我更有经验的人讨论一下。啊-好的。我想我不明白你原来的问题。为了澄清-您希望根据符号查找所使用的库文件,是吗?在Linux中,这是由程序加载器完成的——它将符号与库缓存相匹配。看到了吗?是的,我想知道是否有可能在不实际加载和搜索共享对象的情况下,将库的名称分配给每个导入的符号—定义它的库,并在动态链接期间仅基于可执行文件中的数据从中链接它—您最终得出结论了吗?如果是,是什么?我在问自己同样的问题。。。