4

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

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

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

function_names 文件的输出:

b __libc_csu_fini
b PrintDivider    
b PrintFooter    
b __libc_csu_init    
b PrintHeader

我只想提取我的功能。那么如何检查函数名称是否以 __ 开头,或者任何其他替代方法也非常受欢迎。

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

4

3 回答 3

9

readelf在您的目标文件而不是链接的可执行文件上使用怎么样?然后没有来自库函数的垃圾邮件。使用该-c标志编译为目标文件,而不是立即链接。

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

$ nm -P tst.o | awk '$2 == "T" {print "b " $1}'
b foo
b main

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

$ nm -P a.out | awk '$2 == "T" && $1 !~ /^_/ && $1 != "main" {print "b " $1}'
于 2013-07-05T11:14:12.320 回答
5

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

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

readelf -s ./a.out | gawk '
{
  if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main" && $8~/^[[:alpha:]]/) {
    print $NF;
  }
}'
于 2013-07-05T11:09:49.767 回答
1

管它通过grep ^[^_]。[30 个字符]

于 2013-07-05T10:51:33.120 回答