如何检索用于编译给定的ELF可执行文件的GCC版本?

我想检索用于编译给定的可执行文件的GCC版本。 我尝试readelf但没有得到的信息。 有什么想法吗?

它通常存储在注释部分

 strings -a <binary/library> |grep "GCC: (" 

返回GCC:(GNU)XXX

 strip -R .comment <binary> strings -a <binary/library> |grep "GCC: (" 

不返回任何输出

除去.comment(以及.note)部分以减小大小并不罕见

 strip --strip-all -R .note -R .comment <binary> strip --strip-unneeded -R .note -R .comment <library> 

注意:busyboxstring默认指定-a选项,这是.comment部分所需的

编辑:与Berendra Tusla的答案相反,它不需要使用任何debugging标志编译此方法的工作。

二进制例子:

 # echo "int main(void){}">ac # gcc -oa ac -s # strings -aa |grep GCC GCC: (GNU) 4.3.4 # strip -R .comment a # strings -aa |grep GCC # 

对象示例:

 # gcc -c ac -s # strings -a ao |grep GCC GCC: (GNU) 4.3.4 # strip -R .comment ao # strings -aa |grep GCC # 

请注意,没有任何-g(debugging)标志和存在用于去除不需要的符号的-s标志。 GCC信息仍然可用,除非.comment部分被删除。 如果您需要保持此信息不变,则可能需要检查makefile(或适用的构build脚本)以validation-fno-ident不在$ CFLAGS中,而$ STRIP命令缺less-R .comment。 -fno-ident防止gcc从注释部分开始生成这些符号。

要完成别人所说的话: 除非您使用debugging信息进行编译否则不会将其存储在对象(或exe)文件中! (选项-g )。 如果您使用debug信息进行编译,则可以使用readelf将其恢复:

 $ cat ac int main(void){ return 0; } $ gcc ac $ readelf -wi a.out $ gcc ac -g $ readelf -wi a.out Contents of the .debug_info section: Compilation Unit @ offset 0x0: Length: 0x42 (32-bit) Version: 2 Abbrev Offset: 0 Pointer Size: 4 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) < c> DW_AT_producer : (indirect string, offset: 0x0): GNU C 4.4.3 20100108 (prerelease) <10> DW_AT_language : 1 (ANSI C) <11> DW_AT_name : ac <15> DW_AT_comp_dir : (indirect string, offset: 0x22): /tmp <19> DW_AT_low_pc : 0x8048394 <1d> DW_AT_high_pc : 0x804839e <21> DW_AT_stmt_list : 0x0 <1><25>: Abbrev Number: 2 (DW_TAG_subprogram) <26> DW_AT_external : 1 <27> DW_AT_name : (indirect string, offset: 0x27): main <2b> DW_AT_decl_file : 1 <2c> DW_AT_decl_line : 1 <2d> DW_AT_prototyped : 1 <2e> DW_AT_type : <0x3e> <32> DW_AT_low_pc : 0x8048394 <36> DW_AT_high_pc : 0x804839e <3a> DW_AT_frame_base : 0x0 (location list) <1><3e>: Abbrev Number: 3 (DW_TAG_base_type) <3f> DW_AT_byte_size : 4 <40> DW_AT_encoding : 5 (signed) <41> DW_AT_name : int 

看看它是如何说GNU C 4.4.3 20100108 (prerelease)

还有另外两种方式(也许有点简单),我刚刚在这里读到: https : //unix.stackexchange.com/questions/719/can-we-get-compiler-information-from-an-elf-binary

 $ readelf -p .comment /usr/lib64/flash-plugin/libflashplayer.so String dump of section '.comment': [ 1] GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7) [ 2e] GCC: (GNU) 4.3.2 ... 

 $ objdump -s --section .comment /usr/lib64/flash-plugin/libflashplayer.so /usr/lib64/flash-plugin/libflashplayer.so: file format elf64-x86-64 Contents of section .comment: 0000 00474343 3a202847 4e552920 342e332e .GCC: (GNU) 4.3. 0010 32203230 30383131 30352028 52656420 2 20081105 (Red 0020 48617420 342e332e 322d3729 00004743 Hat 4.3.2-7)..GC 0030 433a2028 474e5529 20342e33 2e320000 C: (GNU) 4.3.2.. ... 

这个信息没有存储在编译对象(c)中。

其实,对于C代码,你完全没有运气。 但是,对于C ++代码,您可能会从符号版本中find一些信息。 C ++运行时库中的一些函数是特定于版本的,并在对象文件中标记为这样。 尝试这个:

 readelf -Wa file.exe | grep 'GCC[[:alnum:]_.]*' --only-match | sort | uniq | tail -n 1 

但是,它不会显示使用的GCC版本。 它显示的是运行时提供给编译器的符号版本。 运行时通常是编译器的运行时间,其版本不小于上述命令显示的版本。

该信息不存储在编译对象中。

您可以使用elfinfo实用程序。 除了GCC,还支持检测Go和FPC的编译器版本。

Interesting Posts