Pag-unawa sa Format ng File ng ELF

Understanding Elf File Format



Mula sa Source Code To Binary Code

Nagsisimula ang programming sa pagkakaroon ng isang matalino na ideya, at pagsulat ng source code sa isang wika na napili mo, halimbawa C, at pag-save ng source code sa isang file. Sa tulong ng isang sapat na tagatala, halimbawa ng GCC, ang iyong source code ay isinalin sa object code, una. Sa paglaon, isinalin ng linker ang object code sa isang binary file na nag-uugnay sa object code sa mga sanggunian na aklatan. Naglalaman ang file na ito ng solong mga tagubilin bilang code ng makina na nauunawaan ng CPU, at naisasagawa kaagad sa pagpapatakbo ng naipong programa.

Ang binary file na nabanggit sa itaas ay sumusunod sa isang tukoy na istraktura, at ang isa sa mga pinaka-karaniwan ay pinangalanang ELF na pinapaikli ang Executable at Linkable Format. Malawakang ginagamit ito para sa maipapatupad na mga file, maililipat na mga file ng object, nakabahaging mga aklatan, at mga pangunahing pagtapon.







Dalawampung taon na ang nakalilipas - noong 1999 - ang proyekto ng 86open ay pumili ng ELF bilang karaniwang pamantayan ng format ng binary file para sa mga Unix at kagaya ng Unix na mga system sa mga prosesor ng x86. Sa kabutihang palad, ang format na ELF ay dating naitala sa parehong System V Application Binary Interface, at ang Tool Interface Standard [4]. Ang katotohanang ito ay labis na pinasimple ang kasunduan sa pamantayan sa pagitan ng iba't ibang mga vendor at developer ng mga operating system na nakabatay sa Unix.



Ang dahilan sa likod ng pasyang iyon ay ang disenyo ng ELF - kakayahang umangkop, malawak, at suporta sa cross-platform para sa iba't ibang mga endian na format at laki ng address. Ang disenyo ng ELF ay hindi limitado sa isang tukoy na processor, set ng pagtuturo, o arkitektura ng hardware. Para sa isang detalyadong paghahambing ng maipapatupad na mga format ng file, tingnan dito [3].



Simula noon, ang format na ELF ay ginagamit ng maraming magkakaibang mga operating system. Bukod sa iba pa, kasama dito ang Linux, Solaris / Illumos, Free-, Net- at OpenBSD, QNX, BeOS / Haiku, at Fuchsia OS [2]. Bukod dito, mahahanap mo ito sa mga mobile device na nagpapatakbo ng Android, Maemo o Meego OS / Sailfish OS pati na rin sa mga console ng laro tulad ng PlayStation Portable, Dreamcast, at Wii.





Hindi nililinaw ng pagtutukoy ang extension ng filename para sa mga ELF file. Ang ginagamit ay iba't ibang mga kumbinasyon ng titik, tulad ng .axf, .bin, .elf, .o, .prx, .puff, .ko, .so, at .mod, o wala.

Ang Istraktura ng isang ELF File

Sa isang terminal ng Linux, binibigyan ka ng command man elf ng isang madaling gamiting buod tungkol sa istraktura ng isang ELF file:



Listahan 1: Ang manpage ng istrakturang ELF

$ man onse

Manual ng ELF (5) Linux Programmer's ELF (5)

PANGALAN
duwende - format ng mga naisasagawa at Pag-link na Format (ELF) na mga file

SINOPSIS
# isama

DESCRIPTION
Tinutukoy ng file ng header ang format ng ELF na maipapatupad na binary
mga file. Sa gitna ng mga file na ito ay normal na maipapatupad na mga file, maililipat muli
mga file ng object, pangunahing file at mga nakabahaging aklatan.

Ang isang maipapatupad na file gamit ang format na file ng ELF ay binubuo ng isang header ng ELF,
sinundan ng isang talahanayan ng header ng programa o isang talahanayan ng header ng seksyon, o pareho.
Ang header ng ELF ay palaging nasa offset na zero ng file. Ang programa
talahanayan ng header at ang offset ng talahanayan ng header table sa file ay
tinukoy sa header ng ELF. Inilalarawan ng dalawang talahanayan ang natitirang bahagi ng
mga partikularidad ng file.

...

Tulad ng nakikita mo mula sa paglalarawan sa itaas, ang isang ELF file ay binubuo ng dalawang seksyon - isang ELF header, at data ng file. Ang seksyon ng data ng file ay maaaring binubuo ng isang talahanayan ng header ng programa na naglalarawan sa zero o higit pang mga segment, isang talahanayan ng header ng seksyon na naglalarawan sa zero o higit pang mga seksyon, na sinusundan ng data na tinukoy ng mga entry mula sa talahanayan ng header ng programa, at talahanayan ng header ng seksyon. Naglalaman ang bawat segment ng impormasyon na kinakailangan para sa run-time na pagpapatupad ng file, habang ang mga seksyon ay naglalaman ng mahalagang data para sa pag-link at paglilipat. Ang larawan 1 ay naglalarawan nito sa iskematiko.

Ang ELF Header

Ang header ng ELF ay 32 bytes ang haba, at kinikilala ang format ng file. Nagsisimula ito sa isang pagkakasunud-sunod ng apat na natatanging byte na 0x7F na sinusundan ng 0x45, 0x4c, at 0x46 na isinalin sa tatlong titik E, L, at F. Kabilang sa iba pang mga halaga, ipinapahiwatig din ng header kung ito ay isang ELF file para sa 32 o Ang 64-bit na format, gumagamit ng kaunti o malaking endianness, ipinapakita ang bersyon ng ELF pati na rin sa kung aling operating system ang file ay naipon para makisalamuha sa tamang application binary interface (ABI) at set ng pagtuturo ng cpu.

Ang hexdump ng pag-ugnay sa binary file ay ganito ang sumusunod:

. Listahan 2: Ang hexdump ng binary file

$ hd / usr / bin / touch | ulo -5
00000000 7f 45 4c 46 02 01 01 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 | ..> ......% @ ..... |
00000020 40 00 00 00 00 00 00 00 28 e4 00 00 00 00 00 | | ....... (....... |
00000030 00 00 00 00 40 00 38 00 09 00 40 00 1b 00 1a 00 | [protektado ng email] @ ..... |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 | [protektado ng email] |

Nag-aalok ang Debian GNU / Linux ng readelf command na ibinibigay sa package na 'binutils' ng GNU. Sinamahan ng switch -h (maikling bersyon para sa –file-header) maganda itong ipinapakita ang header ng isang ELF file. Ang listahan ng 3 ay naglalarawan nito para sa touch touch.

. Listahan 3: Ipinapakita ang header ng isang ELF file

$ readelf -h / usr / bin / touch
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klase: ELF64
Data: komplemento ng 2, maliit na endian
Bersyon: 1 (kasalukuyang)
OS / ABI: UNIX - System V
Bersyon ng ABI: 0
Uri: EXEC (Maipapatupad na file)
Makina: Mga advanced na Micro Device X86-64
Bersyon: 0x1
Address ng puntong entry: 0x4025e3
Simula ng mga header ng programa: 64 (bytes into file)
Simula ng mga header ng seksyon: 58408 (bytes into file)
Mga Bandila: 0x0
Laki ng header na ito: 64 (bytes)
Laki ng mga header ng programa: 56 (bytes)
Bilang ng mga header ng programa: 9
Laki ng mga header ng seksyon: 64 (bytes)
Bilang ng mga header ng seksyon: 27
Listahan ng talahanayan ng header string ng seksyon: 26

Ang Header ng Program

Ipinapakita ng header ng programa ang mga segment na ginamit sa run-time, at sinasabi sa system kung paano lumikha ng isang imahe ng proseso. Ipinapakita ng header mula sa Listing 2 na ang ELF file ay binubuo ng 9 mga header ng programa na may sukat na 56 bytes bawat isa, at ang unang header ay nagsisimula sa byte 64.

Muli, ang utos ng sarili ay tumutulong upang makuha ang impormasyon mula sa ELF file. Ang switch -l (maikli para sa –program-header o –segments) ay nagpapakita ng higit pang mga detalye tulad ng ipinakita sa Listahan 4.

. Listahan 4: Ipakita ang impormasyon tungkol sa mga header ng programa

$ readelf -l / usr / bin / touch

Ang uri ng file ng duwende ay EXEC (Maipapatupad na file)
Entry point 0x4025e3
Mayroong 9 mga header ng programa, simula sa offset 64

Mga Header ng Programa:
I-type ang Offset VirtAddr PhysAddr
I-align ang Mga FileSiz MemSiz Flags
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Humihiling ng interpreter ng programa: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
LOAD 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMIC 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
TANDAAN 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

Seksyon sa Pagma-map ng segment:
Mga Seksyon ng Segment ...
00
01 .interp
02 .interp .note.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 .dynamic
05 .note.ABI-tag .note.gnu. build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamic .got

Ang Header ng Seksyon

Ang pangatlong bahagi ng istraktura ng ELF ay ang header ng seksyon. Ito ay sinadya upang ilista ang solong mga seksyon ng binary. Ang switch -S (maikli para sa –section-header o – section) ay naglilista ng iba't ibang mga header. Tulad ng para sa touch command, mayroong 27 na mga header ng seksyon, at ang Listahan 5 ay nagpapakita ng unang apat sa kanila kasama ang huling isa lamang. Saklaw ng bawat linya ang laki ng seksyon, ang uri ng seksyon pati na rin ang address at memorya ng offset.

. Listahan 5: Ang mga detalye ng seksyon ay isiniwalat ng sarili

$ readelf -S / usr / bin / touch
Mayroong 27 mga header ng seksyon, simula sa offset 0xe428:

Mga Header ng Seksyon:
[Nr] Uri ng Pangalan ng Address Offset
I-align ang Impormasyon ng Laki ng EntSize na Mga Laki
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .note.ABI-tag TANDAAN 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .note.gnu. build-i TANDAAN 0000000000400274 00000274
...
...
[26] .shstrtab STRTAB 0000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
Susi sa Mga Bandila:
W (sumulat), A (alokasyon), X (ipatupad), M (pagsasama), S (mga kuwerdas), l (malaki)
Ako (impormasyon), L (link ng link), G (pangkat), T (TLS), E (ibukod), x (hindi alam)
O (kinakailangang dagdag na pagpoproseso ng OS) o (tukoy sa OS), p (tukoy sa processor)

Mga tool upang Pag-aralan ang isang ELF file

Tulad ng napansin mo mula sa mga halimbawa sa itaas, ang GNU / Linux ay pinuno ng isang bilang ng mga kapaki-pakinabang na tool na makakatulong sa iyo na pag-aralan ang isang ELF file. Ang unang kandidato na titingnan natin ay ang file utility.

ipinapakita ng file ang pangunahing impormasyon tungkol sa mga ELF file, kabilang ang itinuro na arkitektura kung saan inilaan ang code sa isang maililipat, maipapatupad, o nakabahaging object file. Sa listahan ng 6 sinabi nito sa iyo na / bin / touch ay isang 64-bit na maipapatupad na file kasunod ng Linux Standard Base (LSB), dinamikong na-link, at binuo para sa bersyon ng kernel ng GNU / Linux na 2.6.32.

. Listahan 6: Pangunahing impormasyon gamit ang file

$ file / bin / touch
/ bin / touch: ELF 64-bit LSB maipapatupad, x86-64, bersyon 1 (SYSV), dinamikong na-link, interpreter / lib64 / l,
para sa GNU / Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, hinubad
$

Ang pangalawang kandidato ay ang sarili. Ipinapakita nito ang detalyadong impormasyon tungkol sa isang ELF file. Ang listahan ng mga switch ay maihahambing sa haba, at sumasakop sa lahat ng mga aspeto ng format na ELF. Gamit ang switch -n (maikli para sa –notes) Ipinapakita ng listahan ng 7 ang mga seksyon ng tala, lamang, na umiiral sa pag-ugnay ng file - ang tag ng bersyon ng ABI, at ang pagbuo ng bitstring ng ID.

. Listahan 7: Ipakita ang Napiling mga seksyon ng isang ELF file

$ readelf -n / usr / bin / touch

Nagpapakita ng mga tala na natagpuan sa file offset 0x00000254 na may haba na 0x00000020:
Paglalarawan ng laki ng Data ng May-ari
GNU 0x00000010 NT_GNU_ABI_TAG (tag ng bersyon ng ABI)
OS: Linux, ABI: 2.6.32

Nagpapakita ng mga tala na natagpuan sa file offset 0x00000274 na may haba na 0x00000024:
Paglalarawan ng laki ng Data ng May-ari
GNU 0x00000014 NT_GNU_BUILD_ID (natatanging bitstring ng build ID)
Build ID: ec08d609e9e8e73d4be6134541a472ad0ea34502

Tandaan na sa ilalim ng Solaris at FreeBSD, ang utility elfdump [7] ay tumutugma sa sarili. Hanggang sa 2019, wala pang bagong paglabas o pag-update mula pa noong 2003.

Ang pangatlo ay ang pakete na pinangalanang mga elfutil [6] na pulos magagamit para sa Linux. Nagbibigay ito ng mga alternatibong tool sa GNU Binutils, at pinapayagan din ang pagpapatunay ng mga ELF file. Tandaan na ang lahat ng mga pangalan ng mga kagamitan na ibinigay sa package ay nagsisimula sa eu para sa mga 'elf utils'.

Huling ngunit hindi pa huli ay babanggitin namin ang objdump. Ang tool na ito ay katulad sa sarili ngunit nakatuon sa mga file ng object. Nagbibigay ito ng isang katulad na saklaw ng impormasyon tungkol sa mga ELF file at iba pang mga format ng object.

. Listahan 8: Ang impormasyon ng file na nakuha sa pamamagitan ng objdump

$ objdump -f / bin / touch

/ bin / touch: format ng file elf64-x86-64
arkitektura: i386: x86-64, mga watawat 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
simulan ang address 0x00000000004025e3

$

Mayroon ding isang software package na tinatawag na ‘elfkickers’ [9] na naglalaman ng mga tool upang mabasa ang mga nilalaman ng isang ELF file pati na rin ang pagmamanipula nito. Sa kasamaang palad, ang bilang ng mga pinakawalan ay medyo mababa, at iyon ang dahilan kung bakit binanggit lamang namin ito, at huwag magpakita ng mga karagdagang halimbawa.

Bilang isang developer maaari kang tumingin sa 'pax-utils' [10,11], sa halip. Ang hanay ng mga utility na ito ay nagbibigay ng isang bilang ng mga tool na makakatulong upang mapatunayan ang mga ELF file. Bilang isang halimbawa, pinag-aaralan ng dumpelf ang ELF file, at ibinabalik ang isang C header file na naglalaman ng mga detalye - tingnan ang Larawan 2.

Konklusyon

Salamat sa isang kumbinasyon ng matalino na disenyo at mahusay na dokumentasyon ang format na ELF ay gumagana nang mahusay, at ginagamit pa rin pagkalipas ng 20 taon. Ang mga kagamitan na ipinakita sa itaas ay nagbibigay-daan sa iyo ng isang pananaw sa pananaw sa isang ELF file, at hayaan mong malaman kung ano ang ginagawa ng isang programa. Ito ang mga unang hakbang para sa pagsusuri ng software - maligayang pag-hack!

Mga Link at Sanggunian
Mga Pasasalamat

Nais ng manunulat na pasalamatan si Axel Beckert para sa kanyang suporta tungkol sa paghahanda ng artikulong ito.