70

Is there some chance to know how a binary was built, under Linux? (and or other Unix)

Compiler, version, time, flags etc...

I looked at readelf and couldn't find much, but there might be other ways at analyzing the binary code/section etc...

Anything you know how to extract?

bahamat
40.8k5 gold badges76 silver badges104 bronze badges
asked Aug 18, 2010 at 17:58

9 Answers 9

65

There isn't a universal way, but you can make an educated guess by looking for things only done by one compiler.

GCC is the easiest; it writes a .comment section that contains the GCC version string (the same string you get if you run gcc --version). I don't know if there's a way to display it with readelf, but with objdump it's:

objdump -s --section .comment /path/binary

I just realized I ignored the rest of your question. Flags aren't generally saved anywhere; they would be in a comment section most likely, but I've never seen that done. There's a spot in the COFF header for a timestamp, but there's no equivalent in ELF, so I don't think the compile time is available either

answered Aug 18, 2010 at 18:34
45

How about:

readelf -p .comment a.out
Michael Mrozek
95.6k40 gold badges245 silver badges236 bronze badges
answered Aug 19, 2011 at 7:48
2
  • 3
    How is this different than Michael's objdump? Does it give more information? Available on different platforms? Cleaner output format? Commented Aug 19, 2011 at 7:58
  • 11
    Cleaner output format. Commented Mar 3, 2013 at 15:48
24

You can try using the strings command. It will create a lot of text output; by checking it you might guess the compiler.

pubuntu@pubuntu:~$ strings -a a.out |grep -i gcc
GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Here I know it's compiled with gcc but you can always redirect strings output to a file and examine it.

There is one very good utility called peid for Windows but I can't find any alternative for it on Linux.

ctype.h
5561 gold badge7 silver badges17 bronze badges
answered Aug 18, 2010 at 18:59
1
  • 3
    +1, allows you to see the compilation flags (if gcc) Commented Sep 11, 2014 at 15:33
6

There are two methods . Both will give the same result

objdump -s --section .comment path/to/binary

Using readelf command, readelf -S binary will display the 40 section headers in the binary . Note the serial number of .comment section header. In my system , it showed as 27 (may be different for your case)

readelf -x 30 path/to/binary -> which will display the Hex dump of section '.comment' . In that dump , you can see the compiler used for building the binary.

answered Oct 9, 2012 at 13:44
5

readelf or objdump both can do this.

ELF file compiled by gcc will add .note.ABI-tag and .note.gnu.build-id sections. Both could displayed by:

objdump -sj .note.ABI-tag ELFFILE
objdump -sj .note.gnu.build-id ELFFILE

Option "s" means display full contents, "j" for indicate section name. This style get hex contents of that sections.

The command readelf -n will show human-readable content of ELFFILE once. option "n" means NOTES. Choose one as your like.

By the way, use objcopy, you can add your own section in elf file.

answered Jun 2, 2015 at 6:57
2
  • readelf -n worked for me - example output: Displaying notes found in: .note.gnu.build-id Owner Data size Description GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: b88bae04e9043b71b329bac0ce2a2e5314183272 Commented Sep 4, 2019 at 10:58
  • 1
    It's .note.gnu.build-id, not .note.gnu-build-id. Commented Sep 12, 2020 at 13:15
4

You can also use this clever script that counts the numbers of various CPU instructions used by the binary. It is based on parsing objdump output. Beware that it can take quite a long time to finish if you use it on a big binary.

Stephen Kitt
478k59 gold badges1.2k silver badges1.3k bronze badges
answered Aug 20, 2011 at 0:57
1
  • Worth noting that it's x86 only. Commented Jun 12, 2019 at 17:05
1

If you open an ELF binary in 7-zip, it will list the various sections within. From there, you can use the View context-menu option on say, the ".comment" section, to see the compiler's comments (eg. "GCC: (GNU) 4.9 20150123 (prerelease) Android clang version 3.8.256229 (based on LLVM 3.8.256229)").

Beware that the ".comment" section, if it exists, seems to start with a null character, so be sure to choose a viewer application for use within 7-zip that doesn't get confused by this (eg. tries to interpret the data as Unicode). Other sections that may exist and be of interest are ".note.*".

answered May 30, 2018 at 3:41
1
0

Might be worth a lucky shot, depending on which program. Some programs will have this compiled in as information and accessible by some sort of version call (-V, --version, -Version, etc). You may find any subset of those items you are looking for (including null set). Here's a particularly fruitful example, Perl 5:

$ perl -V
Summary of my perl5 (revision 5 version 26 subversion 2) configuration:
 Platform:
 osname=linux
 osvers=4.15.15-1-arch
 archname=x86_64-linux-thread-multi
 uname='linux flo-64 4.15.15-1-arch #1 smp preempt sat mar 31 23:59:25 utc 2018 x86_64 gnulinux '
 config_args='-des -Dusethreads -Duseshrplib -Doptimize=-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt -Dprefix=/usr -Dvendorprefix=/usr -Dprivlib=/usr/share/perl5/core_perl -Darchlib=/usr/lib/perl5/5.26/core_perl -Dsitelib=/usr/share/perl5/site_perl -Dsitearch=/usr/lib/perl5/5.26/site_perl -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib/perl5/5.26/vendor_perl -Dscriptdir=/usr/bin/core_perl -Dsitescript=/usr/bin/site_perl -Dvendorscript=/usr/bin/vendor_perl -Dinc_version_list=none -Dman1ext=1perl -Dman3ext=3perl -Dcccdlflags='-fPIC' -Dlddlflags=-shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Dldflags=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'
 hint=recommended
 useposix=true
 d_sigaction=define
 useithreads=define
 usemultiplicity=define
 use64bitint=define
 use64bitall=define
 uselongdouble=undef
 usemymalloc=n
 default_inc_excludes_dot=define
 bincompat5005=undef
 Compiler:
 cc='cc'
 ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
 optimize='-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong -fno-plt'
 cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
 ccversion=''
 gccversion='7.3.1 20180312'
 gccosandvers=''
 intsize=4
 longsize=8
 ptrsize=8
 doublesize=8
 byteorder=12345678
 doublekind=3
 d_longlong=define
 longlongsize=8
 d_longdbl=define
 longdblsize=16
 longdblkind=3
 ivtype='long'
 ivsize=8
 nvtype='double'
 nvsize=8
 Off_t='off_t'
 lseeksize=8
 alignbytes=8
 prototype=define
 Linker and Libraries:
 ld='cc'
 ldflags ='-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -L/usr/local/lib'
 libpth=/usr/local/lib /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include-fixed /usr/lib /lib/../lib /usr/lib/../lib /lib /lib64 /usr/lib64
 libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
 perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
 libc=libc-2.26.so
 so=so
 useshrplib=true
 libperl=libperl.so
 gnulibc_version='2.26'
 Dynamic Linking:
 dlsrc=dl_dlopen.xs
 dlext=so
 d_dlsymun=undef
 ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.26/core_perl/CORE'
 cccdlflags='-fPIC'
 lddlflags='-shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -L/usr/local/lib -fstack-protector-strong'
Characteristics of this binary (from libperl): 
 Compile-time options:
 HAS_TIMES
 MULTIPLICITY
 PERLIO_LAYERS
 PERL_COPY_ON_WRITE
 PERL_DONT_CREATE_GVSV
 PERL_IMPLICIT_CONTEXT
 PERL_MALLOC_WRAP
 PERL_OP_PARENT
 PERL_PRESERVE_IVUV
 USE_64_BIT_ALL
 USE_64_BIT_INT
 USE_ITHREADS
 USE_LARGE_FILES
 USE_LOCALE
 USE_LOCALE_COLLATE
 USE_LOCALE_CTYPE
 USE_LOCALE_NUMERIC
 USE_LOCALE_TIME
 USE_PERLIO
 USE_PERL_ATOF
 USE_REENTRANT_API
 Built under linux
 Compiled at Apr 18 2018 22:21:20
 %ENV:
 PERL5LIB="/home/jhuber/perl5/lib/perl5"
 PERL_LOCAL_LIB_ROOT="/home/jhuber/perl5"
 PERL_MB_OPT="--install_base "/home/jhuber/perl5""
 PERL_MM_OPT="INSTALL_BASE=/home/jhuber/perl5"
 @INC:
 /home/jhuber/perl5/lib/perl5/x86_64-linux-thread-multi
 /home/jhuber/perl5/lib/perl5
 /usr/lib/perl5/5.26/site_perl
 /usr/share/perl5/site_perl
 /usr/lib/perl5/5.26/vendor_perl
 /usr/share/perl5/vendor_perl
 /usr/lib/perl5/5.26/core_perl
 /usr/share/perl5/core_perl
answered May 8, 2018 at 17:15
0

I was looking for compilation details of a static linked haproxy binary.

Using -vv gave me the details I needed:

$ ./haproxy -vv
HA-Proxy version 1.6.4 2016年03月13日
Copyright 2000-2016 Willy Tarreau <[email protected]>
Build options :
 TARGET = linux2628
 CPU = generic
 CC = gcc
 CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
 OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_STATIC_PCRE=1
Default settings :
 maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with OpenSSL version : OpenSSL 1.0.2g 1 Mar 2016
Running on OpenSSL version : OpenSSL 1.0.2g 1 Mar 2016
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.38 2015年11月23日
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built without Lua support
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Available polling systems :
 epoll : pref=300, test result OK
 poll : pref=200, test result OK
 select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
answered Mar 15, 2023 at 17:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.