ELF

ELF Dosya Formatını Anlama

ELF Dosya Formatını Anlama

Kaynak Koddan İkili Kod'a

Programlama, akıllı bir fikre sahip olmakla ve kaynak kodunu seçtiğiniz bir programlama dilinde, örneğin C'de yazmakla ve kaynak kodunu bir dosyaya kaydetmekle başlar. Yeterli bir derleyici yardımıyla, örneğin GCC, kaynak kodunuz önce nesne koduna çevrilir. Sonunda, bağlayıcı, nesne kodunu, nesne kodunu başvurulan kitaplıklarla bağlayan ikili bir dosyaya çevirir. Bu dosya, CPU tarafından anlaşılan ve derlenen program çalıştırılır çalıştırılmaz çalıştırılan makine kodu olarak tek talimatları içerir.

Yukarıda bahsedilen ikili dosya belirli bir yapıyı takip eder ve en yaygın olanlardan biri, Yürütülebilir ve Bağlanabilir Biçimi kısaltan ELF olarak adlandırılır. Yürütülebilir dosyalar, yeniden konumlandırılabilir nesne dosyaları, paylaşılan kitaplıklar ve çekirdek dökümleri için yaygın olarak kullanılır.

Yirmi yıl önce - 1999'da - 86open projesi, x86 işlemcilerdeki Unix ve Unix benzeri sistemler için standart ikili dosya formatı olarak ELF'yi seçti. Neyse ki, ELF formatı daha önce hem System V Uygulama İkili Arayüzü hem de Araç Arayüzü Standardında [4] belgelenmişti. Bu gerçek, Unix tabanlı işletim sistemlerinin farklı satıcıları ve geliştiricileri arasındaki standardizasyon anlaşmasını büyük ölçüde basitleştirdi.

Bu kararın arkasındaki neden ELF'nin tasarımıydı - farklı endian biçimleri ve adres boyutları için esneklik, genişletilebilirlik ve platformlar arası destek. ELF'nin tasarımı belirli bir işlemci, komut seti veya donanım mimarisi ile sınırlı değildir. Yürütülebilir dosya biçimlerinin ayrıntılı bir karşılaştırması için buraya bakın [3].

O zamandan beri, ELF formatı birkaç farklı işletim sistemi tarafından kullanılmaktadır. Diğerlerinin yanı sıra buna Linux, Solaris/Illumos, Free-, Net- ve OpenBSD, QNX, BeOS/Haiku ve Fuchsia OS [2] dahildir. Ayrıca, Android, Maemo veya Meego OS/Sailfish OS çalıştıran mobil cihazlarda ve ayrıca PlayStation Portable, Dreamcast ve Wii gibi oyun konsollarında bulacaksınız.

Spesifikasyon, ELF dosyaları için dosya adı uzantısını netleştirmez. Kullanımda, çeşitli harf kombinasyonları, örneğin .axf, .çöp Kutusu, .elf, .Ö, .prx, .puf, .ko, .yani ve .mod veya hiçbiri.

Bir ELF Dosyasının Yapısı

Bir Linux terminalinde, man elf komutu size bir ELF dosyasının yapısı hakkında kullanışlı bir özet verir:

Liste 1: ELF yapısının kılavuz sayfası

$ adam elf
ELF(5) Linux Programcı El Kitabı ELF(5)
İSİM
elf - Yürütülebilir ve Bağlama Biçimi (ELF) dosyalarının biçimi
ÖZET
#Dahil etmek
AÇIKLAMA
başlık dosyası ELF yürütülebilir ikili dosyasının biçimini tanımlar
Dosyalar. Bu dosyalar arasında normal yürütülebilir dosyalar, yeniden konumlandırılabilir
nesne dosyaları, çekirdek dosyalar ve paylaşılan kitaplıklar.
ELF dosya biçimini kullanan yürütülebilir bir dosya, bir ELF başlığından oluşur,
ardından bir program başlık tablosu veya bir bölüm başlık tablosu veya her ikisi gelir.
ELF başlığı her zaman dosyanın ofset sıfır noktasındadır. program
başlık tablosu ve bölüm başlık tablosunun dosyadaki ofseti
ELF başlığında tanımlanmış. İki tablo geri kalanını açıklamaktadır
dosyanın özellikleri.

Yukarıdaki açıklamadan da görebileceğiniz gibi, bir ELF dosyası iki bölümden oluşur - bir ELF başlığı ve dosya verileri. Dosya verileri bölümü, sıfır veya daha fazla bölümü tanımlayan bir program başlık tablosundan, sıfır veya daha fazla bölümü tanımlayan bir bölüm başlık tablosundan, ardından program başlık tablosundan girişler tarafından atıfta bulunulan verilerden ve bölüm başlık tablosundan oluşabilir. Her segment, dosyanın çalışma zamanında yürütülmesi için gerekli bilgileri içerirken, bölümler bağlantı ve yer değiştirme için önemli veriler içerir. Şekil 1 bunu şematik olarak göstermektedir.

ELF Başlığı

ELF başlığı 32 bayt uzunluğundadır ve dosyanın biçimini tanımlar. 0x7F olan dört benzersiz bayt dizisiyle başlar, ardından 0x45, 0x4c ve 0x46 E, L ve F olmak üzere üç harfe dönüşür. Diğer değerlerin yanı sıra, başlık ayrıca 32 veya 64 bit biçimi için bir ELF dosyası olup olmadığını, küçük veya büyük endianness kullanıp kullanmadığını, ELF sürümünü ve dosyanın birlikte çalışabilmesi için hangi işletim sistemi için derlendiğini gösterir. sağ uygulama ikili arabirimi (ABI) ve işlemci komut seti.

İkili dosya dokunuşunun hexdump'ı aşağıdaki gibi görünür:

.Liste 2: İkili dosyanın hexdump'ı

$ hd /usr/bin/dokunma | kafa -5
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 e3 25 40 00 00 00 00 00 |… >… %@… |
00000020 40 00 00 00 00 00 00 28 e4 00 00 00 00 00 00 |@… (… |
00000030 00 00 00 00 40 00 38 00 09 00 40 00 1b 00 1a 00 |[e-posta korumalı]@… |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 |[e-posta korumalı]|

Debian GNU/Linux, GNU 'binutils' paketinde sağlanan readelf komutunu sunar. -h anahtarının ("-file-header" için kısa versiyonu) eşliğinde, bir ELF dosyasının başlığını güzel bir şekilde görüntüler. Liste 3, komut dokunuşu için bunu göstermektedir.

.Liste 3: Bir ELF dosyasının başlığını görüntüleme

$ readelf -h /usr/bin/dokunma
ELF Başlığı:
Sihir: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Sınıf: ELF64
Veri: 2'nin tamamlayıcısı, küçük endian
Sürüm: 1 (geçerli)
OS/ABI: UNIX - Sistem V
ABI Sürümü: 0
Tür: EXEC (Yürütülebilir dosya)
Makine: Gelişmiş Mikro Cihazlar X86-64
Sürüm: 0x1
Giriş noktası adresi: 0x4025e3
Program başlıklarının başlangıcı: 64 (dosyaya bayt)
Bölüm başlıklarının başlangıcı: 58408 (dosyaya bayt)
Bayraklar: 0x0
Bu başlığın boyutu: 64 (bayt)
Program başlıklarının boyutu: 56 (bayt)
Program başlığı sayısı: 9
Bölüm başlıklarının boyutu: 64 (bayt)
Bölüm başlıklarının sayısı: 27
Bölüm başlığı dize tablosu dizini: 26

Program Başlığı

Program başlığı, çalışma zamanında kullanılan bölümleri gösterir ve sisteme bir süreç görüntüsünün nasıl oluşturulacağını söyler. Liste 2'deki başlık, ELF dosyasının her biri 56 bayt boyutunda 9 program başlığından oluştuğunu ve ilk başlığın bayt 64'te başladığını gösteriyor.

Yine, readelf komutu, bilgileri ELF dosyasından çıkarmaya yardımcı olur. -l anahtarı (-program-headers veya -segments kısaltması) Liste 4'te gösterildiği gibi daha fazla ayrıntı gösterir.

.Liste 4: Program başlıklarıyla ilgili bilgileri görüntüleyin

$ readelf -l /usr/bin/touch
Elf dosya türü EXEC'dir (Yürütülebilir dosya)
Giriş noktası 0x4025e3
Ofset 64'ten başlayan 9 program başlığı vardır
Program Başlıkları:
Tip Ofset VirtAdr PhysAddr
FileSiz MemSiz Bayrakları Hizala
PHDR 0x00000000000000040 0x0000000000400040 0x0000000000400040
0x000000000000001f8 0x00000000000001f8 RE 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Program yorumlayıcısı isteniyor: /lib64/ld-linux-x86-64.yani.2]
YÜK 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 RE 200000
YÜK 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 2000000
DİNAMİK 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x000000000000001d0 0x00000000000001d0 RW 8
NOT 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x00000000000000044 0x00000000000000044 R 4
GNU_EH_FRAME 0x000000000000bc40 0x000000000040bc40 0x000000000040bc40
0x000000000000003a4 0x00000000000003a4 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x000000000000001f0 0x00000000000001f0 R 1
Segment eşleme için Bölüm:
Segment Bölümleri…
00
01 .yorum
02 .yorum .Not.ABI etiketi .Not.gnu.yapı kimliği .gnu.karma .dinsim .dinstr .gnu.versiyon .gnu.sürüm_r .akraba.din .akraba.plt .içinde .plt .Metin .son .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dinamik .var .var.plt .veri .bss
04 .dinamik
05 .Not.ABI etiketi .Not.gnu.yapı kimliği
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dinamik .var

Bölüm Başlığı

ELF yapısının üçüncü kısmı bölüm başlığıdır. İkili dosyanın tek bölümlerini listelemek içindir. -S anahtarı (-section-headers veya -sections'ın kısaltması) farklı başlıkları listeler. Dokunma komutuna gelince, 27 bölüm başlığı vardır ve Liste 5 bunların ilk dördünü ve sonuncusunu gösterir, yalnızca. Her satır, bölüm boyutunu, bölüm türünü ve bunun yanı sıra adresi ve bellek ofsetini kapsar.

.Liste 5: Readelf tarafından açıklanan bölüm ayrıntıları

$ readelf -S /usr/bin/dokunma
0xe428 ofsetinden başlayan 27 bölüm başlığı vardır:
Bölüm Başlıkları:
[Nr] Ad Türü Adres Ofseti
Boyut EntSize Bayraklar Bağlantı Bilgisi Hizala
[ 0] BOŞ 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .Not.ABI etiketi NOT 0000000000400254 00000254
00000000000000020 0000000000000000 A 0 0 4
[ 3] .Not.gnu.yapı-i NOT 0000000000400274 00000274


[26] .shstrtab STRTAB 0000000000000000 0000e334
000000000000000ef 0000000000000000 0 0 1
Bayrakların Anahtarı:
W (yaz), A (ayır), X (yürüt), M (birleştir), S (dizeler), l (büyük)
I (bilgi), L (bağlantı sırası), G (grup), T (TLS), E (hariç), x (bilinmiyor)
O (işletim sistemi için ekstra işlem gerekir) o (işletim sistemine özel), p (işlemciye özel)

Bir ELF dosyasını Analiz etmek için Araçlar

Yukarıdaki örneklerden de fark etmiş olabileceğiniz gibi, GNU/Linux, bir ELF dosyasını analiz etmenize yardımcı olan bir dizi faydalı araçla donatılmıştır. Bakacağımız ilk aday dosya yardımcı programıdır.

dosyası, yeniden konumlandırılabilir, yürütülebilir veya paylaşılan bir nesne dosyasındaki kodun amaçlandığı komut kümesi mimarisi dahil olmak üzere ELF dosyaları hakkında temel bilgileri görüntüler. Liste 6'da /bin/touch'ın Linux Standard Base'i (LSB) takip eden, dinamik olarak bağlantılı ve GNU/Linux çekirdek sürüm 2 için oluşturulmuş 64 bitlik yürütülebilir bir dosya olduğunu söyler.6.32.

.Liste 6: Dosyayı kullanan temel bilgiler

$ dosya /bin/dokunma
/bin/touch: ELF 64-bit LSB yürütülebilir, x86-64, sürüm 1 (SYSV), dinamik olarak bağlı, yorumlayıcı /lib64/l,
GNU/Linux 2 için.6.32, BuildID[sha1]=ec08d609e9e8e73d4be6134541a472ad0ea34502, soyulmuş
$

İkinci aday readel. Bir ELF dosyası hakkında ayrıntılı bilgi görüntüler. Anahtar listesi nispeten uzundur ve ELF formatının tüm yönlerini kapsar. -n anahtarını kullanma (-notes'un kısaltması) Liste 7, yalnızca dosya dokunuşunda bulunan not bölümlerini gösterir - ABI sürüm etiketi ve yapı kimliği bit dizisi.

.Liste 7: Bir ELF dosyasının Seçili bölümlerini görüntüleyin

$ readelf -n /usr/bin/dokunma
0x00000020 uzunluğunda 0x00000254 dosya uzaklığında bulunan notları görüntüleme:
Sahip Veri boyutu Açıklama
GNU 0x00000010 NT_GNU_ABI_TAG (ABI sürüm etiketi)
İşletim Sistemi: Linux, ABI: 2.6.32
0x00000024 uzunluğunda 0x00000274 dosya uzaklığında bulunan notları görüntüleme:
Sahip Veri boyutu Açıklama
GNU 0x00000014 NT_GNU_BUILD_ID (benzersiz yapı kimliği bit dizisi)
Yapı Kimliği: ec08d609e9e8e73d4be6134541a472ad0ea34502

Solaris ve FreeBSD altında, elfdump [7] yardımcı programının readelf ile karşılık geldiğine dikkat edin. 2019 itibariyle, 2003'ten beri yeni bir sürüm veya güncelleme yapılmamıştır.

Üçüncüsü, tamamen Linux için kullanılabilen elfutils [6] adlı pakettir. GNU Binutils'e alternatif araçlar sağlar ve ayrıca ELF dosyalarının doğrulanmasına izin verir. Pakette sağlanan tüm yardımcı programların adlarının 'elf utils' için eu ile başladığını unutmayın.

Son olarak objdump'tan bahsedeceğiz. Bu araç readelf'e benzer ancak nesne dosyalarına odaklanır. ELF dosyaları ve diğer nesne biçimleri hakkında benzer bir bilgi yelpazesi sağlar.

.Liste 8: objdump tarafından ayıklanan dosya bilgileri

$ objdump -f /bin/dokunma
/bin/touch: dosya biçimi elf64-x86-64
mimari: i386:x86-64, 0x00000112 bayrakları:
EXEC_P, HAS_SYMS, D_PAGED
başlangıç ​​adresi 0x00000000004025e3
$

Ayrıca, bir ELF dosyasının içeriğini okumanın yanı sıra onu manipüle etmek için araçlar içeren 'elfkickers' [9] adlı bir yazılım paketi de vardır. Ne yazık ki, yayın sayısı oldukça azdır ve bu yüzden sadece bundan bahsediyoruz ve daha fazla örnek göstermiyoruz.

Bir geliştirici olarak bunun yerine 'pax-utils' [10,11]'e bakabilirsiniz. Bu yardımcı program seti, ELF dosyalarını doğrulamaya yardımcı olan bir dizi araç sağlar. Örnek olarak dumpelf, ELF dosyasını analiz eder ve ayrıntıları içeren bir C başlık dosyası döndürür - bkz. Şekil 2.

Sonuç

Akıllı tasarım ve mükemmel dokümantasyonun birleşimi sayesinde ELF formatı çok iyi çalışıyor ve 20 yıl sonra hala kullanılıyor. Yukarıda gösterilen yardımcı programlar, bir ELF dosyasına ilişkin bir içgörü görünümü sağlar ve bir programın ne yaptığını anlamanıza olanak tanır. Bunlar yazılımı analiz etmenin ilk adımlarıdır - mutlu bilgisayar korsanlığı!

Bağlantılar ve Referanslar
  • [1] Yürütülebilir ve Bağlanabilir Biçim (ELF), Wikipedia
  • [2] Fuşya İşletim Sistemi
  • [3] Yürütülebilir dosya biçimlerinin karşılaştırılması, Wikipedia
  • [4] Linux Vakfı, Başvurulan Özellikler
  • [5] Ciro Santilli: ELF Merhaba Dünya Eğitimi
  • [6] elfutils Debian paketi
  • [7] elf dökümü
  • [8] Michael Boelen: Linux'ta ELF dosyalarının 101'i: Anlama ve Analiz
  • [9] cinler
  • [10] Sertleştirilmiş/PaX Yardımcı Programları
  • [11] pax-utils, Debian paketi
Teşekkür

Yazar, bu makalenin hazırlanmasındaki desteği için Axel Beckert'e teşekkür eder.

OpenTTD Tutorial
OpenTTD is one of the most popular business simulation games out there. In this game, you need to create a wonderful transportation business. However,...
SuperTuxKart for Linux
SuperTuxKart is a great title designed to bring you the Mario Kart experience free of charge on your Linux system. It is pretty challenging and fun to...
Battle for Wesnoth Tutorial
The Battle for Wesnoth is one of the most popular open source strategy games that you can play at this time. Not only has this game been in developmen...