GNU/Linux >> Belajar Linux >  >> Linux

header file ELF

Saya tidak tahu perintah skrip linker yang dapat melakukan ini, tetapi Anda dapat melakukannya setelah tautan menggunakan objcopy memerintah. --add-section opsi dapat digunakan untuk menambahkan bagian yang berisi data arbitrer ke file ELF. Jika header ELF tidak berisi bidang yang Anda inginkan, buat saja bagian baru dan tambahkan di sana.


Tautan ini (biner elf mungil) adalah jawaban seseorang untuk pertanyaan lain, tetapi tautan ini membahas seluk-beluk header ELF secara mendetail.


Anda dapat membuat file objek dengan bidang informatif seperti nomor versi dan menautkan file tersebut sehingga disertakan dalam biner ELF yang dihasilkan.

Identitas

Misalnya, sebagai bagian dari proses pembuatan, Anda dapat membuat - katakanlah - info.c yang berisi satu atau lebih #ident arahan:

#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"

Kompilasi:

$ gcc -c info.c

Periksa apakah informasi tersebut disertakan:

$ readelf -p .comment info.o
String dump of section '.comment':
  [     1]  Build: 1.2.3 (Halloween)
  [    1a]  Environment: example.org
  [    33]  GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)

Sebagai alternatif, Anda dapat menggunakan objdump -s --section .comment info.o . Perhatikan bahwa GCC juga menulis komentarnya sendiri, secara default.

Periksa informasi setelah menautkan executable ELF:

$ gcc -o main main.o info.o
$ readelf -p .comment main 
String dump of section '.comment':
  [     0]  GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)
  [    2c]  Build: 1.2.3 (Halloween)
  [    45]  Environment: example.org

Bagian Komentar

Menggunakan #ident dalam unit terjemahan C pada dasarnya sama dengan membuat .comment bagian dalam file assembler. Contoh:

$ cat info.s
.section .comment
.string "Build: 1.2.3 (Halloween)"
.string "Environment: example.org"
$ gcc -c info.s
$ readelf -p .comment info.o
String dump of section '.comment':
  [     0]  Build: 1.2.3 (Halloween)
  [    19]  Environment: example.org

Menggunakan nama bagian yang tidak umum juga dapat digunakan (mis. .section .blahblah ). Tapi .comment digunakan dan dipahami oleh alat lain. GNU juga memahami .ident direktif, dan inilah yang GCC terjemahkan #ident ke.

Dengan Simbol

Untuk data yang juga ingin Anda akses dari executable ELF itu sendiri, Anda perlu membuat simbol.

Salinan objek

Katakanlah Anda ingin memasukkan beberapa byte ajaib yang disimpan dalam file data:

$ cat magic.bin 
2342

Ubah menjadi file objek dengan GNU objcopy:

$ objcopy -I binary -O elf64-x86-64 -B i386 \
    --rename-section .data=.rodata,alloc,load,readonly,data,contents \
    magic.bin magic.o

Periksa simbol:

$ nm  magic.o  
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start

Contoh penggunaan:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>

extern const char _binary_magic_bin_start[];
extern const char _binary_magic_bin_end[];
extern const unsigned char _binary_magic_bin_size;
static const size_t magic_bin_size = (uintptr_t) &_binary_magic_bin_size;

int main()
{
  char s[23];
  memcpy(s, _binary_magic_bin_start,
      _binary_magic_bin_end - _binary_magic_bin_start);
  s[magic_bin_size] = 0;
  puts(s);
  return 0;
}

Tautkan semuanya menjadi satu:

$ gcc -g -o main_magic main_magic.c magic.o

GNU ld

GNU ld juga dapat mengubah file data menjadi file objek menggunakan skema penamaan yang kompatibel dengan objcopy:

$ ld -r -b binary magic.bin -o magic-ld.o

Tidak seperti objcopy, ini menempatkan simbol ke dalam .data bukan .rodata bagian, meskipun (lih. objdump -h magic.o ).

incbin

Jika objcopy GNU tidak tersedia, seseorang dapat menggunakan GNU sebagai .incbin direktif untuk membuat file objek (rakit dengan gcc -c incbin.s ):

    .section .rodata

    .global _binary_magic_bin_start
    .type _binary_magic_bin_start, @object
_binary_magic_bin_start:
    .incbin "magic.bin"
    .size _binary_magic_bin_start, . - _binary_magic_bin_start

    .global _binary_magic_bin_size
    .type _binary_magic_bin_size, @object
    .set _binary_magic_bin_size, . - _binary_magic_bin_start

    .global _binary_magic_bin_end
    .type _binary_magic_bin_end, @object
    .set _binary_magic_bin_end, _binary_magic_bin_start + _binary_magic_bin_size
    ; an alternate  way to include the size    
    .global _binary_magic_bin_len
    .type _binary_magic_bin_len, @object
    .size _binary_magic_bin_len, 8
_binary_magic_bin_len:
    .quad _binary_magic_bin_size

xxd

Alternatif yang lebih portabel yang tidak memerlukan objcopy GNU atau GNU adalah membuat file C perantara dan mengompilasi serta menautkannya. Misalnya dengan xxd:

$ xxd -i magic.bin | sed 's/\(unsigned\)/const \1/' > magic.c
$ gcc -c magic.c
$ nm magic.o
0000000000000000 R magic_bin
0000000000000008 R magic_bin_len
$ cat magic.c
const unsigned char magic_bin[] = {
  0x32, 0x33, 0x34, 0x32, 0x0a
};
const unsigned int magic_bin_len = 5;

Linux
  1. Urutan Pengalihan?

  2. Hitung Baris Dalam File?

  3. Menambahkan bagian ke file ELF

  1. C fopen vs terbuka

  2. Alat untuk memodifikasi bagian dinamis dari biner ELF

  3. Membaca dari file dalam perakitan

  1. glibc:file elf OS ABI tidak valid

  2. Tulis ke file .txt?

  3. Apa perbedaan bagian dan segmen dalam format file ELF