Pouvons-nous obtenir les informations du compilateur à partir d'un binaire elfe?

50

Existe-t-il une chance de savoir comment un binaire a été construit sous Linux? (et ou autre Unix)

Compilateur, version, heure, drapeaux etc ...

J'ai regardé readelfet je n'ai pas trouvé grand chose, mais il pourrait y avoir d'autres moyens d'analyser le code / section binaire, etc.

Quelque chose que vous savez extraire?

Elmarco
la source

Réponses:

48

Il n'y a pas de solution universelle, mais vous pouvez faire une supposition éclairée en recherchant des tâches effectuées par un seul compilateur.

GCC est le plus facile. il écrit une .commentsection contenant la chaîne de la version GCC (la même chaîne que si vous exécutiez gcc --version). Je ne sais pas s'il y a un moyen de l'afficher avec readelf, mais avec objdumpc'est:

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

Je viens de me rendre compte que j'ai ignoré le reste de votre question. Les drapeaux ne sont généralement sauvegardés nulle part; ils seraient probablement dans une section de commentaires, mais je n'ai jamais vu cela se faire. Il y a une place dans l'en-tête COFF pour un horodatage, mais il n'y a pas d'équivalent dans ELF, donc je ne pense pas que le temps de compilation soit disponible non plus

Michael Mrozek
la source
28

Que diriez-vous:

readelf -p .comment a.out
Colin King
la source
3
En quoi est-ce différent de Michael objdump? Donne-t-il plus d'informations? Disponible sur différentes plateformes? Format de sortie plus propre?
Caleb
9
Format de sortie plus propre.
Marcin
19

Vous pouvez essayer d'utiliser la stringscommande. Cela créera beaucoup de texte; en le cochant, vous pouvez deviner le compilateur.

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

Ici, je sais qu’il est compilé avec gccmais vous pouvez toujours rediriger la stringssortie vers un fichier et l’examiner.

Il existe un très bon utilitaire appelé peidWindows, mais je ne trouve aucune alternative sous Linux.

Hemant
la source
1
+1, vous permet de voir les drapeaux de compilation (si gcc)
Ivan Black
4

Il y a deux méthodes. Les deux vont donner le même résultat

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

En utilisant la commande readelf, readelf -S binary affichera les en-têtes de 40 sections dans le binaire. Notez le numéro de série de l'en .comment -tête de section. Dans mon système, il était indiqué que 27 (peut être différent pour votre cas)

readelf -x 30 path/to/binary -> qui affichera le vidage hexadécimal de la section '.comment'. Dans ce vidage, vous pouvez voir le compilateur utilisé pour construire le binaire.

Ranjini
la source
4

readelf ou objdump les deux peuvent le faire.

Le fichier ELF compilé par gcc ajoutera les sections .note.ABI-tag et .note.gnu.build-id. les deux pourraient afficher

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

option "s" signifie afficher tout le contenu, "j" pour indiquer le nom de la section. Ce style récupère le contenu hexadécimal de cette section.

readelf -n

affichera une fois le contenu lisible par l'homme de ELFFILE. l'option "n" signifie NOTES.

Choisissez un comme votre comme.

À propos, utilisez objcopy, vous pouvez ajouter votre propre section dans un fichier elf.

liuyang1
la source
readelf -na travaillé pour moi - exemple de sortie: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
Den-Jason
4

Vous pouvez également utiliser ce script intelligent qui compte le nombre d'instructions de processeur utilisées par le binaire. Il est basé sur l'analyse de la sortie d'objdump. Attention, la finition peut être assez longue si vous l'utilisez sur un gros fichier binaire.

rozcietrzewiacz
la source
À noter que c'est x86 seulement.
Victor Sergienko
0

Peut-être un coup de chance, selon le programme. Certains programmes auront cette information compilée et accessible par une sorte d’appel de version (-V, --version, -Version, etc.). Vous pouvez trouver n'importe quel sous-ensemble des éléments que vous recherchez (y compris un ensemble nul). Voici un exemple particulièrement fructueux, 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
Joshua Huber
la source
0

Si vous ouvrez un fichier binaire ELF dans 7-zip, il listera les différentes sections qu'il contient. À partir de là, vous pouvez utiliser l’option Afficher le menu contextuel de la section ".comment", par exemple, pour afficher les commentaires du compilateur (par exemple, "GCC: (GNU) 4.9 20150123 (version préliminaire) Android version 3.8.256229 (basée sur LLVM 3.8.256229) ").

Notez que la section ".comment", si elle existe, semble commencer par un caractère nul. Assurez-vous donc de choisir une application de visionneuse à utiliser dans une version 7-zip qui ne soit pas gênée par cela (par exemple, essaie d'interpréter le données en Unicode). Les autres sections pouvant exister et présenter un intérêt sont ".note. *".

Joe
la source