PE檔案格式詳細解析(一)

有毒發表於2020-03-08

PE檔案格式詳細解析(一)

一、PE檔案基本介紹

PE檔案是Windows作業系統下使用的一種可執行檔案,由COFF(UNIX平臺下的通用物件檔案格式)格式檔案發展而來。32位成為PE32,64位稱為PE+或PE32+。

二、PE檔案格式

  1. PE檔案種類如下表所示:
種類 主副檔名
可執行系列 EXE, SCR
庫系列 DLL, OCX, CPL, DRV
驅動程式系列 SYS, VXD
物件檔案系列 OBJ
  1. 基本結構

    使用010editor(二進位制檔案檢視工具)開啟一個exe可以看到如下結構:

    PE_struc1

    上圖是該exe檔案的起始部分,也是PE檔案的頭部,exe執行所需要的所有資訊都儲存在PE頭中。

PE_struc2

 

​ 從DOS頭到節區頭是PE頭部分,其下的節區合稱為PE體。檔案中使用偏移(offset),記憶體中使用VA(Virtual Address,虛擬地址)來表示位置。檔案載入到記憶體時,情況就會發生變化(節區大小、位置等)。檔案的內容一般可分為程式碼(.text)、資料(.data)、資源(.rsrc)節,分別儲存。PE頭與各節區的尾部存在一個區域,成為NULL填充。檔案/記憶體中節區的起始位置應該在各檔案/記憶體最小單位的倍數上,空白區域使用NULL進行填充(如上圖所示)。

  1. VA&RVA

    VA指程式虛擬記憶體的絕對地址,RVA(Relative Virtual Address,相對虛擬地址)指從某個基準未知(ImageBase)開始的相對地址。VA與RVA的換算滿足如下公式:

    RVA + IamgeBase = VA

    PE頭內部資訊主要以RVA的形式進行儲存,主要原因是PE檔案(主要是DLL)載入到程式虛擬記憶體的特定位置時, 該位置可能已經載入了其他PE檔案(DLL)。此時需要進行重定位將其載入到其他的空白位置,保證程式的正常執行。

三、PE頭

  1. DOS頭

    主要為現代PE檔案可以對早期的DOS檔案進行良好相容存在,其結構體為IMAGE_DOS_HEADER。

    大小為64位元組,其中2個重要的成員分別是:

    • e_magic:DOS簽名(4D5A,MZ)
    • e_lfanew:指示NT頭的偏移(檔案不同,值不同)
  2. DOS存根

    stub,位於DOS頭下方,可選,大小不固定,由程式碼與資料混合組成。

  3. NT頭

    結構體為IMAGE_NT_HEADERS,大小為F8,由3個成員組成:

    • 簽名結構體,值為50450000h(“PE”00)
    • 檔案頭,表現檔案大致屬性,結構體為IMAGE_FILE_HEADER,重要成員有4個:
      • Machine:每個CPU都擁有的唯一的Machine碼,相容32位Intel x86晶片的Machine碼為14C;
      • NumberOfSections:指出檔案中存在的節區數量;
      • SizeOfOptionalHeader:指出結構體IMAGE_OPTIONAL_HEADER32(32位系統)的長度
      • Characteristics:標識檔案屬性,檔案是否是可執行形態、是否為DLL等,以bit OR形式進行組合
    • 可選頭,結構體為IMAGE_OPTIONAL_HEADER32,重要成員有9個:
      • Magic:IMAGE_OPTIONAL_HEADER32為10B,IMAGE_OPTIONAL_HEADER64為20B
      • AddressOfEntryPoint:持有EP的RVA值,指出程式最先執行的程式碼起始地址
      • ImageBase:指出檔案的優先裝入地址(32位程式虛擬記憶體範圍為:0~7FFFFFFF)
      • SectionAlignment,FileAlignment:前者制定了節區在記憶體中的最小單位,後者制定了節區在磁碟檔案中的最小單位
      • SizeOfImage:指定了PE Image在虛擬記憶體中所佔空間的大小
      • SizeOfHeaders:指出整個PE頭的大小
      • Subsystem:區分系統驅動檔案和普通可執行檔案
      • NumberOfRvaAndSize:指定DataDirectory陣列的個數
      • DataDirectory:由IMAGE_DATA_DIRECTORY結構體組成的陣列
  4. 節區頭

    節區頭中定義了各節區的屬性,包括不同的特性、訪問許可權等,結構體為IMAGE_SECTION_HEADER,重要成員有5個:

    • VirtualSize:記憶體中節區所佔大小
    • VirtualAddress:記憶體中節區起始地址(RVA)
    • SizeOfRawData:磁碟檔案中節區所佔大小
    • Charateristics:節區屬性(bit OR)

四、RVA To RAW

PE檔案從磁碟到記憶體的對映:

  1. 查詢RVA所在節區

  2. 使用簡單的公式計算檔案偏移:

    RAW - PointerToRawData = RVA - ImageBase

    RAW = RVA - ImageBase + PointerToRawData

example:ImageBase為0x10000000,節區為.text,檔案中起始地址為0x00000400,記憶體中的起始地址為0x01001000,RVA = 5000,RAW = 5000 - 1000 + 400 = 4400。

相關文章