在运行时定位ELF共享库导出

在运行时定位ELF共享库导出

问题描述:

仅使用其内存映像可以提取已加载共享库的导出符号?在运行时定位ELF共享库导出

我在说的是.dynsym部分列出的符号。据我所知,我们可以这样:

  1. 找到库的基地址。
    例如,通过读取/proc/<pid>/maps,可以找到从磁盘库中映射的内存区域,然后我们可以查找ELF魔术字节以找到ELF标头,从而为我们提供基地址。

  2. 从程序头中找到PT_DYNAMIC段。
    解析ELF标题,然后遍历程序标题以找到包含.dynamic部分的段。

  3. 提取动态符号表的位置。
    对ElfN_Dyn进行迭代结构可以找到带有DT_TAB和DT_SYMTAB的d_tags。这些将为我们提供字符串表(带有符号名称)和动态符号表本身的地址。

这就是我偶然发现的地方。 .dynamic部分有一个标记为字符串表(DT_STRSZ)的大小,但没有指示符号表大小。它只包含单个条目的大小(DT_SYMENT)。我如何检索表格中符号条目的数量?

应该可以推断,从.dynsym节的大小,但ELF文件在内存中表示为段。节表不需要加载到内存中,只能通过读取相应的文件(可靠地)访问。

我相信这是可能的,因为动态链接器必须知道符号表的大小。但是,动态加载器可能已经将其存储在文件被加载的地方,并且链接器仅使用缓存的值。虽然将符号表加载到内存中看起来有点愚蠢,但不会加载少数几个字节的大小。

动态符号表的大小必须从符号散列表(DT_HASHDT_GNU_HASH)推出:this answer给出了一些代码。

标准哈希表(不再用于GNU系统)是quite simple。的第一个条目是nchain它是:

符号表中的条目的数量应该等于nchain

的GNU哈希表是更加复杂。