可以仅使用其内存映像提取已加载的共享库的导出符号吗?
我说的是 .dynsym 部分中列出的符号。据我了解,我们可以这样:
找到库的基地址。
例如,通过阅读/proc/<pid>/maps
,可以找到从磁盘库中映射的内存区域,然后我们可以查找ELF魔术字节来找到给我们基地址的ELF标题。
从程序标题中找到PT_DYNAMIC段。
解析ELF标题,然后遍历程序标题以查找包含 .dynamic <的段/ strong> section。
提取动态符号表的位置。
迭代ElfN_Dyn结构,找到带有d_tags DT_STRTAB和DT_SYMTAB的结构。这些将为我们提供字符串表(带符号名称)和动态符号表本身的地址。
这就是我跌跌撞撞的地方。 .dynamic 部分有一个字符串表(DT_STRSZ)大小的标记,但没有符号表大小的指示。它只包含单个条目的大小(DT_SYMENT)。如何检索表中的符号条目数?
应该可以从 .dynsym 部分的大小推断出,但是ELF文件在内存中表示为段。部分表不需要加载到内存中,只能通过读取相应的文件(可靠地)访问。
我认为这是可能的,因为动态链接器必须知道符号表的大小。但是,动态加载程序可能已在加载文件时将其存储在某处,并且链接器仅使用缓存值。虽然将符号表加载到内存中似乎有点愚蠢,但是不加载少量字节并且其大小旁边。
答案 0 :(得分:2)
动态符号表的大小必须从符号哈希表(DT_HASH
或DT_GNU_HASH
)中推断出来:this answer提供了一些代码来执行此操作。
标准哈希表(不再在GNU系统上使用)是quite simple。第一个条目是nchain
,即:
符号表条目的数量应该等于
nchain
GNU哈希表更复杂。