ELF

Razumevanje oblike zapisa datoteke ELF

Razumevanje oblike zapisa datoteke ELF

Od izvorne kode do binarne kode

Programiranje se začne s pametno idejo in pisanjem izvorne kode v izbrani programski jezik, na primer C, ter shranjevanjem izvorne kode v datoteko. S pomočjo ustreznega prevajalnika, na primer GCC, se vaša izvorna koda najprej prevede v objektno kodo. Sčasoma povezovalnik pretvori objektno kodo v binarno datoteko, ki poveže objektno kodo s referenčnimi knjižnicami. Ta datoteka vsebuje posamezna navodila kot strojno kodo, ki jih CPU razume in se izvajajo takoj, ko se zažene prevedeni program.

Zgoraj omenjena binarna datoteka sledi določeni strukturi, ena najpogostejših pa se imenuje ELF, ki okrajša izvedljivo in povezljivo obliko. Pogosto se uporablja za izvršljive datoteke, predmetne datoteke, ki jih je mogoče preseliti, knjižnice v skupni rabi in odlagališča jedra.

Pred dvajsetimi leti - leta 1999 - je projekt 86open izbral ELF kot standardni binarni format datotek za Unix in Unixu podobne sisteme na procesorjih x86. Na srečo je bila oblika ELF že dokumentirana tako v binarnem vmesniku aplikacije System V kot v orodju Standard Interface Tool [4]. To dejstvo je močno poenostavilo dogovor o standardizaciji med različnimi ponudniki in razvijalci operacijskih sistemov, ki temeljijo na Unixu.

Razlog za takšno odločitev je bila zasnova ELF - prilagodljivost, razširljivost in podpora med različnimi platformami za različne endian formate in velikosti naslovov. Zasnova ELF ni omejena na določen procesor, nabor navodil ali arhitekturo strojne opreme. Za podrobno primerjavo oblik izvršljivih datotek si oglejte tukaj [3].

Od takrat format ELF uporablja več različnih operacijskih sistemov. Med drugim to vključuje Linux, Solaris / Illumos, Free-, Net- in OpenBSD, QNX, BeOS / Haiku in Fuchsia OS [2]. Poleg tega ga boste našli v mobilnih napravah z operacijskim sistemom Android, Maemo ali Meego OS / Sailfish OS, pa tudi na igralnih konzolah, kot so PlayStation Portable, Dreamcast in Wii.

Specifikacija ne pojasnjuje končnice imena datoteke za datoteke ELF. V uporabi so različne kombinacije črk, kot so .axf, .zabojnik, .elf, .o, .prx, .puff, .ko, .tako, in .mod ali noben.

Struktura datoteke ELF

V terminalu za Linux vam ukaz man elf pripravi priročen povzetek o strukturi datoteke ELF:

Seznam 1: Stran strani ELF strukture

$ moški elf
ELF (5) Navodila za programerja za Linux ELF (5)
NAME
elf - oblika datotek izvršljivega in povezovalnega formata (ELF)
POVZETEK
#include
OPIS
Datoteka glave definira obliko izvršljive binarne datoteke ELF
datotek. Med temi datotekami so običajne izvedljive datoteke, ki jih je mogoče preseliti
objektne datoteke, jedrne datoteke in knjižnice v skupni rabi.
Izvršljiva datoteka, ki uporablja format datoteke ELF, je sestavljena iz glave ELF,
čemur sledi tabela glave programa ali tabela glav odsekov ali oboje.
Glava ELF je vedno v odmiku nič od datoteke. Program
tabela glave in odmik tabele glave odseka v datoteki sta
opredeljeno v glavi ELF. Dve tabeli opisujeta preostali del
posebnosti datoteke.
..

Kot lahko vidite iz zgornjega opisa, je datoteka ELF sestavljena iz dveh odsekov - glave ELF in podatkov datoteke. Odsek s podatki o datoteki je lahko sestavljen iz tabele z glavo programa, ki opisuje nič ali več segmentov, tabele z glavo odseka, ki opisuje nič ali več odsekov, ki ji sledijo podatki, na katere se nanašajo vnosi iz tabele z glavo programa, in tabele z glavo razdelka. Vsak segment vsebuje informacije, ki so potrebne za izvajanje datoteke, medtem ko odseki vsebujejo pomembne podatke za povezovanje in premestitev. Slika 1 shematsko ponazarja to.

Glava ELF

Glava ELF je dolga 32 bajtov in določa obliko datoteke. Začne se z zaporedjem štirih enoličnih bajtov, ki so 0x7F, čemur sledijo 0x45, 0x4c in 0x46, kar se prevede v tri črke E, L in F. Med drugimi vrednostmi glava tudi navaja, ali gre za datoteko ELF za 32- ali 64-bitno obliko, uporablja malo ali veliko endianness, prikazuje različico ELF in za kateri operacijski sistem je bila datoteka prevedena, da bi lahko sodelovala z desni binarni vmesnik aplikacije (ABI) in nabor navodil CPU.

Hexdump binarne datoteke na dotik izgleda tako:

.Seznam 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 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 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-pošta zaščitena] @… |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 | [e-pošta zaščitena] |

Debian GNU / Linux ponuja ukaz readelf, ki je na voljo v paketu GNU 'binutils'. Skupaj s stikalom -h (kratka različica za "-file-header") lepo prikaže glavo datoteke ELF. Navedba 3 to ponazarja za ukaz touch.

.Navedba 3: Prikaz glave datoteke ELF

$ readelf -h / usr / bin / touch
Glava ELF:
Magija: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Razred: ELF64
Podatki: dopolnilo 2, malo endian
Različica: 1 (trenutno)
OS / ABI: UNIX - sistem V
Različica ABI: 0
Tip: EXEC (izvršljiva datoteka)
Naprava: Napredne mikro naprave X86-64
Različica: 0x1
Naslov vstopne točke: 0x4025e3
Začetek glave programa: 64 (bajtov v datoteko)
Začetki glav odsekov: 58408 (bajti v datoteko)
Zastave: 0x0
Velikost te glave: 64 (bajtov)
Velikost glav programov: 56 (bajtov)
Število glav programov: 9
Velikost glav odsekov: 64 (bajtov)
Število glav odsekov: 27
Kazalo tabele nizov glave odseka: 26

Glava programa

Glava programa prikazuje segmente, ki se uporabljajo med izvajanjem, in sistemu sporoča, kako ustvariti sliko procesa. Glava iz seznama 2 kaže, da je datoteka ELF sestavljena iz 9 programskih glav, ki imajo velikost 56 bajtov, prva glava pa se začne pri bajtu 64.

Spet ukaz readelf pomaga pri pridobivanju informacij iz datoteke ELF. Stikalo -l (kratica za -programske glave ali -segmenti) razkrije več podrobnosti, kot je prikazano v seznamu 4.

.Seznam 4: Prikažite informacije o glavah programa

$ readelf -l / usr / bin / touch
Vrsta datoteke Elf je EXEC (izvršljiva datoteka)
Vstopna točka 0x4025e3
Obstaja 9 glav programov, ki se začnejo z odmikom 64
Glave programov:
Vnesite Offset VirtAddr PhysAddr
FileSiz MemSiz Zastave poravnaj
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Zahteva tolmača programa: / lib64 / ld-linux-x86-64.torej.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
LOAD 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DINAMIČNI 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
OPOMBA 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x000000000000bc40 0x000000000040bc40 0x000000000040bc40
0x00000000000003a4 0x00000000000003a4 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x00000000000001f0 0x00000000000001f0 R 1
Preslikava odsekov do segmentov:
Segmentiraj odseke…
00
01 .interp
02 .interp .Opomba.Oznaka ABI .Opomba.gnu.build-id .gnu.hash .dinzim .dynstr .gnu.različico .gnu.različica_r .rela.dyn .rela.plt .v .plt .besedilo .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dinamično .dobil .dobil.plt .podatkov .bss
04 .dinamično
05 .Opomba.Oznaka ABI .Opomba.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dinamično .dobil

Glava odseka

Tretji del strukture ELF je glava odseka. Namenjen je seznamu posameznih odsekov binarnega elementa. Stikalo -S (okrajšava za -section-headers ali -sections) našteva različne glave. Kar zadeva ukaz na dotik, obstaja 27 glav odsekov, na seznamu 5 pa so prikazani samo prvi štirje in zadnji. Vsaka vrstica zajema velikost odseka, vrsto odseka ter njegov naslov in odmik pomnilnika.

.Seznam 5: Podrobnosti o odsekih, ki jih je razkril readelf

$ readelf -S / usr / bin / touch
Obstaja 27 glav odsekov, ki se začnejo z zamikom 0xe428:
Glave odsekov:
[Nr] Ime Vrsta Naslov Odmik
Velikost EntSize Zastave Povezava Informacije Poravnaj
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .Opomba.ABI-tag OPOMBA 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .Opomba.gnu.build-i OPOMBA 0000000000400274 00000274
..
..
[26] .shstrtab STRTAB 0000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Ključ do zastav:
W (pisanje), A (dodeljevanje), X (izvajanje), M (spajanje), S (nizi), l (veliko)
I (informacije), L (vrstni red povezav), G (skupina), T (TLS), E (izključi), x (neznano)
O (potrebna dodatna obdelava OS) o (specifično za OS), p (specifično za procesor)

Orodja za analizo datoteke ELF

Kot ste morda opazili iz zgornjih primerov, je GNU / Linux opremljen s številnimi uporabnimi orodji, ki vam pomagajo analizirati datoteko ELF. Prvi kandidat, ki si ga bomo ogledali, je pripomoček za datoteke.

datoteka prikazuje osnovne informacije o datotekah ELF, vključno z arhitekturo nabora ukazov, ki ji je namenjena koda v premestljivi, izvedljivi ali predmetni datoteki v skupni rabi. V seznamu 6 vam pove, da je / bin / touch 64-bitna izvedljiva datoteka, ki sledi Linux Standard Base (LSB), dinamično povezana in zgrajena za jedro GNU / Linux različice 2.6.32.

.Seznam 6: Osnovne informacije z uporabo datoteke

$ file / bin / touch
/ bin / touch: ELF 64-bitna izvedljiva LSB, x86-64, različica 1 (SYSV), dinamično povezana, tolmač / lib64 / l,
za GNU / Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, odstranjen
$

Drugi kandidat je prebral. Prikaže podrobne informacije o datoteki ELF. Seznam stikal je primerljivo dolg in zajema vse vidike formata ELF. Uporaba stikala -n (kratica za -notes) V seznamu 7 so prikazani samo odseki opomb, ki obstajajo v dotiku datoteke - oznaka različice ABI in bitstring ID-ja gradnje.

.Seznam 7: Prikaži izbrane odseke datoteke ELF

$ readelf -n / usr / bin / touch
Prikaz opomb, najdenih pri odmiku datoteke 0x00000254 z dolžino 0x00000020:
Lastnik Velikost podatkov Opis
GNU 0x00000010 NT_GNU_ABI_TAG (oznaka različice ABI)
OS: Linux, ABI: 2.6.32
Prikaz opomb, najdenih pri odmiku datoteke 0x00000274 z dolžino 0x00000024:
Lastnik Velikost podatkov Opis
GNU 0x00000014 NT_GNU_BUILD_ID (bitni niz unikatnega ID-ja gradnje)
ID gradnje: ec08d609e9e8e73d4be6134541a472ad0ea34502

Upoštevajte, da pri Solarisu in FreeBSD pripomoček elfdump [7] ustreza readelf. Od leta 2019 ni bilo nove izdaje ali posodobitve od leta 2003.

Tretja številka je paket z imenom elfutils [6], ki je povsem na voljo za Linux. Ponuja alternativna orodja za GNU Binutils in omogoča tudi preverjanje datotek ELF. Upoštevajte, da se vsa imena pripomočkov v paketu začnejo z eu za "elf utils".

Nenazadnje bomo omenili objdump. To orodje je podobno kot readelf, vendar se osredotoča na predmetne datoteke. Ponuja podobno vrsto informacij o datotekah ELF in drugih oblikah objektov.

.Seznam 8: Informacije o datoteki, ki jih je izdal objdump

$ objdump -f / bin / touch
/ bin / touch: oblika datoteke elf64-x86-64
arhitektura: i386: x86-64, zastave 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
začetni naslov 0x00000000004025e3
$

Obstaja tudi programski paket, imenovan "elfkickers" [9], ki vsebuje orodja za branje vsebine datoteke ELF in njeno manipulacijo. Na žalost je število izdaj precej majhno, zato ga samo omenimo in ne prikazujemo nadaljnjih primerov.

Kot razvijalec boste morda namesto tega pogledali 'pax-utils' [10,11]. Ta nabor pripomočkov ponuja številna orodja, ki pomagajo pri preverjanju veljavnosti datotek ELF. Kot primer dumpelf analizira datoteko ELF in vrne datoteko glave C, ki vsebuje podrobnosti - glej sliko 2.

Zaključek

Zahvaljujoč kombinaciji pametnega oblikovanja in odlične dokumentacije format ELF deluje zelo dobro in je po 20 letih še vedno v uporabi. Zgornji pripomočki vam omogočajo vpogled v datoteko ELF in vam omogočajo, da ugotovite, kaj program počne. To so prvi koraki za analizo programske opreme - srečno vdiranje!

Povezave in reference
  • [1] Izvedljiva in povezljiva oblika (ELF), Wikipedia
  • [2] Fuchsia OS
  • [3] Primerjava oblik izvršljivih datotek, Wikipedia
  • [4] Linux Foundation, referenčne specifikacije
  • [5] Ciro Santilli: Vadnica ELF Hello World
  • [6] paket elfutils Debian
  • [7] elfdump
  • [8] Michael Boelen: 101 datoteka ELF v Linuxu: Razumevanje in analiza
  • [9] elfkickers
  • [10] Utrjene / PaX pripomočki
  • [11] pax-utils, paket Debian
Zahvala

Pisatelj se zahvaljuje Axelu Beckertu za podporo pri pripravi tega članka.

OpenTTD vs Simutrans
Ustvarjanje lastne simulacije prevoza je lahko zabavno, sproščujoče in izjemno vabljivo. Zato morate preizkusiti čim več iger, da boste našli tisto, k...
Vadnica za OpenTTD
OpenTTD je ena izmed najbolj priljubljenih poslovnih simulacijskih iger. V tej igri morate ustvariti čudovit prevozniški posel. Vendar boste začeli na...
SuperTuxKart za Linux
SuperTuxKart je odličen naslov, zasnovan tako, da vam brezplačno ponuja izkušnjo Mario Kart v vašem sistemu Linux. Igrati je precej zahtevno in zabavn...