寻求可获取ELF文件函数地址的命令/库函数(与addr2line功能相反)
获取ELF文件中函数地址的工具与方法
你需要的是从函数名反查ELF文件中的存储地址(和addr2line功能相反),下面整理几个实用的命令行工具和库函数方案:
一、命令行工具(快速获取)
这些工具能直接从静态ELF文件中提取函数地址,不需要写代码:
1. 优化你当前使用的readelf
你现在用的readelf完全可行,可以简化命令避免冗余:
readelf -s ./a.out | grep -w main
-w参数确保只匹配整词main,避免误匹配类似main_loop的符号。输出里的第二列就是函数的地址(比如你的例子里的000000000001967f)。如果只想单独输出地址,可以用awk提取:
readelf -s ./a.out | grep -w main | awk '{print $2}'
2. nm(最直接的符号查询工具)
nm是专门用来查看目标文件符号表的工具,用法更简洁:
# 查看静态符号表(静态编译或非PIE可执行文件) nm ./a.out | grep -w main # 输出示例:000000000001967f T main # 查看动态符号表(动态链接的ELF) nm -D ./a.out | grep -w main # 只输出地址,去掉其他信息 nm -j ./a.out | grep -w main
输出里的T表示该符号位于文本段(代码段),也就是函数所在的位置。
3. objdump
objdump也能解析符号表,适合需要更多上下文的场景:
objdump -t ./a.out | grep -w main # 提取地址 objdump -t ./a.out | grep -w main | awk '{print $1}'
二、库函数(编程实现)
如果需要在程序中自动获取函数地址,可以用以下库:
1. libelf(标准ELF解析库)
这是处理ELF文件的经典库,能直接读取静态ELF文件的符号表。大致步骤:
- 打开ELF文件并初始化
Elf对象 - 找到符号表节(
.symtab或.dynsym) - 遍历符号表,匹配目标函数名
- 读取符号的
st_value字段,就是函数的地址
2. dlsym(运行时获取已加载符号地址)
如果你的程序已经在运行,或者需要获取当前进程中加载的函数地址,可以用libdl库的dlsym:
#include <dlfcn.h> #include <stdio.h> int main() { void* main_addr = dlsym(RTLD_SELF, "main"); if (main_addr) { printf("main address: %p\n", main_addr); } return 0; }
编译时需要链接libdl:gcc -o get_addr get_addr.c -ldl。注意这个是获取运行时的地址,对于PIE(位置无关可执行文件),地址会是加载后的虚拟地址,和静态ELF中的偏移不同。
3. libbfd(GNU二进制文件描述库)
GNU的libbfd功能更强大,支持多种目标文件格式,也能解析ELF符号表获取函数地址,不过使用起来比libelf稍复杂。
内容的提问来源于stack exchange,提问作者Remy
相关产品推荐
相关产品推荐

