Dari http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 :
Saya baru-baru ini perlu menyematkan file dalam file yang dapat dieksekusi. Karena saya bekerja pada baris perintah dengan gcc, dkk dan bukan dengan alat RAD mewah yang membuat semuanya terjadi secara ajaib, tidak langsung jelas bagi saya bagaimana membuat ini terjadi. Sedikit pencarian di internet menemukan peretasan yang pada dasarnya memasukkannya ke akhir eksekusi dan kemudian menguraikan di mana itu didasarkan pada banyak informasi yang tidak ingin saya ketahui. Sepertinya harus ada cara yang lebih baik ...
Dan ada, itu tujuan penyelamatan. objcopy mengubah file objek atau executable dari satu format ke format lainnya. Salah satu format yang dipahami adalah "biner", yang pada dasarnya adalah file apa pun yang tidak ada dalam salah satu format lain yang dipahami. Jadi, Anda mungkin membayangkan idenya: ubah file yang ingin kita sematkan menjadi file objek, lalu dengan mudah dapat ditautkan dengan kode kita yang lain.
Katakanlah kita memiliki nama file data.txt yang ingin kita sematkan di file yang dapat dieksekusi:
# cat data.txt
Hello world
Untuk mengubahnya menjadi file objek yang dapat kita tautkan dengan program kita, kita hanya menggunakan objcopy untuk menghasilkan file ".o":
# objcopy --input binary \
--output elf32-i386 \
--binary-architecture i386 data.txt data.o
Ini memberitahu objcopy bahwa file masukan kita dalam format "biner", bahwa file keluaran kita harus dalam format "elf32-i386" (file objek pada x86). Opsi --binary-architecture memberi tahu objcopy bahwa file output dimaksudkan untuk "dijalankan" pada x86. Ini diperlukan agar ld menerima file untuk ditautkan dengan file lain untuk x86. Orang akan berpikir bahwa menentukan format keluaran sebagai "elf32-i386" akan menyiratkan hal ini, tetapi sebenarnya tidak.
Sekarang kita memiliki file objek, kita hanya perlu memasukkannya saat kita menjalankan linker:
# gcc main.c data.o
Ketika kami menjalankan hasilnya, kami mendapatkan output yang didoakan:
# ./a.out
Hello world
Tentu saja, saya belum menceritakan keseluruhan cerita, atau menunjukkan main.c. Ketika objcopy melakukan konversi di atas, ia menambahkan beberapa simbol "linker" ke file objek yang dikonversi:
_binary_data_txt_start
_binary_data_txt_end
Setelah menautkan, simbol-simbol ini menentukan awal dan akhir file yang disematkan. Nama simbol dibentuk dengan memasukkan biner dan menambahkan _start atau _end ke nama file. Jika nama file berisi karakter apa pun yang tidak valid dalam nama simbol, maka akan diubah menjadi garis bawah (misalnya data.txt menjadi data_txt). Jika Anda mendapatkan nama yang belum terselesaikan saat menautkan menggunakan simbol ini, lakukan hexdump -C pada file objek dan lihat di akhir dump untuk nama yang dipilih objcopy.
Kode untuk benar-benar menggunakan file yang disematkan sekarang seharusnya sudah cukup jelas:
#include <stdio.h>
extern char _binary_data_txt_start;
extern char _binary_data_txt_end;
main()
{
char* p = &_binary_data_txt_start;
while ( p != &_binary_data_txt_end ) putchar(*p++);
}
Satu hal penting dan halus untuk diperhatikan adalah bahwa simbol yang ditambahkan ke file objek bukanlah "variabel". Mereka tidak berisi data apa pun, melainkan alamat mereka adalah nilainya. Saya mendeklarasikannya sebagai tipe char karena nyaman untuk contoh ini: data yang disematkan adalah data karakter. Namun, Anda bisa mendeklarasikannya sebagai apa saja, seperti int jika datanya adalah larik bilangan bulat, atau sebagai struct foo_bar_t jika datanya adalah larik dari bilah foo. Jika data yang disematkan tidak seragam, maka char mungkin yang paling nyaman: ambil alamatnya dan berikan penunjuk ke jenis yang tepat saat Anda melintasi data.