Razumijevanje formata datoteke ELF

Understanding Elf File Format



Od izvornog koda do binarnog koda

Programiranje započinje pametnom idejom i pisanjem izvornog koda u programskom jeziku po vašem izboru, na primjer C, te spremanjem izvornog koda u datoteku. Uz pomoć odgovarajućeg prevoditelja, na primjer GCC -a, vaš izvorni kod prvo se prevodi u objektni kod. Na kraju povezivač prevodi objektni kod u binarnu datoteku koja povezuje kod objekta s referenciranim knjižnicama. Ova datoteka sadrži pojedinačne upute kao strojni kod koje CPU razumije, a izvršavaju se čim se pokrene prevedeni program.

Gore spomenuta binarna datoteka slijedi specifičnu strukturu, a jedna od najčešćih naziva se ELF koja skraćuje izvršni i povezivi format. Široko se koristi za izvršne datoteke, datoteke objekata koje se mogu premjestiti, zajedničke knjižnice i dumpove jezgre.







Prije dvadeset godina-1999.-projekt 86open odabrao je ELF kao standardni binarni format datoteke za Unix i Unix slične sustave na x86 procesorima. Srećom, format ELF je prethodno dokumentiran i u aplikacijskom binarnom sučelju System V i u standardu sučelja alata [4]. Ova je činjenica iznimno pojednostavila sporazum o standardizaciji između različitih dobavljača i programera operativnih sustava temeljenih na Unixu.



Razlog za tu odluku bio je dizajn ELF-a-fleksibilnost, proširivost i podrška za više platformi za različite endijanske formate i veličine adresa. Dizajn ELF -a nije ograničen na određeni procesor, skup uputa ili hardversku arhitekturu. Za detaljnu usporedbu izvršnih formata datoteka, pogledajte ovdje [3].



Od tada, format ELF koristi nekoliko različitih operativnih sustava. Između ostalog, ovo uključuje Linux, Solaris/Illumos, Free-, Net- i OpenBSD, QNX, BeOS/Haiku i Fuchsia OS [2]. Nadalje, naći ćete ga na mobilnim uređajima sa sustavom Android, Maemo ili Meego OS/Sailfish OS, kao i na igraćim konzolama poput PlayStation Portable, Dreamcast i Wii.





Specifikacija ne pojašnjava nastavak naziva datoteke za ELF datoteke. U upotrebi su različite kombinacije slova, kao što su .axf, .bin, .elf, .o, .prx, .puff, .ko, .so i .mod, ili ništa.

Struktura ELF datoteke

Na Linux terminalu naredba man elf daje vam zgodan sažetak o strukturi ELF datoteke:



Popis 1: Stranica korisnika ELF strukture

$ čovjek jedanaest

ELF (5) Priručnik za programere za Linux ELF (5)

IME
elf - format datoteka izvršnog i povezujućeg formata (ELF)

SINOPSIS
#uključi

OPIS
Zaglavna datoteka definira format izvršne binarne datoteke ELF
datoteke. Među tim datotekama su normalne izvršne datoteke koje se mogu premjestiti
objektne datoteke, osnovne datoteke i zajedničke knjižnice.

Izvršna datoteka koja koristi format datoteke ELF sastoji se od zaglavlja ELF,
slijedi tablica zaglavlja programa ili tablica zaglavlja odjeljka, ili oboje.
Zaglavlje ELF uvijek je na nuli pomaka datoteke. Program
tablica zaglavlja i pomak tablice zaglavlja odjeljka u datoteci su
definirano u ELF zaglavlju. Dvije tablice opisuju ostatak
posebnosti datoteke.

...

Kao što možete vidjeti iz gornjeg opisa, ELF datoteka se sastoji od dva odjeljka - ELF zaglavlja i podataka datoteke. Odjeljak s podacima o datoteci može se sastojati od tablice zaglavlja programa koja opisuje nulu ili više segmenata, tablice zaglavlja odjeljka koja opisuje nulu ili više odjeljaka, iza koje slijede podaci na koje se upućuju unosi iz tablice zaglavlja programa i tablice zaglavlja odjeljka. Svaki segment sadrži informacije koje su potrebne za izvršavanje datoteke tijekom izvođenja, dok odjeljci sadrže važne podatke za povezivanje i premještanje. Slika 1 to shematski prikazuje.

Zaglavlje ELF

ELF zaglavlje ima 32 bajta i identificira format datoteke. Počinje nizom od četiri jedinstvena bajta koji su 0x7F nakon čega slijede 0x45, 0x4c i 0x46 koji se prevodi u tri slova E, L i F. Između ostalih vrijednosti, zaglavlje također označava radi li se o ELF datoteci za 32 ili 64-bitni format, koristi malo ili veliko endianness, prikazuje verziju ELF-a, kao i za koji je operacijski sustav datoteka kompilirana kako bi radila s odgovarajućim aplikacijskim binarnim sučeljem (ABI) i skupom uputa za procesor.

Hexdump dodira binarne datoteke izgleda ovako:

.Listing 2: Hexdump binarne datoteke

$ hd/usr/bin/touch | glava -5
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 | .SAM ........... |
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 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 | [zaštićena e -pošta] @..... |
00000040 06 00 00 00 05 00 00 40 00 00 00 00 00 00 00 | [zaštićena e -pošta] |

Debian GNU/Linux nudi naredbu readelf koja se nalazi u GNU -ovom paketu 'binutils'. U pratnji prekidača -h (kratka verzija za –file -header) lijepo prikazuje zaglavlje ELF datoteke. Popis 3 prikazuje ovo za naredbu touch.

.Listing 3: Prikaz zaglavlja ELF datoteke

$ readelf -h/usr/bin/touch
ELF zaglavlje:
Čarolija: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klasa: ELF64
Podaci: 2 komplementa, mali endijan
Verzija: 1 (trenutna)
OS / ABI: UNIX - sustav V
ABI verzija: 0
Vrsta: EXEC (izvršna datoteka)
Stroj: Napredni mikro uređaji X86-64
Verzija: 0x1
Adresa ulaznog mjesta: 0x4025e3
Početak zaglavlja programa: 64 (bajtova u datoteku)
Početak zaglavlja odjeljka: 58408 (bajtova u datoteku)
Zastave: 0x0
Veličina ovog zaglavlja: 64 (bajta)
Veličina zaglavlja programa: 56 (bajtova)
Broj zaglavlja programa: 9
Veličina zaglavlja odjeljaka: 64 (bajtova)
Broj zaglavlja odjeljaka: 27
Indeks tablice nizova zaglavlja odjeljka: 26

Zaglavlje programa

Zaglavlje programa prikazuje segmente korištene za vrijeme izvođenja i govori sustavu kako izraditi sliku procesa. Zaglavlje iz Popisa 2 pokazuje da se ELF datoteka sastoji od 9 programskih zaglavlja koja imaju veličinu po 56 bajta, a prvo zaglavlje počinje od 64 bajta.

Opet, naredba readelf pomaže izvući podatke iz ELF datoteke. Prekidač -l (skraćeno od –programska zaglavlja ili –segmenti) otkriva više detalja kako je prikazano u popisu 4.

.Listing 4: Prikaz informacija o zaglavljima programa

$ readelf -l/usr/bin/touch

Elf vrsta datoteke je EXEC (izvršna datoteka)
Ulazna točka 0x4025e3
Postoji 9 zaglavlja programa, počevši od pomaka 64

Zaglavlja programa:
Upišite Offset VirtAddr PhysAddr
FileSiz MemSiz zastavice Poravnajte
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Traženje programskog tumača: /lib64/ld-linux-x86-64.so.2]
UČITAJ 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
UČITAJ 0x000000000000de10 0x00000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMIC 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
NAPOMENA 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x000000000000bc40 0x000000000040bc40 0x00000000004040bc40
0x00000000000003a4 0x00000000000003a4 R 4
GNU_STACK 0x0000000000000000 0x000000000000000000 0x0000000000000000
0x000000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x00000000000001f0 0x00000000000001f0 R 1

Mapiranje odjeljka u segment:
Odjeljci segmenata ...
00
01 .prekid
02 .interp .nota.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini. rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
04 .dinamički
05 .bilješka.ABI-oznaka .bilješka.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dinamički .got

Zaglavlje odjeljka

Treći dio strukture ELF -a je zaglavlje odjeljka. Namijenjen je popisu pojedinačnih odjeljaka binarnog fajla. Prekidač -S (skraćeno od –section -headers ili –sections) navodi različita zaglavlja. Što se tiče naredbe za dodir, postoji 27 zaglavlja odjeljaka, a u popisu 5 prikazana su samo prva četiri i samo posljednje. Svaki redak obuhvaća veličinu odjeljka, vrstu odjeljka, kao i njegovu adresu i pomak memorije.

.Listing 5: Readelf otkriva pojedinosti odjeljka

$ readelf -S/usr/bin/touch
Postoji 27 zaglavlja odjeljaka, počevši od pomaka 0xe428:

Zaglavlja odjeljaka:
[Br] Naziv Vrsta Adresa Pomak
Veličina EntSize zastavice Podaci o vezi Poravnajte
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interpcijski ZDRAVCI 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .bilješka.ABI-oznaka NAPOMENA 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .nota.gnu.build-i NAPOMENA 0000000000400274 00000274
...
...
[26] .shstrtab STRTAB 000000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Ključ do zastava:
W (upisivanje), A (alociranje), X (izvršavanje), M (spajanje), S (nizovi), l (veliko)
I (info), L (redoslijed povezivanja), G (grupa), T (TLS), E (isključuje), x (nepoznato)
O (potrebna dodatna obrada OS -a) o (specifična za OS), p (specifična za procesor)

Alati za analizu ELF datoteke

Kao što ste možda primijetili iz gornjih primjera, GNU/Linux je obogaćen brojnim korisnim alatima koji vam pomažu u analizi ELF datoteke. Prvi kandidat kojeg ćemo pogledati je uslužni program za datoteke.

file prikazuje osnovne informacije o ELF datotekama, uključujući arhitekturu skupa uputa za koju je namijenjen kôd u datoteci koja se može premjestiti, izvršiti ili podijeliti. U popisu 6 govori vam da je/bin/touch 64-bitna izvršna datoteka koja slijedi Linux Standard Base (LSB), dinamički povezana i izrađena za verziju jezgre GNU/Linux 2.6.32.

.Listing 6: Osnovni podaci pomoću datoteke

$ file /bin /touch
/bin/touch: ELF 64-bitna LSB izvršna datoteka, x86-64, verzija 1 (SYSV), dinamički povezana, tumač/lib64/l,
za GNU/Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, uklonjen
$

Drugi kandidat se čita sam. Prikazuje detaljne informacije o datoteci ELF. Popis sklopki je usporedivo dugačak i pokriva sve aspekte ELF formata. Upotrebom prekidača -n (skraćeno od –notes) Popis 7 prikazuje samo odjeljke bilješki koji postoje u dodirnoj datoteci -oznaku verzije ABI -a i niz bitova ID -a gradnje.

.Listing 7: Prikaz odabranih odjeljaka ELF datoteke

$ readelf -n/usr/bin/touch

Bilješke prikazane na pomaku datoteke 0x00000254 duljine 0x00000020:
Vlasnik Veličina podataka Opis
GNU 0x00000010 NT_GNU_ABI_TAG (oznaka inačice ABI)
OS: Linux, ABI: 2.6.32

Bilješke prikazane na pomaku datoteke 0x00000274 duljine 0x00000024:
Vlasnik Veličina podataka Opis
GNU 0x00000014 NT_GNU_BUILD_ID (jedinstveni niz bitova ID -a gradnje)
ID međuverzije: ec08d609e9e8e73d4be6134541a472ad0ea34502

Imajte na umu da pod Solarisom i FreeBSD -om uslužni program elfdump [7] odgovara readelf. Od 2019. nije bilo novog izdanja ili ažuriranja od 2003. godine.

Treći je paket pod nazivom elfutils [6] koji je čisto dostupan za Linux. Pruža alternativne alate GNU Binutilsima, a također dopušta provjeru valjanosti ELF datoteka. Imajte na umu da svi nazivi pomoćnih programa navedenih u paketu počinju s eu za 'elf utils'.

Na kraju ćemo spomenuti objdump. Ovaj je alat sličan readelfu, ali se fokusira na objektne datoteke. Pruža sličan raspon informacija o ELF datotekama i drugim formatima objekata.

.Listing 8: Podaci o datoteci izvučeni od strane objdump

$ objdump -f /bin /touch

/bin/touch: format datoteke elf64-x86-64
arhitektura: i386: x86-64, zastavice 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
početna adresa 0x00000000004025e3

$

Postoji i softverski paket pod nazivom 'elfkickers' [9] koji sadrži alate za čitanje sadržaja ELF datoteke, kao i za rukovanje njome. Nažalost, broj izdanja je prilično mali, pa ga zato samo spominjemo, a ne prikazujemo daljnje primjere.

Kao programer, umjesto toga možete pogledati 'pax-utils' [10,11]. Ovaj skup uslužnih programa pruža niz alata koji pomažu u provjeri valjanosti ELF datoteka. Kao primjer, dumpelf analizira datoteku ELF i vraća datoteku zaglavlja C koja sadrži pojedinosti - vidi sliku 2.

Zaključak

Zahvaljujući kombinaciji pametnog dizajna i izvrsne dokumentacije, ELF format radi vrlo dobro, a i dalje se koristi nakon 20 godina. Gore prikazani uslužni programi omogućuju vam uvid u ELF datoteku i omogućuju vam da shvatite što program radi. Ovo su prvi koraci za analizu softvera - sretno hakiranje!

Linkovi i reference
Zahvalnice

Pisac se zahvaljuje Axelu Beckertu na podršci u pripremi ovog članka.