dlsym 的静态 ELF 替代品

Static ELF alternative to dlsym

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

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

有,但在编译期间不需要 -rdynamic

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

0000000000400716 T lookup
0000000000400759 T main

程序加载到内存后,我可以使用此信息定位项目吗?

Can I use this information to locate the items once the program is loaded into memory?

您当然可以:遍历 a.out 中的所有符号,直到找到匹配的符号。迭代符号的示例代码是 . Or use libelf.

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

更新:

The example you point to seems incomplete? It uses data and elf, where are they coming from?

是的,您需要为该示例添加一点苦力。

dataa.out 在内存中的位置,read 或(更好)mmaped.

您可以自己 mmap a.out,或者通过例如查找现有映射getauxval(AT_PHDR) 四舍五入为页面大小。

ehdr(ElfW(Ehdr) *)data(即,data 视情况转换为 Elf32_EhdrElf64_Ehdr

如果不清楚,那么您可能应该只使用 libelf,它会为您处理细节。

Also, does ELF only allow me to find the name of the symbol, or can it actually give me the pointer to the in memory location of the symbol?

可以给你两个:str + sym[i].st_name是名字,sym[i].st_value是指针(nm显示的值)。

(presumably the e.g. 0000000000400716 is some relative base address, not the actual in memory location, right?)

不,实际上(对于这个二进制文件)它是绝对地址。

位置无关的二进制文件确实使用相对地址(所以你需要像上面提到的 getauxval 这样的东西来找到这样的可执行文件的基本位置),但是这个特定的二进制文件看起来像 ET_EXEC (使用 readelf -h a.out 来验证这一点)。地址 0x400000典型的 地址,用于在 Linux x86_64 上加载非 PIE 可执行文件(这可能是您的系统)。