Treść książki
Przejdź do opcji czytnikaPrzejdź do nawigacjiPrzejdź do informacjiPrzejdź do stopki
2.2.PlikiwykonywalneELF
Programywykonywalneorazbibliotekiwspółdzielone(ang.
sharedlibraries
lub
sharedobjects
)wsystemachGNU/Linuxzapisywane
sąwplikach,którychstrukturazdefiniowanajestprzezstandardELF(
ExecutableandLinkableFormat
).
GNU/Linuxniesąjedynymisystemami,wktórychwykorzystanoformatELFdoprzechowywaniatreściplikówwykonywalnychlub
bibliotek;jestonstosowanyrównieżw:
•innychsystemachuniksowych(rodzinasystemówBSD:FreeBSD,OpenBSD,NetBSD,Solaris,QNXitp.),
•alternatywnychsystemachużytkowychlubbadawczych(AmigaOS4,MorphOS,AROS,Plan9),
•systemachkonsoligierkomputerowych(SonyPlaystation2/3/4,NintendoWii),
•urządzeniachpodręcznych,takichjaktablety,smartfonyzsystemamiAndroid,SamsungBada,NokiaMaemoitp.
Użycietegoformatunawieluróżnychsystemachwynikazfaktu,żeELFzostałzaprojektowanyjakoformatuniwersalny.To–niestety
–czasemwiążesięztym,żeniektórewartościzapisanewplikubędąmiałysenstylkowtedy,gdybędąinterpretowanezgodniezregułami
interpretacjiokreślonymidladanejarchitektury.Naszczęścietakichspecyficznychmiejscjestniewieleidużączęśćformatumożna
zinterpretowaćzapomocąogólnychmetod.
UniwersalnośćformatuELFpociągazasobąkoniecznośćidentyfikacjitypudanychprzechowywanychwpliku.Wzależnościodtypu
architektury,dlaktórejprzeznaczonyjestprogram,formatczęścidanych(takichjakkodźródłowy)będzieniecoinny.Naprzykładprogram
nakonsolęPlayStation3przechowywanywplikuELFbędziezawierałinnykodmaszynowyniżprogramwplikuELFprzeznaczonydla
architekturyx86-64;przyczynajestprosta–obiearchitekturyróżniąsięodsiebieizawierająróżnejednostkicentralne(procesory).
DoanalizystrukturyplikuELFnajczęściejwykorzystujesięnarzędziareadelf(1)iobjdump(1),dostępnewłaściwiewkażdejdystrybucji
systemuGNU/Linux(wchodząwskładpopularnegopakietunarzędziowegobinutils).Wdalszychczęściachrozdziałubędziemysię
posługiwaćtymiprogramamidoodczytywaniastrategicznychinformacjizprzykładowychplikówwykonywalnychlubbibliotek.
PełnedefinicjeformatuELFznajdująsięwpliku/usr/include/linux/elf.h,któryjestdostępnywwiększościdystrybucji(może
byćwymaganedoinstalowanieodpowiedniegopakietu–wdystrybucjiArchLinuxpakiettennosinazwęlinux-api-headers)oraz
wdokumentacji[3].Polecamyzapoznaniesięztreściątegopliku,ponieważrozdziałtenniepowstałzmyśląoprzedstawieniukompletnej
dokumentacjitegostandardu;pokazanewnimbędąjedynienajważniejszeaspektyformatu,przydatnepodczasprzeprowadzaniaanalizy
plikówwykonywalnychozamkniętymźródle.
2.2.1.Identyfikacjasystemuiarchitekturydocelowej
Jednąznajbardziejpodstawowychinformacji,którąnależyokreślićzaraznasamympoczątku,jestarchitekturadocelowaprogramu.Jeśli
kodjestkierowanypodprocesorPowerPC,niemasensuuruchamiaćgonaarchitekturzex86-64iodwrotnie.Częstoanalizującsamplik
binarny,możnaokreślićdokładnąarchitekturęplatformydocelowej,dlaktórejdanyplikELFbyłzbudowany.Posiadanietejinformacji
umożliwipoprawnąinterpretacjękodumaszynowegozapisanegowodpowiednichsekcjach.
Poszukiwanedaneznajdująsięwnagłówkuonazwie
fileheader
(strukturyElf32_EhdrlubElf64_Ehdr),któryznajdujesięzaraz
napoczątkupliku.Zrzutekranunarysunku2.1przedstawianagłówek
fileheader
wprogramiedoedycjidanychbinarnych.
Rysunek2.1.Nagłówek
fileheader
Adres0x00zawiera4bajty,którezawszeprzyjmujątęsamąpostać:0x7F,0x45,0x4Coraz0x46.Wprzypadku,gdyplikpodtym
adresemzawierainnątreść,najprawdopodobniejniejesttoplikELF.
•Adres0x04zawierajedenbajtidentyfikującydługośćsłowaplatformydocelowej.Bajtowartości„1”identyfikujeplatformę32-bitową,
natomiastbajtowartości„2”oznaczaplatformę64-bitową.Należyzwrócićuwagę,żewprzypadkuplatformy64-bitowejwszystkie
adresybędązajmowały8bajtów,zamiaststandardowych4bajtównaplatformie32-bitowej.Powodujetoczęstosytuację,wktórej
adresyposzczególnychpólmogąsięróżnićpomiędzywersją32-a64-bitową.
•Adres0x05zawierajedenbajtokreślającykolejnośćbajtównadanejplatformie.Sądostępnedwiemożliwości:najbardziejznaczący
bajtjakopierwszy(ang.
big-endian
,np.architekturaPowerPC)symbolizowanąprzezwartość„1”oraznajbardziejznaczącybajtjako
ostatni(ang.
little-endian
,np.architekturax86)symbolizowanąprzezwartość„2”.
•Adres0x07zawierajedenbajtokreślającyużytyinterfejsbinarny(
ApplicationBinaryInterface
,wskrócie
ABI
).Nowewersje
specyfikacjiELFwycofująużycietegopolaiobecniezalecasięjegowyzerowanie.Wartojednakzwrócićuwagęnainformacje
znajdującesięwtympolu;historyczniewielesystemówwpisywałotutajdedykowanąwartośćwskazującąnarodzajsystemu,pod
którykierowanybyłplikwykonywalny:
–wartość„0”zgodniezestandardemoznaczaławartośćniesprecyzowaną;
–wartość„1”oznaczałasystemHP-UX(spadkobiercaSystemV,produkowanyprzezfirmęHPpo1984r.);aktualniewartośćtajest
wykorzystywanawsystemieGNU/Linux;
–wartość„2”oznaczałasystemNetBSD;
–wartość„3”byłazarezerwowanadlasystemuGNU/Linux,niejestjużjednakstosowana;
–wartość„4”możeoznaczaćsystemGNU/Hurd,tworzonyprzezprojektGNU;
–wartość„6”oznaczałasystemSolaris,produkowanyprzezfirmęOracle(wcześniejSunMicrosystems);
–wartość„7”byłastosowanadookreśleniaABIsystemuAIX(jesttosystemUNIXprodukowanyprzezfirmęIBM);
–wartość„9”jestnadalwykorzystywanawsystemieFreeBSD;
–wartość„12”byładedykowanadlasystemuOpenBSD.
•Adres0x08historyczniezawierałinformacjeowersjiABIzdefiniowanegowpoprzednimpolu.AktualnaspecyfikacjaformatuELF
zalecawyzerowanietegopola.
•Adres0x10zawieradwabajtyokreślającetypplikuwykonywalnego.Wartość„0”toniesprecyzowanytyp–wartośćtanigdynie
powinnapojawićsięwpliku.Wartość„1”oznaczatyprelokowanyijeststosowanadoopisuplikówobiektówpowstałychjakowynik
kompilacjinp.kompilatoraClubC++(pliki*.o).Wartość„2”(ET_EXEC)oznaczastandardowyplikwykonywalny.Wartość„3”