ti-enxame.com

Podemos obter informações do compilador de um binário elfo?

Existe alguma chance de saber como um binário foi construído, no Linux? (e ou outro Unix)

Compilador, versão, hora, sinalizadores etc ...

Eu olhei para readelf e não consegui encontrar muita coisa, mas pode haver outras maneiras de analisar o código/seção binário etc ...

Alguma coisa que você sabe extrair?

53
elmarco

Não existe uma maneira universal, mas você pode fazer um palpite, procurando coisas feitas apenas por um compilador.

O GCC é o mais fácil; escreve um .comment seção que contém a string da versão do GCC (a mesma string que você obtém se executar gcc --version). Não sei se existe uma maneira de exibi-lo com readelf, mas com objdump é:

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

Acabei de perceber que ignorei o resto da sua pergunta. As bandeiras geralmente não são salvas em nenhum lugar; eles provavelmente estariam em uma seção de comentários, mas nunca vi isso feito. Há um ponto no cabeçalho COFF para um registro de data e hora, mas não há equivalente no ELF, então não acho que o tempo de compilação esteja disponível também

52
Michael Mrozek

E se:

readelf -p .comment a.out
29
Colin King

Você pode tentar usar o comando strings. Isso criará muita saída de texto; marcando você pode adivinhar o compilador.

[email protected]:~$ strings -a a.out |grep -i gcc
GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Aqui eu sei que ele é compilado com gcc, mas você sempre pode redirecionar strings output para um arquivo e examiná-lo.

Existe um utilitário muito bom chamado peid para Windows, mas não consigo encontrar nenhuma alternativa para ele no Linux.

19
Hemant

readelf ou objdump, ambos podem fazer isso.

O arquivo ELF compilado pelo gcc adicionará .note.ABI-tag e .note.gnu.build-id duas seções. ambos podem ser exibidos por

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

opção "s" significa exibir o conteúdo completo, "j" para indicar o nome da seção. Esse estilo obtém o conteúdo hexadecimal dessas seções.

readelf -n

mostrará o conteúdo legível por humanos do ELFFILE uma vez. opção "n" significa NOTAS.

Escolha um como quiser.

A propósito, use objcopy, você pode adicionar sua própria seção no arquivo elf.

5
liuyang1

Existem dois métodos. Ambos darão o mesmo resultado

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

Usando o comando readelf, readelf -S binary exibirá os 40 cabeçalhos da seção no binário. Anote o número de série de .comment cabeçalho da seção. No meu sistema, ele apareceu como 27 (pode ser diferente para o seu caso)

readelf -x 30 path/to/binary -> que exibirá o dump Hex da seção '.comment'. Nesse despejo, você pode ver o compilador usado para criar o binário.

5
Ranjini

Você também pode usar este script inteligente que conta os números de várias instruções de CPU usadas pelo binário. É baseado na análise da saída objdump. Lembre-se de que pode levar muito tempo para terminar se você o usar em um grande binário.

4
rozcietrzewiacz

Se você abrir um binário ELF no 7-Zip, ele listará as várias seções. A partir daí, você pode usar a opção Exibir menu de contexto, por exemplo, na seção ".comment", para ver os comentários do compilador (por exemplo, "GCC: (GNU) 4.9 20150123 (pré-lançamento) Android = clang versão 3.8.256229 (com base no LLVM 3.8.256229) ").

Observe que a seção ".comment", se existir, parece começar com um caractere nulo; portanto, escolha um aplicativo visualizador para uso no 7-Zip que não fique confuso com isso (por exemplo, tente interpretar o dados como Unicode). Outras seções que podem existir e ser interessantes são ".nota. *".

0
Joe

Pode valer a pena um tiro de sorte, dependendo de qual programa. Alguns programas terão isso compilado como informação e acessível por algum tipo de chamada de versão (-V, --version, -Version, etc). Você pode encontrar qualquer subconjunto desses itens que você está procurando (incluindo conjunto nulo). Aqui está um exemplo particularmente proveitoso, o 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
Joshua Huber