Alat ini memungkinkan untuk mendapatkan file .elf yang dapat dianalisis sepenuhnya dari gambar kernel VMLinux/VMlinuz/BzImage/Zimage (baik gumpalan biner mentah atau file .elf .elf yang sudah ada sebelumnya), dengan fungsi yang dipulihkan dan simbol variabel.
Untuk ini, ia memindai kernel Anda untuk tabel simbol kernel (Kallsyms), tabel simbol terkompresi yang ada di hampir setiap kernel, sebagian besar tidak berubah.
Karena tabel simbol yang bersangkutan pada awalnya dikompresi, ia harus memulihkan string yang tidak terlihat dalam biner asli.
Ini menghasilkan file .elf yang dapat Anda analisis menggunakan Ida Pro dan Ghidra. Alat ini karenanya berguna untuk sistem tertanam rekayasa terbalik.
Penggunaan:
./vmlinux-to-elf < input_kernel.bin > < output_kernel.elf > Instalasi Sistem-Seluruh (Perintah Kedua mungkin tidak diperlukan karena PIP harus menemukan dependensi dalam file setup.py ):
sudo apt install python3-pip liblzo2-dev
sudo pip3 install --upgrade lz4 zstandard git+https://github.com/clubby789/python-lzo@b4e39df
sudo pip3 install --upgrade git+https://github.com/marin-m/vmlinux-to-elfboot.img tertentu, dimulai dengan ANDROID! atau UNCOMPRESSED_IMG MAGIC [OK]Sejarah singkat tabel simbol "Kallsyms" dapat ditemukan di bagian atas file "Kallsyms_finder.py". Secara singkat, ini diperkenalkan sekitar tahun 2004 dalam kernel Linux dalam bentuknya saat ini dan digunakan untuk mencetak pesan "kernel oops", antara lain.
Ini berisi tupel "nama simbol", "alamat simbol", "tipe simbol" (tipe simbol yang ditetapkan dengan satu huruf dengan cara yang mirip dengan utilitas nm ), informasi ini dikemas erat dengan algoritma kompresi sederhana.
Skema di bawah ini menampilkan bagaimana informasi ini diserialisasi ke dalam kernel, offset dari masing-masing struktur masing-masing terdeteksi oleh vmlinux-to-elf melalui heuristik:
| Nama array | Keterangan | Isi sampel |
|---|---|---|
kallsyms_addresses (atau kallsyms_offsets + kallsyms_relative_base ) | Alamat (atau offset relatif terhadap pangkalan, dalam kernel baru -baru ini) dari setiap simbol, sebagai array | 80 82 00 C0 80 82 00 C0 80 82 00 C0 0C 84 00 C0 B4 84 00 C0 5C 85 00 C0 60 85 00 C0 60 85 00 C0 ... |
kallsyms_num_syms | Jumlah total simbol, sebagai bilangan bulat (berguna untuk memeriksa endianness, penyelarasan, decoding yang benar dari tabel simbol) | 54 D4 00 00 |
kallsyms_names | Simbol terkompresi, dipisahkan panjang nama itu sendiri. Setiap byte dalam string simbol terkompresi merujuk indeks dalam array "Kallsyms_token_index", yang dengan sendirinya merujuk pada offset karakter atau fragmen string dalam array "Kallsyms_token_table". | 09 54 64 6F 5F E1 F1 66 F5 25 05 54 F3 74 AB 74 0E 54 FF AB ... |
kallsyms_markers | Tabel pencarian yang melayani untuk menemukan dengan cepat offset perkiraan nama simbol terkompresi di "Kallsyms_names": setiap 256 simbol, offset ke simbol yang bersangkutan di "Kallsyms_names" ditambahkan sebagai panjang untuk tabel ini. | 00 00 00 00 03 0C 00 00 0C 18 00 00 1B 24 00 00 0F 31 00 00 DA 3D 00 00 CF 4A 00 00 ... |
kallsyms_seqs_of_names | Tabel pencarian ini (hanya ada dalam 6.2+ kernel) berisi urutan array dari bilangan bulat 3-byte yang dikemas, di mana indeks array cocok dengan urutan alfanumerik untuk nama simbol yang diberikan, dan nilai array cocok dengan indeks entri yang sesuai di kallsyms_addresses dan kallsyms_names Array | |
kallsyms_token_table | Fragmen atau karakter string yang diakhiri nol yang mungkin terkandung dalam nama simbol kernel. Ini dapat berisi paling banyak 256 fragmen atau karakter string. Indeks yang sesuai dengan titik kode ASCII yang sebenarnya digunakan dalam simbol kernel apa pun akan sesuai dengan karakter ASCII yang bersangkutan, posisi lain akan berisi fragmen string yang dipilih secara statistik. Alat ini mencoba untuk secara heuristik menemukan array ini di seluruh file yang diteruskan terlebih dahulu untuk menemukan tabel simbol kallsyms . | 73 69 00 67 70 00 74 74 00 79 6E 00 69 6E 74 5F 00 66 72 00 ... |
kallsyms_token_index | 256 kata, masing -masing pemetaan ke offset karakter atau fragmen string yang ditunjuk oleh indeks masing -masing dalam "Kallsyms_token_table". | 00 00 03 00 06 00 09 00 0C 00 11 00 14 00 1B 00 1E 00 22 00 2C 00 30 00 35 00 38 00 ... |
Bidang -bidang ini memiliki penyelarasan variabel dan ukuran bidang. Ukuran lapangan dapat bervariasi lebih dari arsitektur dan versi kernel juga. Untuk alasan ini, vmlinux-to-elf telah diuji pada berbagai kasus.
OpenWRT sejak 2013 memiliki tambalan yang menghilangkan kompresi di atas tabel kallsyms secara default (saat membangun kallsyms telah diaktifkan oleh pengguna). Mereka melakukan ini untuk menghemat ruang saat mengompres kembali kernel menggunakan LZMA.
Ini berarti bahwa entri kallsyms_token_table dan kallsyms_token_address menghilang, dan bahwa nama simbol menggunakan teks biasa ASCII sebagai gantinya. Kasing ini juga didukung.
Dalam kernel Linux 6.2 standar, array kallsyms dikodekan dalam urutan berikut:
kallsyms_addresses (atau kallsyms_offsets + kallsyms_relative_base )kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_seqs_of_names (hanya 6.2+)kallsyms_token_tablekallsyms_token_indexUntuk kernel Linux 6.4+, tata letak ini diubah menjadi:
kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_token_tablekallsyms_token_indexkallsyms_addresses (atau kallsyms_offsets + kallsyms_relative_base )kallsyms_seqs_of_names Sementara ini diuraikan dalam urutan berikut oleh algoritma penguraian vmlinux-to-elf :
kallsyms_token_table (struktur sebelum terakhir)kallsyms_token_index (struktur terakhir, ke depan)kallsyms_markers (mundur)kallsyms_names (mundur lagi)kallsyms_num_syms (mundur lagi)kallsyms_addresses (atau kallsyms_offsets + kallsyms_relative_base ) (mundur lagi) Ini harus mendukung kernel dari versi 2.6.10 (Desember 2004), hingga 6.4 saat ini (pada Agustus 2023). Hanya kernel yang secara eksplisit dikonfigurasi tanpa CONFIG_KALLSYMS tidak boleh didukung. Jika variabel konfigurasi kernel ini tidak diatur saat build, maka Anda akan mendapatkan: KallsymsNotFoundException: No embedded symbol table found in this kernel .
Untuk kernel mentah, arsitektur berikut dapat dideteksi (menggunakan sihir dari binwalk): Mipsel, Mipseb, Armel, Armeb, PowerPC, SPARC, x86, x86-64, ARM64, MIPS64, Superh, busur.
Format kompresi kernel berikut dapat secara otomatis terdeteksi: XZ, LZMA, GZIP, BZ2, LZ4, LZO dan ZSTD.
Anda juga dapat memperoleh output teks saja dari nama simbol kernel, alamat dan jenis melalui penggunaan utilitas kallsyms-finder , juga dibundel dengan alat ini. Format outputnya akan mirip dengan file /proc/kallsyms procfs.
Beberapa parameter yang harus secara otomatis disimpulkan oleh alat (seperti set instruksi atau alamat dasar) dapat ditimpa jika masalah. Spesifikasi penuh dari argumen yang memungkinkan untuk melakukan yang disajikan di bawah ini:
$ vmlinux-to-elf -h
usage: vmlinux-to-elf [-h] [--e-machine DECIMAL_NUMBER] [--bit-size BIT_SIZE]
[--file-offset HEX_NUMBER] [--base-address HEX_NUMBER]
input_file output_file
Turn a raw or compressed kernel binary, or a kernel ELF without symbols, into
a fully analyzable ELF whose symbols were extracted from the kernel symbol
table
positional arguments:
input_file Path to the
vmlinux/vmlinuz/zImage/bzImage/kernel.bin/kernel.elf
file to make into an analyzable .ELF
output_file Path to the analyzable .ELF to output
optional arguments:
-h, --help show this help message and exit
--e-machine DECIMAL_NUMBER
Force overriding the output ELF "e_machine" field with
this integer value (rather than auto-detect)
--bit-size BIT_SIZE Force overriding the input kernel bit size, providing
32 or 64 bit (rather than auto-detect)
--file-offset HEX_NUMBER
Consider that the raw kernel starts at this offset of
the provided raw file or compressed stream (rather
than 0, or the beginning of the ELF sections if an ELF
header was present in the input)
--base-address HEX_NUMBER
Force overriding the output ELF base address field
with this integer value (rather than auto-detect)
$ kallsyms-finder -h
usage: kallsyms-finder [-h] [--bit-size BIT_SIZE] input_file
Find the kernel's embedded symbol table from a raw or stripped ELF kernel
file, and print these to the standard output with their addresses
positional arguments:
input_file Path to the kernel file to extract symbols from
optional arguments:
-h, --help show this help message and exit
--bit-size BIT_SIZE Force overriding the input kernel bit size, providing
32 or 64 bit (rather than auto-detect)
Jangan ragu untuk membuka masalah untuk saran perbaikan.