GNU/Linux >> Belajar Linux >  >> Linux

12 Linux Utilitas Biner GNU Perintah Binutils dengan Contoh (sebagai, ld, ar, nm, objcopy, objdump, ukuran, string, strip, c++ flint, addr2line, readelf Contoh Perintah)

Utilitas Biner GNU, biasanya disebut sebagai binutils, adalah kumpulan alat pengembangan yang menangani file perakitan, file objek , dan perpustakaan.

Generasi baru bahasa pemrograman yang datang dalam beberapa tahun terakhir benar-benar menutupi fungsionalitas utilitas ini, seperti yang terjadi di latar belakang. Jadi, banyak pengembang yang tidak menggunakan alat ini.

Namun, jika Anda seorang pengembang yang bekerja pada platform Linux / UNIX, penting untuk memahami berbagai perintah yang tersedia sebagai bagian dari alat pengembangan GNU.

Berikut ini adalah 12 perintah binutils berbeda yang tercakup dalam tutorial ini.

  1. sebagai – Perintah Perakit GNU
  2. ld – Perintah Penaut GNU
  3. ar – Perintah Arsip GNU
  4. nm – Mencantumkan Simbol File Objek
  5. objcopy – Menyalin dan Menerjemahkan File Objek
  6. objdump – Menampilkan Informasi File Objek
  7. ukuran – Daftar Ukuran Bagian dan Ukuran Toal
  8. string – Menampilkan Karakter yang Dapat Dicetak dari File
  9. strip – Buang Simbol dari File Objek
  10. c++filt – Perintah Demangle
  11. addr2line – Mengonversi Alamat ke Nama File dan Angka
  12. readelf – Menampilkan Info File ELF

Alat ini akan membantu Anda untuk memanipulasi file biner, objek, dan perpustakaan Anda secara efektif.

Dari 12 utilitas ini, as dan ld adalah yang paling penting, mereka adalah backend default dari GNU Compiler Collection (gcc). GCC hanya melakukan pekerjaan yang dikompilasi dari C/C++ ke bahasa assembly, dan tugas as dan ld untuk menghasilkan biner yang dapat dieksekusi.

Siapkan Kode Contoh

Untuk memahami bagaimana semua perintah ini bekerja, pertama, mari kita siapkan beberapa contoh kode assembly dari kode C dengan menggunakan gcc -S. Semua eksperimen yang ditampilkan di sini, dilakukan pada kotak linux x86 64bits.

Di bawah ini adalah kode C, yang hanya menggunakan nilai balik dari fungsi eksternal sebagai kode pengembalian. Tidak ada input/output, jadi jika ingin mengecek apakah program sudah dijalankan seperti yang diharapkan, silahkan cek kembali statusnya (echo $?). Kami memiliki tiga fungsi, main, func1 dan func2, dan satu file untuk setiap fungsi.

// func1.c file:
int func1() {
	return func2();
}

// func2.c file:
int func2() {
	return 1;
}

// main.c file:
int main() {
	return func1();
}

GCC memiliki dukungan library runtime C, sehingga fungsi utama diperlakukan sebagai fungsi normal. Untuk menyederhanakan demo, kami tidak ingin melibatkan pustaka C saat mengkompilasi dan menautkan file .s ini. Jadi, dua modifikasi dilakukan untuk main.s:

Modifikasi pertama adalah label _start ditambahkan untuk tahap tautan.

_start label adalah titik masuk Aplikasi, jika tidak ditentukan, peringatan seperti di bawah ini akan dilaporkan saat dijalankan ld.

ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078

Modifikasi kedua adalah ret diganti dengan panggilan keluar sistem.

Kita harus menaikkan interupsi keluar sistem secara manual. %eax digunakan untuk menyimpan nilai kembalian fungsi, tetapi panggilan keluar sistem menahannya di %ebx. Jadi, salin dari %eax ke %ebx

Di bawah ini adalah versi edit ulang kode perakitan gcc.

file func1.s:

	.file	"func1.c"
	.text
.globl func1
	.type	func1, @function
func1:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	$0, %eax
	call	func2
	leave

file func2.s:

	.file	"func2.c"
	.text
.globl func2
	.type	func2, @function
func2:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	$1, %eax
	leave
	ret

file main.s:

	.file	"main.c"
	.text
.globl main
.globl _start
	.type	main, @function
_start:
main:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	$0, %eax
	call	func1
            movl    %eax, %ebx
            movl    $1, %eax
            int        $0x80
	leave

1. sebagai – Perintah Perakit GNU

sebagai mengambil file perakitan sebagai input dan output file objek. File objek hanyalah format internal, yang akan digunakan sebagai input ld untuk menghasilkan file executable akhir.

Jalankan perintah as pada file main.s untuk mendapatkan file objek main.o seperti gambar di bawah ini.

as main.s -o main.o

file main.o (diproduksi oleh "as main.s -o main.o"), kita bisa mendapatkan informasi di bawah ini.

main.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped

File objek dalam format ELF, yang merupakan format file yang paling banyak digunakan untuk distribusi linux.

Harap diperhatikan bahwa perintah “as” juga memiliki dukungan sintaks untuk prapemrosesan, simbol, batasan, ekspresi, pseudo ops/direktif, dan komentar.

GNU Assembler dapat mendukung banyak koleksi mesin, tetapi biasanya hanya satu keluarga mesin/arsitektur yang dipilih saat dikompilasi atau dikompilasi silang.

2. ld – Perintah Penaut GNU

File objek biasanya berisi referensi ke fungsi eksternal di library/objek yang berbeda, dan tugas linker (ld) untuk menggabungkan semua file objek/library yang diperlukan untuk biner akhir, memindahkan bagian, dan menyelesaikan referensi.

Perilaku sebenarnya dari ld didefinisikan dalam skrip linker, yang menjelaskan tata letak memori dari file yang dapat dieksekusi.

Jika kita menautkan main.o saja (ld main.o -o main), akan ada kesalahan referensi yang tidak ditentukan:

main.o: In function `_start':
main.c:(.text+0xa): undefined reference to `func1'

Kami tidak akan mendapatkan file yang dapat dieksekusi tanpa menautkan ketiga file keberatan (ld main.o func1.o func2.o -o main).

# file main 
main: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), statically linked, not stripped

Berbeda dengan file objek, di sini kita mendapatkan executable yang terhubung secara statis.

as dan ld bekerja pada target/arsitektur tertentu. Tetapi ada beberapa alat yang bekerja pada objek BFD yang didefinisikan dalam binutils.

Dari beberapa baris terakhir dari output objcopy -h, kita bisa mendapatkan target dukungan.

objcopy: supported targets: elf64-x86-64 elf32-i386 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex

Perlu dikatakan bahwa Verilog, ihex tidak didukung oleh OS nyata, tetapi dapat sangat berguna dalam memproses konten objek dalam format teks. Mereka banyak digunakan dalam lingkungan simulasi chip untuk inisialisasi memori/rom.

3. ar/ranlib – Perintah Arsip GNU

ar dapat digunakan untuk menghasilkan dan memanipulasi perpustakaan statis, yang merupakan file arsip yang disusun oleh banyak objek.

Perilaku ar dapat dikontrol dari argumen baris perintah (gaya unix) atau file skrip. ranlib dapat menambahkan indeks simbol ke arsip, yang dapat mempercepat kecepatan tautan dan juga memfasilitasi panggilan rutin. ar -s akan melakukan hal yang sama seperti ranlib.

Untuk pengujian saya, dengan atau tanpa -s, ar akan selalu menampilkan indeks arsip.

Test1, tanpa -s.

# ar -r extern.a func1.o func2.o && nm -s extern.a
ar: creating extern.a

Archive index:
func1 in func1.o
func2 in func2.o

func1.o:
0000000000000000 T func1
                 U func2

func2.o:
0000000000000000 T func2

Untuk detail lengkap tentang perintah ar, baca ini:Perintah ar Linux Contoh:Cara Membuat, Melihat, Mengekstrak, Memodifikasi File Arsip C (*.a)

Uji 2, dengan -s.

# ar -r -s externS.a func1.o func2.o && nm -s externS.a
ar: creating externS.a

Archive index:
func1 in func1.o
func2 in func2.o

func1.o:
0000000000000000 T func1
                 U func2

func2.o:
0000000000000000 T func2

Tes 3, jalankan ranlib lagi.

# cp extern.a externR.a && ranlib externR.a && nm -s externR.a
Archive index:
func1 in func1.o
func2 in func2.o

func1.o:
0000000000000000 T func1
                 U func2

func2.o:
0000000000000000 T func2

Dapat ditunjukkan bahwa setiap pengujian menghasilkan hasil yang sama.

4. nm – Daftar Simbol File Objek

nm dapat membuat daftar simbol dari file objek. Kami telah menunjukkan penggunaannya di bagian atas.

Perintah nm memberikan informasi tentang simbol yang digunakan dalam file objek atau file yang dapat dieksekusi.

Informasi default yang disediakan oleh perintah nm adalah sebagai berikut:

  • Alamat virtual simbol
  • Karakter yang menggambarkan tipe simbol. Jika karakter dalam huruf kecil maka simbol lokal tetapi jika karakter dalam huruf besar maka simbol eksternal
  • Nama simbol
$ nm  -A ./*.o | grep func
./hello2.o:0000000000000000 T func_1
./hello3.o:0000000000000000 T func_2
./hello4.o:0000000000000000 T func_3
./main.o:                   U func
./reloc.o:                  U func
./reloc.o:0000000000000000  T func1
./test1.o:0000000000000000  T func
./test.o:                   U func

Baca selengkapnya:10 Contoh Perintah Linux nm Praktis

5. objcopy – Menyalin dan Menerjemahkan File Objek

objcopy dapat menyalin konten dari satu file objek ke file objek lain, dan objek input/output dapat dalam format yang berbeda.

Ada kalanya Anda perlu mem-port file objek yang tersedia untuk satu jenis platform (seperti ARM atau x86) ke jenis platform lain.

Hal-hal relatif mudah jika kode sumber tersedia karena dapat dikompilasi ulang pada platform target.

Tapi, bagaimana jika kode sumber tidak tersedia dan Anda masih perlu mem-porting file objek dari jenis platform ke platform lain? Nah, jika Anda menggunakan Linux maka perintah objcopy melakukan persis seperti yang diperlukan

Sintaks dari perintah ini adalah :

objcopy [options] infile [outfile]...

Baca selengkapnya:Contoh Perintah Objcopy Linux untuk Menyalin dan Menerjemahkan File Objek

6. objdump – Menampilkan Informasi File Objek

objdump dapat menampilkan informasi yang dipilih dari file objek. Kita bisa menggunakan objdump -d untuk menerapkan disassemble ke main.

# objdump -d main
main:     file format elf64-x86-64

Disassembly of section .text:

0000000000400078 <main>:
  400078:	55                   	push   %rbp
  400079:	48 89 e5             	mov    %rsp,%rbp
  40007c:	b8 00 00 00 00       	mov    $0x0,%eax
  400081:	e8 0a 00 00 00       	callq  400090 <func1>
  400086:	c9                   	leaveq 
  400087:	89 c3                	mov    %eax,%ebx
  400089:	b8 01 00 00 00       	mov    $0x1,%eax
  40008e:	cd 80                	int    $0x80

0000000000400090 <func1>:
  400090:	55                   	push   %rbp
  400091:	48 89 e5             	mov    %rsp,%rbp
  400094:	b8 00 00 00 00       	mov    $0x0,%eax
  400099:	e8 02 00 00 00       	callq  4000a0 <func2>
  40009e:	c9                   	leaveq 
  40009f:	c3                   	retq   

00000000004000a0 <func2>:
  4000a0:	55                   	push   %rbp
  4000a1:	48 89 e5             	mov    %rsp,%rbp
  4000a4:	b8 01 00 00 00       	mov    $0x1,%eax
  4000a9:	c9                   	leaveq 
  4000aa:	c3                   	retq   

Baca lebih lanjut:Contoh Perintah Linux Objdump (Membongkar File Biner)

7. size – Daftar Ukuran Bagian dan Ukuran Toal

size dapat menampilkan informasi ukuran bagian dalam file objek.

# size main
   text	   data	    bss	    dec	    hex	filename
     51	      0	      0	     51	     33	main

8. strings – Menampilkan Karakter yang Dapat Dicetak dari File

string dapat menampilkan urutan karakter yang dapat dicetak dari file objek. Secara default, hanya mencari di bagian .data. Dengan -a switch, semua bagian dapat dicari.

# strings -a main
.symtab
.strtab
.shstrtab
.text
main.c
func1.c
func2.c
func1
_start
__bss_start
main
func2
_edata
_end

Baca lebih lanjut:Contoh Perintah String Linux (Teks Pencarian di File Biner UNIX)

9. strip – Buang Simbol dari File Objek

strip dapat menghapus simbol dari file objek, yang dapat mengurangi ukuran file dan mempercepat eksekusi.

Kita dapat menampilkan tabel simbol dengan objdump. Tabel simbol menunjukkan entri/offset untuk setiap fungsi/label.

# objdump -t main

main:     file format elf64-x86-64

SYMBOL TABLE:
0000000000400078 l    d  .text	0000000000000000 .text
0000000000000000 l    df *ABS*	0000000000000000 main.c
0000000000000000 l    df *ABS*	0000000000000000 func1.c
0000000000000000 l    df *ABS*	0000000000000000 func2.c
0000000000400090 g     F .text	0000000000000000 func1
0000000000400078 g       .text	0000000000000000 _start
00000000006000ab g       *ABS*	0000000000000000 __bss_start
0000000000400078 g     F .text	0000000000000000 main
00000000004000a0 g     F .text	0000000000000000 func2
00000000006000ab g       *ABS*	0000000000000000 _edata
00000000006000b0 g       *ABS*	0000000000000000 _end

Setelah strip (#strip main), tabel simbol akan dihapus.

#objdump -t main

main:     file format elf64-x86-64

SYMBOL TABLE:
no symbols

Baca selengkapnya:10 Contoh Perintah Strip Linux (Mengurangi Ukuran File yang Dapat Dieksekusi/Binary)

10. c++filt – Perintah Demangle

C++ mendukung kelebihan beban yang memungkinkan nama fungsi yang sama mengambil jenis/jumlah argumen yang berbeda.

Ini dilakukan dengan mengubah nama fungsi menjadi nama assembler tingkat rendah, yang disebut mangling. c++filt dapat melakukan demangling untuk C++ dan Java.

Di sini, kami membuat kode sampel baru untuk penjelasan mangling.

Misalkan kita memiliki dua jenis func3 yang mengambil jenis argumen input yang berbeda, void dan int.

==> mangling.cpp <==
int func3(int a) {
	return a;
}
int func3() {
	return 0;
}
int main() {
	return func3(1);
}

Dalam format assembly, mereka memiliki nama yang berbeda, _Z5func3v dan _Z5func3i. Dan, salah satunya akan dipanggil sesuai dengan jenis argumen yang kita berikan ke func3 di mangling.cpp. Dalam contoh ini, _Z5func3i dipanggil.

==> mangling.s <==
	.file	"mangling.cpp"
	.text
.globl _Z5func3i
	.type	_Z5func3i, @function
_Z5func3i:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	%edi, -4(%rbp)
	movl	-4(%rbp), %eax
	leave
	ret

.globl _Z5func3v
	.type	_Z5func3v, @function
_Z5func3v:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	$0, %eax
	leave
	ret

.globl main
	.type	main, @function
main:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	$1, %edi
	call	_Z5func3i
	leave
	ret

#grep func3.*: mangling.s
_Z5func3i:
_Z5func3v:

Kita dapat meneruskan nama fungsi assembly ini ke c++filt, dan pernyataan definisi fungsi asli akan dipulihkan.

#grep func3.*: mangling.s | c++filt 
func3(int):
func3():

objdump juga dapat melakukan demangle dengan gaya yang berbeda:

  -C, --demangle[=STYLE]
  
  Decode mangled/processed symbol names
    The STYLE, if specified, can be 'auto', 'gnu',
    'lucid', 'arm', 'hp', 'edg', 'gnu-v3', 'java'
    or 'gnat'

11. addr2line – Ubah Alamat menjadi Nama File dan Angka

addr2line bisa mendapatkan file dan nomor baris dari alamat yang diberikan atau offset di dalam bagian yang dialokasikan kembali, dengan meneruskan informasi debug.

Pertama, kita harus mengkompilasi file assembly dengan flag -g, sehingga informasi debug akan ditambahkan ke objek. Dapat ditunjukkan dari bawah bahwa ada beberapa bagian debug sekarang.

objdump -h mainD

mainD:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000033  0000000000400078  0000000000400078  00000078  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .debug_aranges 00000090  0000000000000000  0000000000000000  000000b0  2**4
                  CONTENTS, READONLY, DEBUGGING
  2 .debug_info   000000dd  0000000000000000  0000000000000000  00000140  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_abbrev 0000003c  0000000000000000  0000000000000000  0000021d  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_line   000000ba  0000000000000000  0000000000000000  00000259  2**0
                  CONTENTS, READONLY, DEBUGGING

Dari hasil pembongkaran yang ditunjukkan pada bagian 2.d objdump, kita dapat melihat bahwa 0x400090 adalah entri dari func1, yang sama dengan hasil yang diberikan oleh addr2line.

addr2line -e mainD 0x400090
/media/shared/TGS/func1.s:6

12. readelf – Menampilkan Info File ELF

readelf dan elfedit hanya dapat beroperasi pada file elf.

readelf dapat menampilkan informasi dari file elf.
Kami dapat menampilkan informasi detail dari header ELF.

#readelf -h main_full
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400078
  Start of program headers:          64 (bytes into file)
  Start of section headers:          208 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         1
  Size of section headers:           64 (bytes)
  Number of section headers:         5
  Section header string table index: 2

Sama seperti readelf, Anda juga dapat menggunakan elfedit yang dapat memperbarui mesin, jenis file dan OS ABI di header elf. Harap dicatat bahwa, elfedit mungkin tidak disertakan secara default dalam distribusi Anda.

Baca selengkapnya:Dasar-dasar Format File Objek ELF Linux (dan Struktur Header ELF)


Linux
  1. Urutkan Perintah di Linux dengan Contoh

  2. 10+ perintah Linux VI dengan contoh

  3. perintah chattr di Linux dengan contoh

  1. perintah whoami di Linux dijelaskan dengan contoh

  2. 10 Contoh Perintah Strip Linux (Mengurangi Ukuran File yang Dapat Dieksekusi/Binary)

  3. Contoh Perintah Objdump Linux (Membongkar File Biner)

  1. Perintah Netstat di Linux - 28 Perintah dengan Contoh

  2. 10 Perintah Cepat Linux Tail dengan Contoh

  3. 17 Perintah Tar Berguna dengan Contoh Praktis di Linux