Treść książki

Przejdź do opcji czytnikaPrzejdź do nawigacjiPrzejdź do informacjiPrzejdź do stopki
2.2.PlikiwykonywalneELF
Programywykonywalneorazbibliotekiwspółdzielone(ang.
sharedlibraries
lub
sharedobjects
)wsystemachGNU/Linuxzapisywane
wplikach,którychstrukturazdefiniowanajestprzezstandardELF(
ExecutableandLinkableFormat
).
GNU/Linuxniejedynymisystemami,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.Toniestety
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;przyczynajestprostaobiearchitekturyróż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ćwymaganedoinstalowanieodpowiedniegopakietuwdystrybucjiArchLinuxpakiettennosinazwę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ą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.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”toniesprecyzowanytypwartośćtanigdynie
powinnapojawićsięwpliku.Wartość„1”oznaczatyprelokowanyijeststosowanadoopisuplikówobiektówpowstałychjakowynik
kompilacjinp.kompilatoraClubC++(pliki*.o).Wartość„2”(ET_EXEC)oznaczastandardowyplikwykonywalny.Wartość„3”