46

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?

45

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

27

How about:

readelf -p .comment a.out
  • 3
    How is this different than Michael's objdump? Does it give more information? Available on different platforms? Cleaner output format? – Caleb Aug 19 '11 at 7:58
  • 9
    Cleaner output format. – marcin Mar 3 '13 at 15:48
18

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.

  • 1
    +1, allows you to see the compilation flags (if gcc) – Ivan Black Sep 11 '14 at 15:33
4

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.

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.

3

readelf or objdump both can do this.

ELF file compiled by gcc will add .note.ABI-tag and .note.gnu.build-id two 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.

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.

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
0

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.*".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.