ALV

Forstå ELF-filformatet

Forstå ELF-filformatet

Fra kildekode til binær kode

Programmering starter med å ha en smart idé og skrive kildekode på et programmeringsspråk du ønsker, for eksempel C, og lagre kildekoden i en fil. Ved hjelp av en tilstrekkelig kompilator, for eksempel GCC, blir kildekoden din først oversatt til objektkode. Til slutt oversetter linkeren objektkoden til en binær fil som knytter objektkoden til de refererte bibliotekene. Denne filen inneholder enkeltinstruksjonene som maskinkode som er forstått av CPU, og kjøres så snart det kompilerte programmet kjøres.

Binærfilen nevnt ovenfor følger en bestemt struktur, og en av de vanligste heter ELF som forkorter kjørbart og koblingsbart format. Det brukes mye for kjørbare filer, flyttbare objektfiler, delte biblioteker og kjernedumper.

For tjue år siden - i 1999 - har 86open-prosjektet valgt ELF som standard binært filformat for Unix og Unix-lignende systemer på x86-prosessorer. Heldigvis hadde ELF-formatet tidligere blitt dokumentert i både System V Application Binary Interface og Tool Interface Standard [4]. Dette faktum forenklet avtalen om standardisering mellom de forskjellige leverandørene og utviklerne av Unix-baserte operativsystemer enormt.

Årsaken bak beslutningen var utformingen av ELF - fleksibilitet, utvidbarhet og støtte på tvers av plattformer for forskjellige endianformater og adressestørrelser. ELFs design er ikke begrenset til en spesifikk prosessor, instruksjonssett eller maskinvarearkitektur. For en detaljert sammenligning av kjørbare filformater, se her [3].

Siden da er ELF-formatet i bruk av flere forskjellige operativsystemer. Dette inkluderer blant annet Linux, Solaris / Illumos, Free-, Net- og OpenBSD, QNX, BeOS / Haiku og Fuchsia OS [2]. Videre finner du den på mobile enheter som kjører Android, Maemo eller Meego OS / Sailfish OS, samt på spillkonsoller som PlayStation Portable, Dreamcast og Wii.

Spesifikasjonen avklarer ikke filtypen for ELF-filer. I bruk er en rekke bokstavkombinasjoner, for eksempel .axf, .søppel, .Alv, .o, .prx, .puff, .ko, .så, og .mod, eller ingen.

Strukturen til en ELF-fil

På en Linux-terminal gir command man elf deg et praktisk sammendrag om strukturen til en ELF-fil:

Oppføring 1: Startsiden til ELF-strukturen

$ mann alv
ELF (5) Linux Programmer's Manual ELF (5)
NAVN
elf - format for kjørbare og ELF-filer (Linking Format)
SYNOPSIS
#inkludere
BESKRIVELSE
Overskriftsfilen definerer formatet for ELF-kjørbar binær
filer. Blant disse filene er normale kjørbare filer, flyttbare
objektfiler, kjernefiler og delte biblioteker.
En kjørbar fil som bruker ELF-filformatet, består av en ELF-overskrift,
etterfulgt av en programoverskriftstabell eller en seksjonstabell eller begge deler.
ELF-overskriften er alltid på offset null for filen. Programmet
header-tabellen og seksjonen header-tabellens forskyvning i filen er
definert i ELF-overskriften. De to tabellene beskriver resten av
særegenheter i filen.
..

Som du kan se fra beskrivelsen ovenfor, består en ELF-fil av to seksjoner - en ELF-overskrift og fildata. Fildataseksjonen kan bestå av en programoverskriftstabel som beskriver null eller flere segmenter, en seksjonsoverskriftstabell som beskriver null eller flere seksjoner, etterfulgt av data som refereres til av oppføringer fra programoverskriftstabellen, og seksjonstittelbordet. Hvert segment inneholder informasjon som er nødvendig for kjøring av filen, mens seksjoner inneholder viktige data for kobling og flytting. Figur 1 illustrerer dette skjematisk.

ELF-toppteksten

ELF-overskriften er 32 byte lang, og identifiserer formatet på filen. Det starter med en sekvens på fire unike byte som er 0x7F etterfulgt av 0x45, 0x4c og 0x46 som oversettes til de tre bokstavene E, L og F. Blant andre verdier angir overskriften også om det er en ELF-fil for 32- eller 64-biters format, bruker liten eller stor endianness, viser ELF-versjonen samt for hvilket operativsystem filen ble kompilert for for å kunne samarbeide med høyre applikasjons binært grensesnitt (ABI) og cpu instruksjonssett.

Hexdumpen til binærfilberøringen ser slik ut:

.Oppføring 2: Hexdump av binærfilen

$ hd / usr / bin / touch | hodet -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-postbeskyttet] @… |
00000040 06 00 00 00 05 00 00 40 00 00 00 00 00 00 00 | [e-postbeskyttet] |

Debian GNU / Linux tilbyr readelf-kommandoen som er gitt i GNU 'binutils' -pakken. Ledsaget av bryteren -h (kortversjon for “-fil-header”) viser den pent overskriften til en ELF-fil. Oppføring 3 illustrerer dette for kommandotrykk.

.Listing 3: Viser overskriften til en ELF-fil

$ readelf -h / usr / bin / touch
ELF-topptekst:
Magi: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klasse: ELF64
Data: 2-komplement, lite endian
Versjon: 1 (nåværende)
OS / ABI: UNIX - System V
ABI-versjon: 0
Type: EXEC (kjørbar fil)
Maskin: Advanced Micro Devices X86-64
Versjon: 0x1
Inngangsadresse: 0x4025e3
Start av programoverskrifter: 64 (byte i fil)
Start av seksjonsoverskrifter: 58408 (byte i fil)
Flagg: 0x0
Størrelse på denne overskriften: 64 (byte)
Størrelse på programoverskrifter: 56 (byte)
Antall programoverskrifter: 9
Størrelse på seksjonsoverskrifter: 64 (byte)
Antall seksjonsoverskrifter: 27
Seksjon overskrift streng tabell indeks: 26

Programoverskriften

Programhodet viser segmentene som brukes under kjøretid, og forteller systemet hvordan du lager et prosessbilde. Overskriften fra oppføring 2 viser at ELF-filen består av 9 programoverskrifter som har en størrelse på 56 byte hver, og den første overskriften starter ved byte 64.

Igjen hjelper readelf-kommandoen med å trekke ut informasjonen fra ELF-filen. Bryteren -l (kort for-program-headers eller -segments) avslører flere detaljer som vist i liste 4.

.Listing 4: Vis informasjon om programoverskriftene

$ readelf -l / usr / bin / touch
Elf-filtype er EXEC (kjørbar fil)
Inngangspunkt 0x4025e3
Det er 9 programoverskrifter, som starter ved forskyvning 64
Programoverskrifter:
Skriv Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Ber om programtolk: / lib64 / ld-linux-x86-64.så.2]
LAST 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
LOAD 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMIC 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
MERKNAD 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
Seksjon til segmentkartlegging:
Segmenter ..
00
01 .interp
02 .interp .Merk.ABI-tag .Merk.gnu.build-id .gnu.hasj .dynsym .dynstr .gnu.versjon .gnu.versjon_r .rela.dyn .rela.plt .i det .plt .tekst .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dynamisk .fikk .fikk.plt .data .bss
04 .dynamisk
05 .Merk.ABI-tag .Merk.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamisk .fikk

Seksjonens topptekst

Den tredje delen av ELF-strukturen er seksjonstittelen. Det er ment å liste opp de enkelte delene av binæren. Bryteren -S (kort for -seksjonsoverskrifter eller -seksjoner) viser de forskjellige overskriftene. Når det gjelder berøringskommandoen, er det 27 seksjonsoverskrifter, og oppføring 5 viser de fire første av dem pluss den siste, bare. Hver linje dekker seksjonsstørrelsen, seksjonstypen, adresse og minneforskyvning.

.Oppføring 5: Seksjonsdetaljer avslørt av readelf

$ readelf -S / usr / bin / touch
Det er 27 seksjonsoverskrifter, som starter ved forskyvning 0xe428:
Seksjonsoverskrifter:
[Nr] Navn Type Adresse Offset
Størrelse EntSize Flagg Link Info Align
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .Merk.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .Merk.gnu.build-i MERK 0000000000400274 00000274
..
..
[26] .shstrtab STRTAB 0000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Nøkkel til flagg:
W (skriv), A (tildel), X (utfør), M (slå sammen), S (strenger), l (stor)
I (info), L (lenkerekkefølge), G (gruppe), T (TLS), E (ekskluder), x (ukjent)
O (ekstra OS-behandling kreves) o (OS-spesifikk), p (prosessorspesifikk)

Verktøy for å analysere en ELF-fil

Som du kanskje har bemerket fra eksemplene ovenfor, er GNU / Linux utarbeidet med en rekke nyttige verktøy som hjelper deg med å analysere en ELF-fil. Den første kandidaten vi skal se på er filverktøyet.

filen viser grunnleggende informasjon om ELF-filer, inkludert instruksjonsarkitekturen som koden i en flyttbar, kjørbar eller delt objektfil er ment for. I liste 6 forteller den deg at / bin / touch er en 64-biters kjørbar fil som følger Linux Standard Base (LSB), dynamisk koblet og bygget for GNU / Linux-kjernen versjon 2.6.32.

.Liste 6: Grunnleggende informasjon ved hjelp av fil

$ fil / kasse / berøring
/ bin / touch: ELF 64-bit LSB-kjørbar, x86-64, versjon 1 (SYSV), dynamisk koblet, tolk / lib64 / l,
for GNU / Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, strippet
$

Den andre kandidaten er leseverdig. Den viser detaljert informasjon om en ELF-fil. Listen over brytere er sammenlignbar lang og dekker alle aspektene ved ELF-formatet. Bruke bryteren -n (kort for -noter) Oppføring 7 viser kun notedelene som finnes i filberøringen - ABI-versjonskoden og build-ID-bitstrengen.

.Oppføring 7: Vis valgte deler av en ELF-fil

$ readelf -n / usr / bin / touch
Viser notater funnet ved filforskyvning 0x00000254 med lengde 0x00000020:
Eier Datastørrelse Beskrivelse
GNU 0x00000010 NT_GNU_ABI_TAG (ABI-versjonskode)
OS: Linux, ABI: 2.6.32
Viser notater funnet ved filforskyvning 0x00000274 med lengde 0x00000024:
Eier Datastørrelse Beskrivelse
GNU 0x00000014 NT_GNU_BUILD_ID (unik bygg-ID bitstreng)
Bygg-ID: ec08d609e9e8e73d4be6134541a472ad0ea34502

Merk at under Solaris og FreeBSD tilsvarer elfdumpen [7] med readelf. Fra og med 2019 har det ikke kommet en ny utgivelse eller oppdatering siden 2003.

Nummer tre er pakken med navnet elfutils [6] som er rent tilgjengelig for Linux. Det gir alternative verktøy til GNU Binutils, og tillater også validering av ELF-filer. Merk at alle navnene på verktøyene i pakken starter med eu for 'elf utils'.

Sist men ikke minst vil vi nevne objdump. Dette verktøyet ligner på readelf, men fokuserer på objektfiler. Det gir et lignende utvalg av informasjon om ELF-filer og andre objektformater.

.Oppføring 8: Filinformasjon hentet av objdump

$ objdump -f / bin / touch
/ bin / touch: filformat elf64-x86-64
arkitektur: i386: x86-64, flagg 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
startadresse 0x00000000004025e3
$

Det er også en programvarepakke kalt 'elfkickers' [9] som inneholder verktøy for å lese innholdet i en ELF-fil, samt manipulere den. Dessverre er antall utgivelser ganske lavt, og det er derfor vi bare nevner det, og viser ikke flere eksempler.

Som utvikler kan du i stedet se på 'pax-utils' [10,11]. Dette settet med verktøy gir en rekke verktøy som hjelper til med å validere ELF-filer. Som et eksempel, analyserer dumpelf ELF-filen, og returnerer en C-headerfil som inneholder detaljene - se figur 2.

Konklusjon

Takket være en kombinasjon av smart design og utmerket dokumentasjon fungerer ELF-formatet veldig bra, og er fortsatt i bruk etter 20 år. Verktøyene vist ovenfor gir deg et innblikk i en ELF-fil, og lar deg finne ut hva et program gjør. Dette er de første trinnene for å analysere programvare - lykkelig hacking!

Lenker og referanser
  • [1] Executable and Linkable Format (ELF), Wikipedia
  • [2] Fuchsia OS
  • [3] Sammenligning av kjørbare filformater, Wikipedia
  • [4] Linux Foundation, refererte spesifikasjoner
  • [5] Ciro Santilli: ELF Hello World Tutorial
  • [6] elfutils Debian-pakke
  • [7] alfdump
  • [8] Michael Boelen: 101 av ELF-filer på Linux: forståelse og analyse
  • [9] elfkickers
  • [10] Hardened / PaX Utilities
  • [11] pax-utils, Debian-pakke
Anerkjennelser

Forfatteren vil takke Axel Beckert for hans støtte angående utarbeidelsen av denne artikkelen.

Mus Hvordan endre mus og berøringsplateinnstillinger ved hjelp av Xinput i Linux
Hvordan endre mus og berøringsplateinnstillinger ved hjelp av Xinput i Linux
De fleste Linux-distribusjoner leveres med "libinput" -biblioteket som standard for å håndtere inngangshendelser på et system. Den kan behandle inngan...
Mus Kartlegg museknappene på en annen måte for annen programvare med X-Mouse Button Control
Kartlegg museknappene på en annen måte for annen programvare med X-Mouse Button Control
Kanskje du trenger et verktøy som kan gjøre at musens kontroll endres med hvert program du bruker. Hvis dette er tilfelle, kan du prøve et program som...
Mus Microsoft Sculpt Touch Wireless Mouse Review
Microsoft Sculpt Touch Wireless Mouse Review
Jeg har nylig lest om Microsoft Sculpt Touch trådløs mus og bestemte meg for å kjøpe den. Etter å ha brukt den en stund bestemte jeg meg for å dele mi...