ELF

Porozumění formátu souboru ELF

Porozumění formátu souboru ELF

Od zdrojového kódu po binární kód

Programování začíná chytrým nápadem a napsáním zdrojového kódu v programovacím jazyce podle vašeho výběru, například C, a uložením zdrojového kódu do souboru. S pomocí vhodného kompilátoru, například GCC, je váš zdrojový kód nejprve přeložen do objektového kódu. Nakonec linker přeloží kód objektu do binárního souboru, který propojí kód objektu s odkazovanými knihovnami. Tento soubor obsahuje jednotlivé instrukce jako strojový kód, kterým procesor rozumí a jsou provedeny, jakmile je spuštěn kompilovaný program.

Výše uvedený binární soubor sleduje konkrétní strukturu a jeden z nejběžnějších je pojmenován ELF, který zkracuje formát spustitelného a spojitelného formátu. Je široce používán pro spustitelné soubory, soubory přemístitelných objektů, sdílené knihovny a základní skládky.

Před dvaceti lety - v roce 1999 - si projekt 86open vybral ELF jako standardní formát binárního souboru pro Unix a systémy podobné Unixu na procesorech x86. Naštěstí byl formát ELF dříve dokumentován jak v binárním rozhraní aplikace System V, tak ve standardu rozhraní nástroje [4]. Tato skutečnost nesmírně zjednodušila dohodu o standardizaci mezi různými prodejci a vývojáři operačních systémů založených na Unixu.

Důvodem tohoto rozhodnutí byl návrh ELF - flexibilita, rozšiřitelnost a podpora různých platforem pro různé formáty endian a velikosti adres. Návrh ELF se neomezuje na konkrétní procesor, instrukční sadu nebo hardwarovou architekturu. Podrobné srovnání formátů spustitelných souborů naleznete zde [3].

Od té doby formát ELF používá několik různých operačních systémů. To mimo jiné zahrnuje Linux, Solaris / Illumos, Free-, Net- a OpenBSD, QNX, BeOS / Haiku a Fuchsia OS [2]. Dále jej najdete na mobilních zařízeních se systémem Android, Maemo nebo Meego OS / Sailfish OS a také na herních konzolách jako PlayStation Portable, Dreamcast a Wii.

Specifikace neobjasňuje příponu názvu souboru pro soubory ELF. Používá se celá řada kombinací písmen, například .axf, .zásobník, .Elf, .Ó, .prx, .obláček, .ko, .ano, a .mod, nebo žádný.

Struktura souboru ELF

Na terminálu Linux vám příkaz man elf poskytne užitečné shrnutí struktury souboru ELF:

Výpis 1: Stránka struktury ELF

$ man elf
ELF (5) Linux Programmer's Manual ELF (5)
NÁZEV
elf - formát spustitelného a spojovacího formátu (ELF)
SYNOPSE
#zahrnout
POPIS
Hlavičkový soubor definuje formát spustitelného binárního souboru ELF
soubory. Mezi těmito soubory jsou normální spustitelné soubory, přemístitelné
objektové soubory, základní soubory a sdílené knihovny.
Spustitelný soubor ve formátu souboru ELF se skládá z hlavičky ELF,
následuje tabulka záhlaví programu nebo tabulka záhlaví sekce nebo obojí.
Záhlaví ELF je vždy na offsetu nula souboru. Program
tabulka záhlaví a posunutí tabulky záhlaví sekce v souboru jsou
definované v hlavičce ELF. Tyto dvě tabulky popisují zbytek
zvláštnosti souboru.

Jak vidíte z výše uvedeného popisu, soubor ELF se skládá ze dvou částí - hlavičky ELF a dat souboru. Sekce datových souborů může sestávat z tabulky záhlaví programu popisující nula nebo více segmentů, tabulky záhlaví sekce popisující nula nebo více sekcí, za kterou následují data, na která odkazují položky z tabulky záhlaví programu, a tabulky záhlaví sekce. Každý segment obsahuje informace, které jsou nezbytné pro spuštění souboru za běhu, zatímco oddíly obsahují důležitá data pro propojení a přemístění. Obrázek 1 to schematicky ilustruje.

Záhlaví ELF

Záhlaví ELF je 32 bajtů dlouhé a identifikuje formát souboru. Začíná to sekvencí čtyř jedinečných bajtů, které jsou 0x7F následované 0x45, 0x4c a 0x46, což se promítá do tří písmen E, L a F. Mezi jinými hodnotami záhlaví také označuje, zda se jedná o soubor ELF pro 32 nebo 64bitový formát, používá malou nebo velkou endianness, zobrazuje verzi ELF a také pro jaký operační systém byl soubor zkompilován za účelem spolupráce s pravé aplikační binární rozhraní (ABI) a sada instrukcí CPU.

Hexdump dotyku binárního souboru vypadá takto:

.Výpis 2: Hexdump binárního souboru

$ hd / usr / bin / touch | hlava -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 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 | [chráněno e-mailem] @… |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 | [chráněno e-mailem] |

Debian GNU / Linux nabízí příkaz readelf, který je poskytován v balíčku GNU 'binutils'. V doprovodu přepínače -h (zkrácená verze pro „-file-header“) pěkně zobrazí hlavičku souboru ELF. Výpis 3 to ilustruje pro příkazový dotek.

.Výpis 3: Zobrazení záhlaví souboru ELF

$ readelf -h / usr / bin / touch
Záhlaví ELF:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Třída: ELF64
Data: Doplněk 2, malý endian
Verze: 1 (aktuální)
OS / ABI: UNIX - Systém V
Verze ABI: 0
Typ: EXEC (spustitelný soubor)
Stroj: Advanced Micro Devices X86-64
Verze: 0x1
Adresa vstupního bodu: 0x4025e3
Začátek záhlaví programu: 64 (bajtů do souboru)
Začátek záhlaví sekce: 58408 (bajtů do souboru)
Vlajky: 0x0
Velikost této hlavičky: 64 (bajtů)
Velikost záhlaví programu: 56 (bajtů)
Počet záhlaví programu: 9
Velikost záhlaví sekcí: 64 (bajtů)
Počet záhlaví sekcí: 27
Index tabulky řetězců záhlaví sekce: 26

Záhlaví programu

Záhlaví programu zobrazuje segmenty použité za běhu a říká systému, jak vytvořit obraz procesu. Záhlaví ze seznamu 2 ukazuje, že soubor ELF se skládá z 9 záhlaví programu, které mají každý velikost 56 bajtů, a první záhlaví začíná na bajtu 64.

Příkaz readelf opět pomáhá extrahovat informace ze souboru ELF. Přepínač -l (zkratka pro -záhlaví programu nebo -segmenty) odhalí další podrobnosti, jak je uvedeno v seznamu 4.

.Výpis 4: Zobrazí informace o hlavičkách programů

$ readelf -l / usr / bin / touch
Typ souboru elfů je EXEC (spustitelný soubor)
Vstupní bod 0x4025e3
K dispozici je 9 záhlaví programů, počínaje offsetem 64
Záhlaví programu:
Typ Offset VirtAddr PhysAddr
FileSiz MemSiz příznaky zarovnat
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Žádající programový tlumočník: / lib64 / ld-linux-x86-64.tak.2]
ZATÍŽENÍ 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
ZATÍŽENÍ 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMICKÉ 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
POZNÁMKA 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
Mapování řezů do segmentů:
Segmentové sekce ..
00
01 .interp
02 .interp .Poznámka.Značka ABI .Poznámka.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.verze .gnu.verze_r .rela.dyn .rela.plt .inic .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dynamický .mám .mám.plt .data .bss
04 .dynamický
05 .Poznámka.Značka ABI .Poznámka.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamický .mám

Záhlaví sekce

Třetí částí struktury ELF je záhlaví sekce. Je určen k vypsání jednotlivých částí binárního souboru. Přepínač -S (zkratka pro -section-headers or -sections) uvádí různé záhlaví. Pokud jde o dotykový příkaz, existuje 27 záhlaví oddílů a Výpis 5 zobrazuje první čtyři z nich plus poslední, pouze. Každý řádek pokrývá velikost sekce, typ sekce i její adresu a offset paměti.

.Výpis 5: Podrobnosti sekce odhalil sám

$ readelf -S / usr / bin / touch
Existuje 27 hlaviček sekcí, počínaje offsetem 0xe428:
Záhlaví sekcí:
[Nr] Název Typ Adresa Odsazení
Velikost Příznaky Velikost Odkaz Informace Zarovnat
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .Poznámka.Značka ABI POZNÁMKA 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .Poznámka.gnu.build-i POZNÁMKA 0000000000400274 00000274


[26] .shstrtab STRTAB 0000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Klíč k vlajkám:
W (zápis), A (přidělení), X (provedení), M (sloučení), S (řetězce), l (velký)
I (informace), L (pořadí odkazů), G (skupina), T (TLS), E (vyloučit), x (neznámé)
O (je vyžadováno další zpracování OS) o (specifické pro OS), p (specifické pro procesor)

Nástroje pro analýzu souboru ELF

Jak jste si mohli všimnout z výše uvedených příkladů, GNU / Linux je doplněn řadou užitečných nástrojů, které vám pomohou analyzovat soubor ELF. Prvním kandidátem, na kterého se podíváme, je obslužný program souborů.

soubor zobrazuje základní informace o souborech ELF, včetně architektury instrukční sady, pro kterou je kód v přemístitelném, spustitelném nebo sdíleném objektu určen. V seznamu 6 vám říká, že / bin / touch je 64bitový spustitelný soubor podle Linux Standard Base (LSB), dynamicky propojený a vytvořený pro jádro GNU / Linux verze 2.6.32.

.Výpis 6: Základní informace pomocí souboru

$ file / bin / touch
/ bin / touch: ELF 64bitový LSB spustitelný, x86-64, verze 1 (SYSV), dynamicky propojený, tlumočník / lib64 / l,
pro GNU / Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, odstraněno
$

Druhým kandidátem je sám sebe. Zobrazuje podrobné informace o souboru ELF. Seznam přepínačů je srovnatelně dlouhý a zahrnuje všechny aspekty formátu ELF. Použití přepínače -n (zkratka pro -notes) Výpis 7 zobrazuje pouze sekce poznámek, které existují v dotyku souboru - tag verze ABI a bitstring ID sestavení.

.Výpis 7: Zobrazit vybrané části souboru ELF

$ readelf -n / usr / bin / touch
Zobrazení poznámek nalezených v offsetu souboru 0x00000254 s délkou 0x00000020:
Vlastník Velikost dat Popis
GNU 0x00000010 NT_GNU_ABI_TAG (značka verze ABI)
OS: Linux, ABI: 2.6.32
Zobrazení poznámek nalezených v offsetu souboru 0x00000274 s délkou 0x00000024:
Vlastník Velikost dat Popis
GNU 0x00000014 NT_GNU_BUILD_ID (jedinečný bitstring ID sestavení)
ID sestavení: ec08d609e9e8e73d4be6134541a472ad0ea34502

Všimněte si, že v systémech Solaris a FreeBSD odpovídá nástroj elfdump [7] readelf. Od roku 2019 od roku 2003 nedošlo k novému vydání nebo aktualizaci.

Číslo tři je balíček s názvem elfutils [6], který je čistě dostupný pro Linux. Poskytuje alternativní nástroje k GNU Binutils a také umožňuje ověřovat soubory ELF. Všimněte si, že všechny názvy nástrojů poskytovaných v balíčku začínají eu pro 'elf utils'.

V neposlední řadě zmíníme objdump. Tento nástroj je podobný readelf, ale zaměřuje se na soubory objektů. Poskytuje podobnou škálu informací o souborech ELF a dalších formátech objektů.

.Výpis 8: Informace o souboru extrahované objdump

$ objdump -f / bin / touch
/ bin / touch: formát souboru elf64-x86-64
architektura: i386: x86-64, příznaky 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
počáteční adresa 0x00000000004025e3
$

Existuje také softwarový balíček s názvem „elfkickers“ [9], který obsahuje nástroje pro čtení obsahu souboru ELF a jeho manipulaci. Počet vydání je bohužel poměrně nízký, a proto jej pouze zmíníme a neukážeme další příklady.

Jako vývojář se místo toho můžete podívat na 'pax-utils' [10,11]. Tato sada nástrojů poskytuje řadu nástrojů, které pomáhají ověřovat soubory ELF. Například dumpelf analyzuje soubor ELF a vrátí soubor záhlaví C obsahující podrobnosti - viz obrázek 2.

Závěr

Díky kombinaci chytrého designu a vynikající dokumentace formát ELF funguje velmi dobře a je používán i po 20 letech. Výše uvedené nástroje vám umožňují nahlédnout do souboru ELF a umožňují vám zjistit, co program dělá. Toto jsou první kroky pro analýzu softwaru - šťastný hacking!

Odkazy a reference
  • [1] Spustitelný a spojitelný formát (ELF), Wikipedia
  • [2] Fuchsia OS
  • [3] Porovnání formátů spustitelných souborů, Wikipedia
  • [4] Linux Foundation, odkazované specifikace
  • [5] Ciro Santilli: Výukový program Hello World ELF
  • [6] balíček elfutils Debian
  • [7] elfdump
  • [8] Michael Boelen: 101 souborů ELF v systému Linux: porozumění a analýza
  • [9] elfkickers
  • [10] Tvrzené / PaX nástroje
  • [11] pax-utils, balíček Debianu
Poděkování

Spisovatel by chtěl poděkovat Axelovi Beckertovi za jeho podporu při přípravě tohoto článku.

Hry Nejlepší hry z příkazového řádku pro Linux
Nejlepší hry z příkazového řádku pro Linux
Příkazový řádek není při používání Linuxu jen vaším největším spojencem - může být také zdrojem zábavy, protože jej můžete použít k hraní mnoha zábavn...
Hry Nejlepší aplikace pro mapování gamepadu pro Linux
Nejlepší aplikace pro mapování gamepadu pro Linux
Pokud rádi hrajete hry na Linuxu s gamepadem místo typického vstupního systému pro klávesnici a myš, máte k dispozici několik užitečných aplikací. Mno...
Hry Užitečné nástroje pro hráče Linuxu
Užitečné nástroje pro hráče Linuxu
Pokud rádi hrajete hry na Linuxu, je pravděpodobné, že jste ke zlepšení herního zážitku použili aplikace a nástroje jako Wine, Lutris a OBS Studio. Kr...