Portable Executable (PE) izvršni je format datoteka u operacijskom sustavu Windows. Sastoji se od nekoliko sekcija koje mogu sadržavati uvoz i izvoz pojedinih funkcija iz biblioteka, kao i skrivene resurse. Zbog svoje sveprisutnosti i popularnosti operacijskog sustava Windows, većina zloćudnih programa (malwarea) se radi u ovom formatu. Pritom se nerijetko koriste tehnike pakiranja u kojima se kompresijom i kriptiranjem smanjuje vidljivost uzoraka u programu, prikriva stvarna namjena programa i dodaje još jednu ili nekoliko izvršnih datoteka. To otežava statičku i dinamičku analizu programa, ali i čini PE format dobro istraženim i poznatim.
Ključne riječi: PE; format datoteke; pakiranje
Portable Executable (PE) izvršni je format datoteka u operacijskom sustavu Windows. To uključuje aplikacije (.exe datoteke), dinamički povezane biblioteke (DLL) i druge tipove izvršnih datoteka. PE format temelji se na COFF (Common Object File Format) formatu datoteka.
Jedna od glavnih značajki PE formata je njegova podrška za povezivanje dinamičkim bibliotekama. To omogućuje programima da koriste funkcije iz drugih biblioteka bez da ih moraju sadržavati unutar svog izvornog koda. Time se smanjuje veličina izvršne datoteke i omogućuje višestruka upotreba istih biblioteka u različitim aplikacijama.
PE formatom određuje se na koji se način u memoriju računala puni izvršni program. Pritom punilac operacijskog sustava (loader) parsira format datoteke, određuje adrese i smješta podatke u memoriju, učitava zavisne datoteke, biblioteke i funkcije, postavlja početnu točku izvršavanja na početnu adresu programa i po završetku izvođenja programa, oslobađa nepotrebne resurse iz memorije. Upravo zato što se početna adresa u radnoj memoriji na koju se program smješta izračunava pri svakom izvođenju, format se i zove „prijenosnim“ (portable u PE).
PE format zapravo je sadržan u jednom drugom formatu izvršne datoteke kao njen „payload“. MZ format nastao je za MS-DOS i nazvan je po Marku Zbykowskom, svom autoru. Kao i mnogi formati datoteka, započinje takozvanim „čarobnim brojem“ koji se sastoji od bajtova 0x4D 0x5A
(„MZ“). Time započinje MZ, također zvano i DOS zaglavlje, ukupne veličine 64 bajtova. Najbitnije polje u njemu je nazvano e_lfanew
na offsetu 0x3C
i upućuje loadera na adresu na kojoj počinje PE format.
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
Nakon toga slijedi MS-DOS stub, tj. kratki tekst koji se ispisuje na standardnom toku pri pokretanju programa na nepodržanim operacijskim sustavima, defaultno “This program cannot be run in DOS mode.”, ali moguće ju je promijeniti prilikom prevođenja.
Iako većina literature navodi da iza ovog slijedi PE zaglavlje, zapravo slijedi opcionalno, „Rich“ zaglavlje, koje se npr, dodaje pri prevođenju programa Visual Studiom. Ono se sastoji od teksta kodiranim XOR kodom, stringa „Rich“ i 32-bitnog stringa koji se koristio u XOR kodiranju. Taj dio datoteke može biti u potpunosti prazan bez da utječe na izvođenje programa, a zato što je i malo poznat, koristio se u Olympic Destroyer napadu u kojem je promijenjeno Rich zaglavlje tako da nalikuje na jedan drugi maliciozni program.
Potom slijedi COFF/PE/NT zaglavlje, koje započinje potpisom „PE\0\0“ duljine 4 bajta za kojim slijedi zaglavlje image datoteke.
typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
Kako se formatom određuje raspored i struktura podataka unutar datoteke, PE format sadrži i određene metapodatke, od kojih je Machine
prvi kojeg susrećemo u ovoj analizi. On može imati nekoliko vrijednosti, od kojih su značajne:
0x8664
za AMDx640x01c0
za ARM0x014C
za Intel i386 (x86) arhitekture skupa instrukcija (ISA).
U TimeDateStampu
nalazi se vrijeme nastanka datoteke u Unix formatu. Značajna su i polja NumberOfSections
, SizeOfOptionalHeader
te Characteristics
koji sadrži informacije o vrsti datoteke.
Iza slijedi Optional Header s čarobnim brojevima 0x010B
\0x020B
(32/64-bit). Unatoč imenu, on nipošto nije izboran, ako mislimo pokrenuti datoteku. U njemu se nalaze informacije loaderu kako pokrenuti datoteku – adresa početne točke te bazna memorijska adresa. Spominje se i verzija operacijskog sustava te broj podatkovnih direktorija. Pritom veličina nije fiksna, već je određena sa SizeOfOptionalHeader
iz PE zaglavlja. Veličine nisu jednake za 32 i 64 bit, ali najčešće je veličina zaglavlja za 32-bitne sustave 0xE0
.
Slijedi NumberOfHeaders
(iz PE zaglavlja) zaglavlja sekcija (Section Headers) od kojih se svaki sastoji od:
U prethodnom poglavlju spominjale su se relativne adrese. Pri izvršenju programa upravitelj memorijom (barem na Windowsima) koristi virtualnu memoriju koja je sloj apstrakcije između programa i radne memorije, što se ostvaruje straničenjem. Virutalna memorija omogućava višestruke adresne prostore, kako bi svaki program mogao pristupiti „istoj“ adresi, iako se nalaze u različitim dijelovima memorije. Stranice omogućavaju dodjelu diskretne veličine memorije (najčešće 4 kB) procesu. Time se definiraju pojmovi:
Pretvorba adresa radi se na sljedeći način: VA = RVA + ImageBase
, RVA = VA – ImageBase
.
RVA = FizičkiOffset
– PtrToRawData
+ SectionRVA
, a FizičkiOffset
= RVA – SectionRVA
+ PtrToRawData
Pritom se u memoriju stranice i sekcije unose poravnate na FileAlignment
i SectionAlignment
Podatkovni direktoriji parovi su (adresa, veličina) u obliku tablica koji se učitavaju u memoriju. Najčešći i najvažniji direktoriji su Export, Import, Resource, Relocation te TLS. Export
Export direktorij najčešće je prisutan u DLL datotekama. U tom slučaju u njima se nalaze funkcije dostupne imenom i rednim brojem. Radi se o tri tablice: adresnoj tablici, tablici s pokazivačima na imena te tablici rednih brojeva. Import Import direktorij sastoji se od tablica u kojima se opisuju dodatne ovisnosti koje trebaju programu za izvođenje, najčešće skupine biblioteka i njihovih programskih sučelja. Svaki zapis opisuje jednu biblioteku i pokazuje na listu funkcija koje se uključuju iz njega.
Pakiranje je postupak pri kojem se u izvršnu datoteku “ubacuje” još jedna izvršna datoteka. To je moguće napraviti između sekcija ili kao resurs. Uz to, naprednije i najčešće tehnike koriste metode kompresije i/ili kriptiranja. Oboje postiže da je sadržaj izvršne datoteke prikriven i teži za reverznu analizu, pogotovo statičku, budući da se uklanjaju uzorci u podacima. Uz to, prvo je potrebno otpakirati “payload”, tj. prikriveni izvršni program. Naposlijetku, virtualizacija je također česta tehnika pakiranja. Pritom se stvara virtualni okoliš unutar kojeg se izvršna datoteka izvodi. Time se i olakšava izvođenje malwarea na različitim konfiguracijama računala.
Portable Executable (PE) format se često koristi u računalnoj forenzici za analizu izvršnih datoteka i DLL-ova koji su povezani sa sigurnosnim rizicima i incidentima. Forenzičari koriste različite alate i tehnike za analizu PE datoteka kako bi identificirali potencijalne tragove koji mogu pomoći u istraživanju incidenta.
Pritom se najčešće za PE format radi analiza malware-a, budući da su obično napisani u obliku izvršne datoteke. Za statičku analizu koriste se PE parseri, a u dinamičkoj analizi nadziru se ponašanja kao stvaranje novih procesa, mijenjanje registra ili povezivanje s vanjskim serverima. Osim kao izvršne datoteke, maliciozni programi se često kriju u DLL-ovima, budući da im operacijski sustav vjeruje i daje više privilegije pri izvođenju.
[2] 0xRick - A dive into the PE file format
[3] Sikorski, M., Honig, A.: Practical malware analysis