ELF

ELF-failivormingu mõistmine

ELF-failivormingu mõistmine

Lähtekoodist binaarkoodini

Programmeerimine algab nutika idee loomisest, lähtekoodi kirjutamisest teie valitud programmeerimiskeelde, näiteks C, ja lähtekoodi salvestamisest faili. Sobiva kompilaatori, näiteks GCC abil tõlgitakse teie lähtekood kõigepealt objektikoodiks. Lõpuks tõlgib linker objekti koodi binaarfailiks, mis seob objekti koodi viidatud teekidega. See fail sisaldab üksikuid juhiseid masinkoodina, millest protsessor saab aru ja mis käivitatakse kohe, kui kompileeritud programm on käivitatud.

Eespool nimetatud binaarfail järgib kindlat struktuuri ja üks levinumaid faile on nimetatud ELF -iks, mis lühendab Executable ja Linkable Format. Seda kasutatakse laialdaselt käivitatavate failide, ümberpaigutatavate objektifailide, jagatud teekide ja tuumaprügilate jaoks.

Kakskümmend aastat tagasi - 1999. aastal - valis projekt 86open x86-protsessorite Unixi ja Unixi-laadsete süsteemide standardbinaarfailivorminguks ELF-i. Õnneks oli ELF-vorming varem dokumenteeritud nii süsteemi V rakenduse kahendliideses kui ka tööriistaliidese standardis [4]. See asjaolu lihtsustas tohutult Unix-põhiste operatsioonisüsteemide müüjate ja arendajate vahelist standardimislepingut.

Selle otsuse taga oli ELF-i kujundus - paindlikkus, laiendatavus ja platvormidevaheline tugi erinevatele endi vormingutele ja aadressisuurustele. ELFi disain ei piirdu konkreetse protsessori, käskude või riistvaraarhitektuuriga. Täidetavate failivormingute üksikasjalikku võrdlust leiate siit [3].

Sellest ajast alates on ELF-vormingut kasutanud mitu erinevat opsüsteemi. Muuhulgas kuuluvad siia Linux, Solaris / Illumos, Free-, Net- ja OpenBSD, QNX, BeOS / Haiku ja Fuchsia OS [2]. Lisaks leiate selle mobiilseadmetest, milles töötab Android, Maemo või Meego OS / Sailfish OS, samuti mängukonsoolidelt nagu PlayStation Portable, Dreamcast ja Wii.

Spetsifikatsioon ei selgita ELF-failide failinime laiendust. Kasutusel on mitmesuguseid tähekombinatsioone, näiteks .axf, .prügikast, .päkapikk, .o, .prx, .pahviks, .ko, .nii ja .mod või pole ühtegi.

ELF-faili struktuur

Linuxi terminalis annab käsk man elf teile käepärase kokkuvõtte ELF-faili struktuuri kohta:

Nimekiri 1: ELFi struktuuri käsuleht

$ mees päkapikk
ELF (5) Linuxi programmeerija käsiraamat ELF (5)
NAME
elf - käivitatava ja linkiva vormingu (ELF) failide formaat
LÜHIKOKKUVÕTE
# kaasata
KIRJELDUS
Päisefail määratleb ELF-i käivitatava binaarse vormingu
faile. Nende failide hulgas on tavalised käivitatavad failid, mida saab teisaldada
objektifailid, põhifailid ja jagatud teegid.
ELF-failivormingut kasutav käivitatav fail koosneb ELF-i päisest,
järgneb programmi päise tabel või jaotise päise tabel või mõlemad.
ELF-i päis on alati faili nullist nihutatud. Programm
päise tabel ja jaotise päise tabeli nihe failis on
määratletud ELF-i päises. Kaks tabelit kirjeldavad ülejäänud tabelit
toimiku iseärasused.

Nagu ülaltoodud kirjeldusest näha, koosneb ELF-fail kahest osast - ELF-i päisest ja faili andmetest. Failiandmete sektsioon võib koosneda programmi päistetabelis, mis kirjeldab nulli või enamat segmenti, sektsiooni päisetabelit, mis kirjeldab nulli või enamat sektsiooni, millele järgnevad andmed, millele viidatakse programmi päise tabeli kirjetega, ja sektsiooni päise tabel. Iga segment sisaldab teavet, mis on vajalik faili käitamise ajal, jaotised aga linkimise ja ümberpaigutamise jaoks olulisi andmeid. Joonis 1 illustreerib seda skemaatiliselt.

ELFi päis

ELF-i päis on 32 baiti pikk ja tähistab faili vormingut. See algab nelja unikaalse baidi järjestusega, mis on 0x7F, millele järgnevad 0x45, 0x4c ja 0x46, mis tõlgitakse kolme täheks E, L ja F. Muude väärtuste hulgas näitab päis ka seda, kas see on 32- või 64-bitise vormingu ELF-fail, kasutab väikest või suurt endiidsust, näitab nii ELF-i versiooni kui ka seda, millise operatsioonisüsteemi jaoks fail kompileeriti. õige rakenduse binaarne liides (ABI) ja protsessori käskude komplekt.

Binaarfaili puute heksdump näeb välja järgmine:

.Loend 2: binaarfaili hexdump

$ hd / usr / bin / touch | pea -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 | [meiliga kaitstud] @… |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 | [meiliga kaitstud] |

Debian GNU / Linux pakub GNU 'binutils' paketis olevat käsku readelf. Koos lülitiga -h (lühiversioon “-file-header” jaoks) kuvab see kenasti ELF-faili päise. Loend 3 illustreerib seda käsu puudutamisel.

.Loend 3: ELF-faili päise kuvamine

$ readelf -h / usr / bin / touch
ELFi päis:
Maagia: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klass: ELF64
Andmed: 2 täiend, väike endiaan
Versioon: 1 (praegune)
OS / ABI: UNIX - süsteem V
ABI versioon: 0
Tüüp: EXEC (käivitatav fail)
Masin: täiustatud mikroseadmed X86-64
Versioon: 0x1
Sisestuspunkti aadress: 0x4025e3
Programmi päiste algus: 64 (baidid faili)
Jaotise päiste algus: 58408 (baidid faili)
Lipud: 0x0
Selle päise suurus: 64 (baiti)
Programmi päiste suurus: 56 (baiti)
Programmi päiste arv: 9
Jaotise päiste suurus: 64 (baiti)
Jaotise päiste arv: 27
Jao päise stringitabeli register: 26

Programmi päis

Programmi päis näitab käitamise ajal kasutatavaid segmente ja annab süsteemile teada, kuidas protsessipilti luua. Loendi 2 päis näitab, et ELF-fail koosneb üheksast programmipäisest, mille suurus on 56 baiti, ja esimene päis algab baidist 64.

Jällegi aitab käsk readelf teavet ELF-failist välja tõmmata. Lüliti -l (lühidalt programmipäistele või -segmentidele) näitab rohkem üksikasju, nagu on näidatud loendis 4.

.Loend 4: kuvage teave programmipäiste kohta

$ readelf -l / usr / bin / touch
Elf-faili tüüp on EXEC (käivitatav fail)
Sisestuspunkt 0x4025e3
Programmi päiseid on 9, alustades nihkest 64
Programmi päised:
Tüüp Offset VirtAddr PhysAddr
FileSiz MemSizi lipud joondavad
PHDR 0x000000000000004040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Taotlev programmitõlk: / lib64 / ld-linux-x86-64.nii.2]
LOAD 0x000000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
LOAD 0x00000000000000de10 0x000000000060601010xx0000000000606010
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMIC 0x00000000000000de28 0x00000000006060de28 0x0000000000606028
0x00000000000001d0 0x00000000000001d0 RW 8
MÄRKUS 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x000000000000bc40 0x000000000040bc40 0x000000000040bc40
0x00000000000003a4 0x00000000000003a4 R 4
GNU_STACK 0x000000000000000000 0x000000000000000000 0x000000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x00000000000000de10 0x00000000000060de10 0x0000000000606010
0x00000000000001f0 0x00000000000001f0 R 1
Jaotise segmendi kaardistamine:
Segmentide jaotised ..
00
01 .interp
02 .interp .Märge.ABI-silt .Märge.gnu.järgu ID .gnu.räsi .dynsym .dynstr .gnu.versioon .gnu.versioon_r .rela.dün .rela.plt .selles .plt .teksti .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dünaamiline .sai .sai.plt .andmed .bss
04 .dünaamiline
05 .Märge.ABI-silt .Märge.gnu.järgu ID
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dünaamiline .sai

Jaotise päis

ELF-i struktuuri kolmas osa on jaotise päis. See on mõeldud binaararvu üksikute osade loetlemiseks. Lüliti -S (lühend sektsioonide päistest või sektsioonidest) loetleb erinevad päised. Mis puutub puutekäsklusse, siis seal on 27 jaotise päist ja loendis 5 kuvatakse neist neli esimest koos viimase. Iga rida hõlmab sektsiooni suurust, sektsiooni tüüpi, samuti selle aadressi ja mälu nihet.

.Loend 5: jaotise üksikasjad on avalikustatud

$ readelf -S / usr / bin / touch
Sektsiooni päiseid on 27, alustades nihkest 0xe428:
Jao päised:
[Nr] Nimi Tüüp Aadress Nihe
Suuruse EntSize märgistab lingi teabe joondamine
[0] NULL 000000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .Märge.ABI-silt MÄRKUS 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .Märge.gnu.build-i MÄRKUS 0000000000400274 00000274


[26] .shstrtab STRTAB 000000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Lippude võti:
W (kirjutamine), A (eraldamine), X (käivitamine), M (ühendamine), S (stringid), l (suur)
I (info), L (linkide järjestus), G (rühm), T (TLS), E (välista), x (teadmata)
O (vajalik OS-i täiendav töötlemine) o (OS-i spetsiifiline), p (protsessori spetsiifiline)

Tööriistad ELF-faili analüüsimiseks

Nagu ülalolevatest näidetest võisite märkida, täiendatakse GNU / Linuxi paljude kasulike tööriistadega, mis aitavad teil ELF-faili analüüsida. Esimene kandidaat, kellele vaatame, on faili utiliit.

fail kuvab põhiteavet ELF-failide kohta, sealhulgas käskude arhitektuuri kohta, millele ümberpaigutatava, käivitatava või jagatud objektifaili kood on mõeldud. Loendis 6 ütleb see teile, et / bin / touch on 64-bitine käivitatav fail, mis järgib Linuxi standardbaasi (LSB), dünaamiliselt lingitud ja loodud GNU / Linuxi kerneli versiooni 2 jaoks.6.32.

.Loend 6: põhiteave faili abil

$ file / bin / touch
/ bin / touch: ELF 64-bitine LSB käivitatav fail, x86-64, versioon 1 (SYSV), dünaamiliselt lingitud, interpretaator / lib64 / l,
GNU / Linux 2 jaoks.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, eemaldatud
$

Teine kandidaat on valmis. See kuvab üksikasjalikku teavet ELF-faili kohta. Lülitite loend on suhteliselt pikk ja hõlmab kõiki ELF-vormingu aspekte. Lüliti -n (lühidalt -märkustele) kasutamine kuvab loendis 7 ainult märkmete jaotised, mis eksisteerivad faili puudutamisel - ABI-versiooni silt ja järk-järgulise ehitise ID bitstring.

.Loend 7: kuvage ELF-faili valitud sektsioonid

$ readelf -n / usr / bin / touch
Faili nihkega 0x00000254 leitud märkmete kuvamine pikkusega 0x00000020:
Omaniku andmete suurus Kirjeldus
GNU 0x00000010 NT_GNU_ABI_TAG (ABI versiooni silt)
OS: Linux, ABI: 2.6.32
Faili nihkega 0x00000274 leitud märkmete kuvamine pikkusega 0x00000024:
Omaniku andmete suurus Kirjeldus
GNU 0x00000014 NT_GNU_BUILD_ID (kordumatu koopia ID bitistring)
Järgu ID: ec08d609e9e8e73d4be6134541a472ad0ea34502

Pange tähele, et Solarise ja FreeBSD all vastab utiliit elfdump [7] readelfile. Alates 2019. aastast pole alates 2003. aastast olnud uut väljaannet ega värskendust.

Number kolm on pakett nimega elfutils [6], mis on puhtalt Linuxi jaoks saadaval. See pakub alternatiivseid tööriistu GNU Binutilsile ja võimaldab ka ELF-failide kinnitamist. Pange tähele, et kõik pakendis toodud utiliitide nimed algavad 'elf utils' e-ga.

Lõpuks mainime objdumpi. See tööriist sarnaneb endaga, kuid keskendub objektifailidele. See pakub sarnast teavet ELF-failide ja muude objektivormingute kohta.

.Loend 8: failiteave, mille on välja pakkinud objdump

$ objdump -f / bin / touch
/ bin / touch: failivorming elf64-x86-64
arhitektuur: i386: x86-64, lipud 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
algusaadress 0x00000000004025e3
$

Samuti on olemas tarkvarapakett nimega „elfkickers” [9], mis sisaldab tööriistu nii ELF-faili sisu lugemiseks kui ka sellega manipuleerimiseks. Kahjuks on väljalaskete arv üsna väike ja seepärast me seda lihtsalt mainime ega näita rohkem näiteid.

Arendajana võite selle asemel vaadata "pax-utils" [10,11]. See utiliitide komplekt pakub mitmeid tööriistu, mis aitavad ELF-faile kinnitada. Näiteks analüüsib dumpelf ELF-faili ja tagastab üksikasjadega C-päisefaili - vt joonis 2.

Järeldus

Tänu nutika disaini ja suurepärase dokumentatsiooni kombinatsioonile töötab ELF-vorming väga hästi ja on ka pärast 20 aastat kasutusel. Eespool näidatud utiliidid võimaldavad teil saada ülevaate ELF-failist ja saate välja selgitada, mida programm teeb. Need on esimesed sammud tarkvara analüüsimiseks - õnnelik häkkimine!

Lingid ja viited
  • [1] Käivitatav ja lingitav formaat (ELF), Vikipeedia
  • [2] Fuksia OS
  • [3] Käivitatavate failivormingute võrdlus, Wikipedia
  • [4] Linux Foundation, viidatud spetsifikatsioonid
  • [5] Ciro Santilli: ELFi tere maailma õpetus
  • [6] elfutils Debiani pakett
  • [7] elfdump
  • [8] Michael Boelen: 101 ELF-faili Linuxis: mõistmine ja analüüs
  • [9] päkapikud
  • [10] Karastatud / PaX-utiliidid
  • [11] pax-utils, Debiani pakett
Tänusõnad

Kirjanik soovib tänada Axel Beckertit toetuse eest selle artikli ettevalmistamisel.

OpenTTD õpetus
OpenTTD on seal üks populaarsemaid ärisimulatsioonimänge. Selles mängus peate looma suurepärase transpordiettevõtte. Alustate siiski alguses umbes 190...
SuperTuxKart Linuxile
SuperTuxKart on suurepärane pealkiri, mis on loodud selleks, et tuua teie Linuxi süsteemis tasuta Mario Karti kogemus. See on päris keeruline ja lõbus...
Lahing Wesnothi õpetuse eest
Battle for Wesnoth on üks populaarsemaid avatud lähtekoodiga strateegiamänge, mida saate praegu mängida. See mäng pole mitte ainult olnud väga pikka a...