iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 10
7
Security

資事體大 毒擋一面 - 資安防護深入淺出系列 第 10

[Day10] 格式透視 - 解析 PE 文件格式(前篇)

  • 分享至 

  • xImage
  •  

俗話說的好,知己知彼百戰百勝;要防範它,先瞭解它。
因此今天的主題就是簡單介紹程式身家基本訊息:PE file structure
PE 是 Portable Executable 的縮寫,也就是 Windows 系統中的可執行(Executable)程式或動態連結函式庫(Dynamic link library)的文件格式,主要使用在 32 位和 64 位的 Windows 操作系统上。

為了能夠瞭解 PE 格式,我們需要以下的對照:

1. PE 格式示意圖

PE 格式示意圖

2.Hiew 程式,以小算盤為範例

Hiew

3.PE 格式圖

PE格式圖

泥馬,這麼多密密麻麻的東西,誰想看!挑釁挑釁挑釁挑釁挑釁挑釁

莫急莫慌莫害怕,只要冷靜下來找時光機把範圍劃分出來便可一目了然
PE分區塊

以下為簡單對照

DOS MZ Header

開頭必定為"MZ"4D 5A,這是 DOS EXE 的 Signature。而這東西讓 PE file 在 DOS 模式下也可執行,所佔大小為 40h bytes。

DOS Stub

但也不是什麼都能在 DOS 底下執行,若是程式在 DOS 下無法執行便會跳出這邊的錯誤訊息:"This Program cannot be run in DOS mode"。

PE Header

為了找到 PE 的開頭位置,我們可從 DOS Header 0x3C 的位置找到一個 Double word(又稱 dword,大小為 4 個 bytes),這個 dword 大小表示了整個 DOS MZ Header 的 size,
http://ithelp.ithome.com.tw/upload/images/20161225/20103559wl5pVInFi4.png
也就是 D8 00 00 00,注意!這裡實際位置是 0x000000D8,想必 IQ180 的各位已經注意到必須以 Byte 為單位顛倒過來看才行,這種反向讀取方式稱之為 Little-endian order,在 PE 文件中皆採用此種讀取方式。

到了 PE 位置所看到的必定是 50 45,PE Header 裡包含了許許多多的訊息,其中最重要之一就是距離 PE 位置(0xD8)後 0x28 的 dword,這裡是這隻程式執行時的入口點(Entry point)。聽起來好像沒什麼重要的,不過若是入口點被設置在檔案的 Overlay 區域呢?這就很有趣了~正常來說是不會設置在這邊的。

什麼是 Overlay? 這個以後會再說  嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿
再往後數 12 Bytes 則是 Image base,下圖最後 4 Bytes,也就是 0x01000000
ImageBase
之前找到的入口點是相對虛擬位置(Relative virtual address, RVA)必須還得加上 ImageBase 才是真正的位置(Virtual address, VA)!

什麼是 RVA ?

RVA 就是虛擬空間中到參考點的距離,也就是虛擬空間中的偏移量。舉上面的例子來說:小算盤被放入虛擬地址(Virtual address, VA)的 01000000h 處,且入口點的 RVA 在 0x102D6Ch 處,那在虛擬空間之中真正入口起始位置是 0x01000000 + 0x102D6C = 0x01102D6C。

Section Header

如果 PE file 之中有 4 個區段(section),Section Table 就會有 4 個成員,每個成員包含對應區段的屬性、內存大小、偏移量等訊息

Section

PE file 裡的內容,被劃分成各個區段,每個區段的名子以 ” . ” 當作開頭,以下是常見的區段名和作用:

區段名 作用
.data 已初始化的數據
.idata 導入(import)的文件名表
.edata 導出(export)的文件名表
.rdata 只能讀的初始化數據(無法修改)
.reloc 重定位表信息
.rsrc 資源
.text Exe 或 dll 文件的可執行程式碼

當 PE file 被執行時,PE 裝載器先檢查 DOS MZ Header 中的 PE Header 偏移量,若找到則跳到 PE Header 所在位置。接著檢查 PE header 是否有效,若有則跳到 Section Table 頭部,讀取訊息並利用文件映射(file mapping)的方法將這些區段映射到記憶體中。

希望有興趣的讀者也能夠點個追蹤,有任何問題或有想多了解的地方也可以回覆在文章底下唷,謝謝你們XDDDD!

參考來源:
維基百科 https://en.wikipedia.org/wiki/Portable_Executable


上一篇
[Day09] 聖誕特輯 - 邊緣人在家打文章QQ,聖誕節病毒
下一篇
[Day11] 格式透視 - 解析 PE 文件格式(後篇)
系列文
資事體大 毒擋一面 - 資安防護深入淺出31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jack1234552000
iT邦新手 5 級 ‧ 2021-03-29 09:35:55

請問一下
DOS MZ Header ,Stub
裡頭講解提到的數字還有D8 00 00 00
是您舉例的小算盤嗎

還是每個程式都這樣
因為沒有這方面基礎 這邊是完全看不懂

小茶 iT邦新手 4 級 ‧ 2021-05-08 13:45:39 檢舉

Hi jack1234552000
抱歉有段時間沒登入,隔太久才回覆您的問題,感謝提問唷!
其實都有在看IT鐵人,只是不常登入/images/emoticon/emoticon25.gif
0x0000003C 位置的 D8 00 00 00 會指向 PE header 開始的 address,也等於 MZ DOS header 與 Stub 的 size 總和,因為此指向的位置會受到 Stub size 的影響,所以此欄位的值並非固定的唷。

至於 Stub 的內容是做什麼的呢? 推薦可以看看這篇
Exploring the MS-DOS Stub
根據文章中提到

It is a simple 16-bit assembly program which prints This program cannot be run in DOS mode and exit.
If we run this 64-bit PE inside DOS, the stub will execute, and we get that message.
This program cannot be run in DOS mode.

因為 DOS 的 executable file 同樣具有 MZ header,這樣的 Stub 設計可以使得程式在 DOS 中執行時能夠顯示"此程式無法在 DOS mode 中執行" 並中斷離開,以避免因為 format 問題造成後續錯亂。

我要留言

立即登入留言