是否可以使用ELF查找函数的位置?类似于什么
void *f = dlopen(NULL,..);
void *func = dlsym(f, "myfunc");
可以,但在编译期间不需要-rdynamic
吗?
我可以看到使用nm
项目的命名仍然存在于已编译的二进制文件中?:
0000000000400716 T lookup
0000000000400759 T main
程序加载到内存后,是否可以使用此信息找到项目?
答案 0 :(得分:1)
程序加载到内存后,是否可以使用此信息找到项目?
您确定可以:迭代.Skip()
中的所有符号,直到找到匹配的符号。迭代符号的示例代码是here。或者使用libelf。
如果您需要执行多个符号查找,请对所有符号迭代一次(慢),从符号名称到其地址构建映射,然后使用该映射执行查找。
<强>更新强>
你指出的例子似乎不完整?它使用数据和精灵,它们来自哪里?
是的,你需要在这个例子上涂抹一点肘部油脂。
a.out
是内存中data
a.out
为read
或(更好)mmap
的位置。
您可以自己mmap
a.out
,也可以通过以下方式找到现有的地图。 getauxval(AT_PHDR)
向下舍入到页面大小。
ehdr
为(ElfW(Ehdr) *)data
(即data
阉割为Elf32_Ehdr
或Elf64_Ehdr
。
如果不清楚,那么您可能只需使用libelf
,它会为您处理细节。
另外,ELF是否只允许我找到符号的名称,还是它实际上可以给我指向符号内存位置的指针?
它可以同时为您提供:str + sym[i].st_name
是名称,sym[i].st_value
是指针(由nm
显示的值)。
(大概是0000000000400716是一些相对的基地址,而不是实际的内存位置,对吗?)
不,实际上(对于这个二进制文件)它是绝对地址。
与位置无关的二进制文件确实使用相对地址(因此您需要类似getauxval
之类的内容来查找此类可执行文件的基本位置),但此特定二进制文件看起来像ET_EXEC
(使用readelf -h a.out
来验证这一点。地址0x400000
是典型地址,用于在Linux x86_64上加载非PIE可执行文件(可能就是您的系统)。