仅从ELF二进制文件中提取我的函数名称

Jey*_*ram 4 c linux shell awk readelf

我正在编写一个脚本,用于提取二进制文件中的所有函数(由用户编写).

以下shell脚本提取我的函数名称以及以__开头的一些库函数

readelf -s ./a.out | gawk '
{ 
  if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main") { 
    print "b " $NF; //***Updated
  } 
}' &> function_names; 
Run Code Online (Sandbox Code Playgroud)

function_names文件的输出:

b __libc_csu_fini
b PrintDivider    
b PrintFooter    
b __libc_csu_init    
b PrintHeader
Run Code Online (Sandbox Code Playgroud)

我想只提取我的功能.那么如何检查函数名称是否以__开头,否则任何其他替代品也会高度评价.

更新::
@djf解决方案工作正常.如果.c编译的文件也可能包含以__?开头的函数怎么办?在那种情况下,如何区分?

Jen*_*ens 8

如何使用readelf目标文件而不是链接的可执行文件?然后,库函数没有垃圾邮件.使用该-c标志编译为目标文件而不是立即链接.

PS:从可执行文件或目标文件中提取名称的正确工具nm不是readelf.使用nm -P file你想要的一切.

$ nm -P tst.o | awk '$2 == "T" {print "b " $1}'
b foo
b main
Run Code Online (Sandbox Code Playgroud)

编辑:要忽略main以下划线开头的符号,请使用

$ nm -P a.out | awk '$2 == "T" && $1 !~ /^_/ && $1 != "main" {print "b " $1}'
Run Code Online (Sandbox Code Playgroud)


djf*_*djf 5

您可以添加正则表达式检查以确保函数名称以字母开头.

我假设$ 8包含函数名称:

readelf -s ./a.out | gawk '
{
  if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main" && $8~/^[[:alpha:]]/) {
    print $NF;
  }
}'
Run Code Online (Sandbox Code Playgroud)