Bisakah kita mendapatkan informasi kompiler dari biner elf?

50

Apakah ada peluang untuk mengetahui bagaimana biner dibangun, di Linux? (dan atau Unix lainnya)

Kompiler, versi, waktu, bendera dll ...

Saya melihat readelfdan tidak dapat menemukan banyak, tetapi mungkin ada cara lain untuk menganalisis kode biner / bagian dll ...

Adakah yang Anda tahu cara mengekstrak?

elmarco
sumber

Jawaban:

48

Tidak ada cara universal, tetapi Anda dapat membuat tebakan yang berpendidikan dengan mencari hal-hal yang hanya dilakukan oleh satu kompiler.

GCC adalah yang termudah; itu menulis .commentbagian yang berisi string versi GCC (string yang sama yang Anda dapatkan jika Anda menjalankan gcc --version). Saya tidak tahu apakah ada cara untuk menampilkannya readelf, tetapi dengan objdumpitu:

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

Saya baru sadar saya mengabaikan sisa pertanyaan Anda. Bendera umumnya tidak disimpan di mana pun; mereka akan berada di bagian komentar yang paling mungkin, tetapi saya belum pernah melihat itu dilakukan. Ada tempat di header COFF untuk cap waktu, tapi tidak ada yang setara di ELF, jadi saya tidak berpikir waktu kompilasi juga tersedia

Michael Mrozek
sumber
28

Bagaimana tentang:

readelf -p .comment a.out
Colin King
sumber
3
Bagaimana ini berbeda dari Michael objdump? Apakah ini memberikan informasi lebih lanjut? Tersedia di berbagai platform? Format keluaran lebih bersih?
Caleb
9
Format keluaran lebih bersih.
marcin
19

Anda dapat mencoba menggunakan stringsperintah. Ini akan membuat banyak output teks; dengan memeriksa Anda mungkin menebak kompiler.

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

Di sini saya tahu itu dikompilasi gcctetapi Anda selalu dapat mengarahkan stringsoutput ke file dan memeriksanya.

Ada satu utilitas yang sangat bagus peiduntuk Windows tetapi saya tidak dapat menemukan alternatif untuk itu di Linux.

Hemant
sumber
1
+1, memungkinkan Anda melihat bendera kompilasi (jika gcc)
Ivan Black
4

Ada dua metode. Keduanya akan memberikan hasil yang sama

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

Menggunakan perintah readelf, readelf -S binary akan menampilkan 40 bagian header dalam biner. Catat nomor seri .comment tajuk bagian. Dalam sistem saya, ini menunjukkan 27 (mungkin berbeda untuk kasus Anda)

readelf -x 30 path/to/binary -> yang akan menampilkan dump Hex bagian '.comment'. Di dump itu, Anda bisa melihat kompiler yang digunakan untuk membangun biner.

Ranjini
sumber
4

baik diri sendiri atau objdump keduanya bisa melakukan ini.

File ELF yang dikompilasi oleh gcc akan menambahkan .note.ABI-tag dan .note.gnu.build-id dua bagian. keduanya dapat ditampilkan oleh

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

opsi "s" berarti menampilkan konten lengkap, "j" untuk menunjukkan nama bagian. Gaya ini mendapatkan konten hex bagian itu.

readelf -n

akan menampilkan konten ELFFILE yang dapat dibaca manusia sekali. opsi "n" berarti CATATAN.

Pilih satu sesuai keinginan Anda.

Omong-omong, gunakan keberatan, Anda dapat menambahkan bagian Anda sendiri di file elf.

liuyang1
sumber
readelf -nbekerja untuk saya - contoh output: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

Anda juga dapat menggunakan skrip pintar ini yang menghitung jumlah berbagai instruksi CPU yang digunakan oleh biner. Ini didasarkan pada parsing keluaran objdump. Berhati-hatilah karena bisa memakan waktu yang cukup lama jika Anda menggunakannya pada biner besar.

rozcietrzewiacz
sumber
Perlu dicatat bahwa ini hanya x86.
Victor Sergienko
0

Mungkin layak dicoba, tergantung pada program mana. Beberapa program akan membuat ini dikompilasi sebagai informasi dan dapat diakses oleh semacam panggilan versi (-V, --version, -Version, dll). Anda dapat menemukan subset dari item-item yang Anda cari (termasuk set nol). Inilah contoh yang sangat bermanfaat, 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
sumber
0

Jika Anda membuka biner ELF dalam 7-zip, itu akan mencantumkan berbagai bagian di dalamnya. Dari sana, Anda dapat menggunakan opsi Lihat konteks-menu di katakanlah, bagian ".comment", untuk melihat komentar kompiler (mis. "GCC: (GNU) 4.9 20150123 (prerelease) Android clang versi 3.8.256229 (berdasarkan pada LLVM 3.8.256229) ").

Hati-hati bahwa bagian ".comment", jika ada, tampaknya dimulai dengan karakter nol, jadi pastikan untuk memilih aplikasi penampil untuk digunakan dalam 7-zip yang tidak menjadi bingung dengan ini (mis. Mencoba menafsirkan data sebagai Unicode). Bagian lain yang mungkin ada dan menarik adalah ".note. *".

Joe
sumber