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?
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
E se:
readelf -p .comment a.out
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.
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.
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.
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.
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. *".
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