Можем ли мы получить информацию о компиляторе из двоичного файла elf?

50

Есть ли шанс узнать, как был построен бинарный файл под Linux? (и / или другой Unix)

Компилятор, версия, время, флаги и т.д ...

Я посмотрел readelfи не смог найти много, но могут быть другие способы анализа двоичного кода / раздела и т. Д.

Что-нибудь, что вы знаете, как извлечь?

Elmarco
источник

Ответы:

48

Универсального способа не существует, но вы можете сделать обоснованное предположение, ища вещи, которые выполняет только один компилятор.

GCC самый простой; он записывает .commentраздел, содержащий строку версии GCC (ту же строку, которую вы получите, если вы запустите gcc --version). Я не знаю, есть ли способ показать это readelf, но с objdumpэтим:

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

Я только что понял, что проигнорировал остальную часть вашего вопроса. Флаги вообще нигде не сохраняются; скорее всего, они будут в разделе комментариев, но я никогда не видел, чтобы это было сделано. В заголовке COFF есть место для метки времени, но в ELF нет эквивалента, поэтому я не думаю, что время компиляции также доступно

Михаил Мрозек
источник
28

Как насчет:

readelf -p .comment a.out
Колин Кинг
источник
3
Чем это отличается от Майкла objdump? Это дает больше информации? Доступно на разных платформах? Более чистый формат вывода?
Калеб
9
Более чистый формат вывода.
Марчин
19

Вы можете попробовать использовать stringsкоманду. Это создаст много текстового вывода; проверив его, вы можете угадать компилятор.

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

Здесь я знаю, что он скомпилирован, gccно вы всегда можете перенаправить stringsвывод в файл и проверить его.

Есть одна очень хорошая утилита peidдля Windows, но я не могу найти альтернативы для нее в Linux.

Hemant
источник
1
+1, позволяет увидеть флаги компиляции (если gcc)
Иван Блэк
4

Есть два метода. Оба дадут одинаковый результат

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

Используя команду readelf, вы readelf -S binary увидите 40 заголовков разделов в двоичном файле . Обратите внимание на серийный номер .comment заголовка раздела. В моей системе это показывалось как 27 (может отличаться для вашего случая)

readelf -x 30 path/to/binary -> который будет отображать шестнадцатеричный дамп раздела .comment. В этом дампе вы можете увидеть компилятор, используемый для сборки двоичного файла.

Рейнджини
источник
4

readelf или objdump оба могут сделать это.

ELF-файл, скомпилированный gcc, добавит .note.ABI-tag и .note.gnu.build-id в два раздела. оба могут отображаться

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

опция «s» означает отображение полного содержимого, «j» для указания названия раздела. Этот стиль получает шестнадцатеричное содержимое этих разделов.

readelf -n

покажет удобочитаемое содержание ELFFILE один раз. опция "n" означает ЗАМЕЧАНИЯ.

Выберите тот, который вам нравится.

Кстати, используйте objcopy, вы можете добавить свой собственный раздел в файл elf.

liuyang1
источник
readelf -nработал для меня - пример вывода: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
Ден-Джейсон
4

Вы также можете использовать этот умный скрипт, который подсчитывает количество различных инструкций процессора, используемых двоичным файлом. Он основан на разборе вывода objdump. Помните, что это может занять довольно много времени, если вы используете его в большом двоичном файле.

rozcietrzewiacz
источник
Стоит отметить, что это только x86.
Виктор Сергиенко
0

Может стоить удачного выстрела, в зависимости от того, какая программа. В некоторых программах это будет скомпилировано как информация и доступно с помощью какого-либо вызова версии (-V, --version, -Version и т. Д.). Вы можете найти любое подмножество из тех элементов, которые вы ищете (включая нулевое множество). Вот особенно плодотворный пример 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

Если вы откроете бинарный файл ELF в 7-zip, в нем будут перечислены различные разделы. Оттуда вы можете использовать опцию View context-menu, например, в разделе «.comment», чтобы увидеть комментарии компилятора (например, «GCC: (GNU) 4.9 20150123 (предварительная версия) Android clang версия 3.8.256229 (на основе LLVM 3.8.256229) ").

Помните, что раздел «.comment», если он существует, кажется, начинается с нулевого символа, поэтому обязательно выберите приложение для просмотра для использования в 7-zip, которое не смущается этим (например, пытается интерпретировать данные как Unicode). Другие разделы, которые могут существовать и представлять интерес: ".note. *".

Джо
источник