静态ELF替代dlsym

时间:2018-05-23 12:13:49

标签: elf dlsym

是否可以使用ELF查找函数的位置?类似于什么

void *f = dlopen(NULL,..);
void *func = dlsym(f, "myfunc");

可以,但在编译期间不需要-rdynamic吗?

我可以看到使用nm项目的命名仍然存在于已编译的二进制文件中?:

0000000000400716 T lookup
0000000000400759 T main

程序加载到内存后,是否可以使用此信息找到项目?

1 个答案:

答案 0 :(得分:1)

  

程序加载到内存后,是否可以使用此信息找到项目?

您确定可以:迭代.Skip()中的所有符号,直到找到匹配的符号。迭代符号的示例代码是here。或者使用libelf

如果您需要执行多个符号查找,请对所有符号迭代一次(慢),从符号名称到其地址构建映射,然后使用该映射执行查找。

<强>更新

  

你指出的例子似乎不完整?它使用数据和精灵,它们来自哪里?

是的,你需要在这个例子上涂抹一点肘部油脂。

a.out是内存中data a.outread或(更好)mmap的位置。

您可以自己mmap a.out,也可以通过以下方式找到现有的地图。 getauxval(AT_PHDR)向下舍入到页面大小。

ehdr(ElfW(Ehdr) *)data(即data阉割为Elf32_EhdrElf64_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可执行文件(可能就是您的系统)。

相关问题