GNU/Linux >> Belajar Linux >  >> Linux

10 cara untuk menganalisis file biner di Linux

"Ada 10 tipe orang di dunia ini:mereka yang mengerti biner dan mereka yang tidak."

Lebih banyak sumber daya Linux

  • Lembar contekan perintah Linux
  • Lembar contekan perintah Linux tingkat lanjut
  • Kursus online gratis:Ikhtisar Teknis RHEL
  • Lembar contekan jaringan Linux
  • Lembar contekan SELinux
  • Lembar contekan perintah umum Linux
  • Apa itu container Linux?
  • Artikel Linux terbaru kami

Kami bekerja dengan binari setiap hari, namun kami hanya mengerti sedikit tentang mereka. Yang saya maksud dengan binari adalah file yang dapat dieksekusi yang Anda jalankan setiap hari, langsung dari alat baris perintah hingga aplikasi lengkap.

Linux menyediakan seperangkat alat yang membuat analisis binari menjadi mudah! Apa pun peran pekerjaan Anda, jika Anda bekerja di Linux, mengetahui dasar-dasar tentang alat ini akan membantu Anda memahami sistem Anda dengan lebih baik.

Pada artikel ini, kami akan membahas beberapa yang paling populer dari alat dan perintah Linux ini, yang sebagian besar akan tersedia secara asli sebagai bagian dari distribusi Linux Anda. Jika tidak, Anda selalu dapat menggunakan pengelola paket untuk menginstal dan menjelajahinya. Ingat:belajar menggunakan alat yang tepat pada kesempatan yang tepat membutuhkan banyak kesabaran dan latihan.

berkas

Fungsinya:Membantu menentukan jenis file.

Ini akan menjadi titik awal Anda untuk analisis biner. Kami bekerja dengan file setiap hari. Tidak semuanya adalah tipe yang dapat dieksekusi; ada berbagai macam jenis file di luar sana. Sebelum Anda mulai, Anda perlu memahami jenis file yang sedang dianalisis. Apakah itu file biner, file perpustakaan, file teks ASCII, file video, file gambar, PDF, file data, dll.?

Berkas perintah akan membantu Anda mengidentifikasi jenis file yang tepat yang Anda hadapi.

$ file /bin/ls
/bin/ls:ELF 64-bit LSB executable, x86-64, versi 1 (SYSV), tertaut secara dinamis (menggunakan shared libs), untuk GNU/Linux 2.6.32 , BuildID[sha1]=94943a89d17e9d373b2794dcb1f7e38c95b66c86, dilucuti
$
$ file /etc/passwd
/etc/passwd:teks ASCII
$

ldd

Fungsinya:Mencetak dependensi objek bersama.

Jika Anda telah menggunakan file perintah di atas pada biner yang dapat dieksekusi, Anda tidak dapat melewatkan pesan "tertaut secara dinamis" di output. Apa artinya?

Ketika perangkat lunak sedang dikembangkan, kami mencoba untuk tidak menemukan kembali roda. Ada serangkaian tugas umum yang dibutuhkan sebagian besar program perangkat lunak, seperti mencetak keluaran atau membaca dari standar di, atau membuka file, dll. Semua tugas umum ini diabstraksikan dalam serangkaian fungsi umum yang kemudian dapat digunakan semua orang alih-alih menulis varian mereka sendiri. Fungsi umum ini diletakkan di perpustakaan yang disebut libc atau glibc .

Bagaimana cara menemukan perpustakaan mana yang dapat dieksekusi bergantung? Di situlah ldd perintah datang ke dalam gambar. Menjalankannya terhadap biner yang ditautkan secara dinamis akan menampilkan semua library dependen dan jalurnya.

$ ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007ffef5ba1000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fea9f854000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007fea9f64f000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00007fea9f446000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fea9f079000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fea9ee17000)
        libdl.so.2 => /lib64/libdl .so.2 (0x00007fea9ec13000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fea9fa7b000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007fea9ea0e000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fea9e7f2000)
$

trace

Fungsinya:Pelacak panggilan perpustakaan.

Sekarang kita tahu bagaimana menemukan perpustakaan yang bergantung pada program yang dapat dieksekusi menggunakan ldd memerintah. Namun, perpustakaan dapat berisi ratusan fungsi. Dari ratusan itu, manakah fungsi sebenarnya yang digunakan oleh biner kita?

Lintasan perintah menampilkan semua fungsi yang dipanggil saat run time dari perpustakaan. Dalam contoh di bawah ini, Anda dapat melihat nama fungsi dipanggil, bersama dengan argumen yang diteruskan ke fungsi itu. Anda juga dapat melihat apa yang dikembalikan oleh fungsi-fungsi tersebut di sisi paling kanan dari output.

 $ ltrace ls 
__libc_start_main (0x4028c0, 1, 0x7ffd94023b88, 0x412950
strrchr ("ls", '/') =nil
setLocale (LC_All, " ") =" En_us.utf-8 "
bindtextdomain (" Coreutils "," / usr / share / locale ") =" / usr / share / locale "
teksdomain (" corutils ") =" Coreutils "
__cxa_atexit (0x40A930, 0, 0, 0x736c6974756572) =0
isatty (1) =1
getenv (" quoting_style ") =nil
getenv (" kolom ") =nil
ioctl(1, 21523, 0x7ffd94023a50)                                                   =0
< >
f flush (0x7ff7bae61c0) =0
fclose (0x7ff7bae61c0) =0
+++ keluar (status 0) ++ + $ /> $

Hexdump

Fungsinya:Menampilkan konten file dalam ASCII, desimal, heksadesimal, atau oktal.

Seringkali, Anda membuka file dengan aplikasi yang tidak tahu apa yang harus dilakukan dengan file itu. Coba buka file yang dapat dieksekusi atau file video menggunakan vim; yang akan Anda lihat hanyalah omong kosong yang ditampilkan di layar.

Membuka file yang tidak dikenal di Hexdump membantu Anda melihat apa sebenarnya isi file tersebut. Anda juga dapat memilih untuk melihat representasi ASCII dari data yang ada dalam file menggunakan beberapa opsi baris perintah. Ini mungkin membantu memberi Anda beberapa petunjuk tentang jenis file itu.

$ hexdump -C /bin/ls | kepala
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  d4 42 40 00 00 00 00 00  |..>......B@.....|
00000020  40 00 00 00 00 00 00 00  f0 c3 01 00 00 00 00 00  |@ ...............|
00000030  00 00 00 00 40 00 38 00  09 00 40 00 1f 00 1e 00  |[email protected]...@. ....|
00000040  06 00 00 00 05 00 00 00  40 00 00 00 00 00 00  |........@.......|
00000050  40 00 40 00 00 00 00 00  40 00 40 00 00 00 00 00  |@.@.....@.@.....|
00000060  f8 01 00 00 00 00 00 00  f8 01 00 00 00 00 00 00  |................|
00000070  08 00 00 00 00 00 00  03 00 00 00 04 00 00 00  |...... ..........|
00000080  38 02 00 00 00 00 00 00  38 02 40 00 00 00 00 00  |8.......8.@.....|
00000090  38 02 40 00 00 00 00 00  1c 00 00 00 00 00 00 00  |8.@.............|
$

string

Fungsinya:Mencetak string karakter yang dapat dicetak dalam file.

Jika Hexdump tampak agak berlebihan untuk kasus penggunaan Anda dan Anda hanya mencari karakter yang dapat dicetak dalam biner, Anda dapat menggunakan string perintah.

Saat perangkat lunak sedang dikembangkan, berbagai pesan teks/ASCII ditambahkan ke dalamnya, seperti mencetak pesan info, men-debug info, pesan bantuan, kesalahan, dan sebagainya. Asalkan semua informasi ini ada dalam biner, itu akan dibuang ke layar menggunakan string .

$ strings /bin/ls 

baca sendiri

Fungsinya:Menampilkan informasi tentang file ELF.

ELF (Executable and Linkable File Format) adalah format file yang dominan untuk executable atau binari, tidak hanya di Linux tetapi juga di berbagai sistem UNIX. Jika Anda telah menggunakan alat seperti perintah file, yang memberi tahu Anda bahwa file dalam format ELF, langkah logis berikutnya adalah menggunakan readelf perintah dan berbagai opsinya untuk menganalisis file lebih lanjut.

Memiliki referensi spesifikasi ELF yang sebenarnya berguna saat menggunakan readelf bisa sangat berguna. Anda dapat menemukan spesifikasinya di sini.

$ readelf -h /bin/ls
ELF Header:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Kelas:                       
Data:Komplemen 2, endian kecil
Versi:1 (saat ini)
OS / ABI:Unix - System v
ABI Versi:0
Jenis:Exec (file yang dapat dieksekusi)
  Mesin:                          Perangkat Mikro Lanjutan X86-64
  Versi:                        0x1
  Entry point address:                             :         115696 (byte ke dalam file)
  Bendera:                            0x0
  Ukuran header ini:              64 (byte)
     Ukuran header program:         115696 (byte ke dalam file)
 
  Ukuran header bagian:          64 (byte)
  Jumlah header bagian:        31
  Indeks tabel string header bagian:30
$

objdump

Fungsinya:Menampilkan informasi dari file objek.

Biner dibuat saat Anda menulis kode sumber yang dikompilasi menggunakan alat yang disebut, secara mengejutkan, kompiler. Kompiler ini menghasilkan instruksi bahasa mesin yang setara dengan kode sumber, yang kemudian dapat dieksekusi oleh CPU untuk melakukan tugas yang diberikan. Kode bahasa mesin ini dapat diinterpretasikan melalui mnemonik yang disebut bahasa assembly. Bahasa assembly adalah sekumpulan instruksi yang membantu Anda memahami operasi yang dilakukan oleh program dan akhirnya dieksekusi pada CPU.

objdump utilitas membaca file biner atau yang dapat dieksekusi dan membuang instruksi bahasa rakitan di layar. Pengetahuan tentang perakitan sangat penting untuk memahami output dari objdump perintah.

Ingat:bahasa assembly adalah khusus arsitektur.

$ objdump -d /bin/ls | head

/bin/ls:    format file elf64-x86-64


Pembongkaran bagian .init:

0000000000402150 <_init @@Base>:
  402150:      48 83 ec 08             sub    $0x8,%rsp
  402154:      48 8b 05 6d 8e 21 00    mov    0x218e6d( _ 6d_ />  40215b:      48 85 c0                test   %rax,%rax
$

strace

Fungsinya:Melacak panggilan dan sinyal sistem.

Jika Anda telah menggunakan ltrace , disebutkan sebelumnya, pikirkan strace menjadi serupa. Satu-satunya perbedaan adalah, alih-alih memanggil perpustakaan, strace utilitas melacak panggilan sistem. Panggilan sistem adalah cara Anda berinteraksi dengan kernel untuk menyelesaikan pekerjaan.

Sebagai contoh, jika Anda ingin mencetak sesuatu ke layar, Anda akan menggunakan printf atau menempatkan fungsi dari pustaka standar libc; namun, pada akhirnya, panggilan sistem bernama tulis akan dibuat untuk benar-benar mencetak sesuatu ke layar.

$ strace -f /bin/ls
execve("/bin/ls", ["/bin/ls"], [/* 17 vars */]) =0
brk( NULL)                               =0x686000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =0x7f967f967956a000/dll", _OK
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) =3
fstat(3, {st_mode=S_IFREG|0644, st_size=40661 , ...}) =0
mmap(NULL, 40661, PROT_READ, MAP_PRIVATE, 3, 0) =0x7f9679560000
close(3)                                =0
< >fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) =0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ) =0x7f9679569000
tulis(1, "R2  RH\n", 7R2  RH
)                 =7
close(1)                               =7
close(1)                         96 =      96 =  0  > mun br />close(2)                                =0
exit_group(0)                           =?
++ + keluar dengan 0 +++
$

nm

Fungsinya:Membuat daftar simbol dari file objek.

Jika Anda bekerja dengan biner yang tidak dilucuti, nm perintah akan memberi Anda informasi berharga yang tertanam dalam biner selama kompilasi. nm dapat membantu Anda mengidentifikasi variabel dan fungsi dari biner. Anda dapat membayangkan betapa bergunanya ini jika Anda tidak memiliki akses ke kode sumber biner yang sedang dianalisis.

Untuk menampilkan nm , kami akan segera menulis program kecil dan mengompilasinya dengan -g opsi, dan kita juga akan melihat bahwa biner tidak dihapus dengan menggunakan perintah file.

$ cat hello.c 
#include

int main() {
    printf("Hello world!");
    return 0;
}
$
$ gcc -g hello.c -o hello
$
$ file hello
hello:ELF 64-bit LSB yang dapat dieksekusi , x86-64, versi 1 (SYSV), tertaut secara dinamis (menggunakan shared libs), untuk GNU/Linux 2.6.32, BuildID[sha1]=3de46c8efb98bce4ad525d3328121568ba3d8a5d, tidak dilucuti
$
$ ./hello
Halo dunia!$
$


$ nm halo | ekor
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
00000000004005b0 T __libc_csu_fini
0000000000400540 T __libc_csu_init
     _ _   @ _utama>                 U printf@@GLIBC_2.2.5
0000000000400490 t register_tm_clones
0000000000400430 T _start
0000000000601030 D __TMC_END__
$

gdb

Fungsinya:Debugger GNU.

Yah, tidak semua dalam biner dapat dianalisis secara statis. Kami memang menjalankan beberapa perintah yang menjalankan biner, seperti ltrace dan strace; namun, perangkat lunak terdiri dari berbagai kondisi yang dapat menyebabkan berbagai jalur alternatif dieksekusi.

Satu-satunya cara untuk menganalisis jalur ini adalah pada waktu berjalan dengan memiliki kemampuan untuk menghentikan atau menjeda program di lokasi tertentu dan mampu menganalisis informasi dan kemudian bergerak lebih jauh ke bawah.

Di situlah debugger datang ke dalam gambar, dan di Linux, gdb adalah debugger de facto. Ini membantu Anda memuat program, mengatur breakpoint di tempat tertentu, menganalisis memori dan register CPU, dan melakukan lebih banyak lagi. Ini melengkapi alat lain yang disebutkan di atas dan memungkinkan Anda melakukan lebih banyak analisis runtime.

Satu hal yang perlu diperhatikan adalah, setelah Anda memuat program menggunakan gdb , Anda akan disajikan dengan (gdb)-nya sendiri mengingatkan. Semua perintah lebih lanjut akan dijalankan di gdb . ini command prompt sampai Anda keluar.

Kami akan menggunakan program "halo" yang telah kami kompilasi sebelumnya dan menggunakan gdb untuk melihat cara kerjanya.

$ gdb -q ./hello
Membaca simbol dari /home/flash/hello...done.
(gdb) break main
Breakpoint 1 pada 0x400521:file hello.c , baris 4.
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000400521 in main di hello.c:4
/>Memulai program:/home/flash/./hello

Breakpoint 1, main () di hello.c:4
4           printf("Halo dunia!");
Tidak ada debuginfo terpisah, gunakan:debuginfo-install glibc-2.17-260.el7_6.6.x86_64
(gdb) bt
#0  main () di hello.c:4
(gdb ) c
Melanjutkan.
Halo dunia![Inferior 1 (proses 29620) keluar secara normal]
(gdb) q
$

Kesimpulan

Setelah Anda merasa nyaman menggunakan alat analisis biner Linux asli ini dan memahami output yang mereka berikan, Anda kemudian dapat beralih ke alat analisis biner open source yang lebih canggih dan profesional seperti radare2.


Linux
  1. Linux menemukan perintah

  2. File log Linux

  3. Perintah Linux ls - Daftar File

  1. Perintah mcopy di Linux

  2. Bagaimana cara membandingkan file biner di Linux?

  3. Diff/patch biner untuk file besar di linux?

  1. 5 cara menggunakan perintah pindah di Linux

  2. 3 Cara Mendaftar Pengguna di Linux

  3. Bagaimana membedakan biner dari file teks di linux