PE文件學習系列二 DOS頭分析

合肥程序員羣:49313181。    合肥實名程序員羣 :128131462 (不肯透露姓名和信息者勿加入)
Q  Q:408365330     E-Mail:egojit@qq.com

PE文件結構綜覽:程序員

首先上圖片:windows

看到上面的圖片能夠清晰的看到PE結構複雜結構式什麼樣子的。有DOS首部,PE頭部,PE節表,不少的表塊,最後就是一些調試信息。數據結構

DOS頭由DOS 'MZ' HEADER 和DOS stub組成,DOS "MZ"頭中的MZ是PE文件的一個標誌之一。後期咱們在寫PE小工具的時候這個會被咱們用於去識別PE文件。ide

首先咱們來理解DOS頭。咱們知道Windows系統主體是由C去完成的。全部咱們能夠在windows中去找到用C描述的DOS頭結構。工具

DOS頭分析:spa

第一個就是WinNT.h在我計算機中位置。打開後咱們就能看到咱們想要的DOS頭數據結構了。3d

 1 typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
 2 +0   WORD   e_magic;                     // Magic number
 3 +2   WORD   e_cblp;                      // Bytes on last page of file
 4 +4   WORD   e_cp;                        // Pages in file
 5 +6   WORD   e_crlc;                      // Relocations
 6 +8   WORD   e_cparhdr;                   // Size of header in paragraphs
 7 +A   WORD   e_minalloc;                  // Minimum extra paragraphs needed
 8 +C   WORD   e_maxalloc;                  // Maximum extra paragraphs needed
 9 +E   WORD   e_ss;                        // Initial (relative) SS value
10 +10   WORD   e_sp;                        // Initial SP value
11 +12   WORD   e_csum;                      // Checksum
12 +14    WORD   e_ip;                        // Initial IP value
13 +16    WORD   e_cs;                        // Initial (relative) CS value
14 +18    WORD   e_lfarlc;                    // File address of relocation table
15 +1A    WORD   e_ovno;                      // Overlay number
16 +1C    WORD   e_res[4];                    // Reserved words
17 +24    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
18 +26    WORD   e_oeminfo;                   // OEM information; e_oemid specific
19 +28    WORD   e_res2[10];                  // Reserved words
20 +3C    LONG   e_lfanew;                    // File address of new exe header
21   } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

咱們能夠看到這樣一個結構體這個結構體就是DOS 頭結構體,Windows不少數據都是經過這樣的結構體去組織的。前面的"+數字"是我添加上去的,WinNT.H頭文件中沒有的,這個表示偏移地址。在這裏我默認狀況是你知道什麼是偏移地址,Windows的內存基址。不然一些東西你是沒法理解的。固然這個數字是16進製表示的。調試

咱們用一個UE打開一個PE文件,也就是exe程序。(固然DLL也是PE文件,遵循PE結構。可是咱們這裏默認就是EXE程序),我打開我收集的一個內存查看工具:code

入下圖:orm

能夠看+0H這個位置開始的2個字節(我在這裏假設了解windows下的WORD類型是兩個字節)。這兩個字節也就是e_magic中的內容是MZ。DOS頭中咱們關注的另外一個內容就是最後一個成員也就是+3Ch這個位置,也就是佔四個字節的e_lfanew。(你們要知道32位機器中long型和DWORD型是同樣的4個字節),DOS頭中咱們關注這兩個內容。e_lfanew這個是爲了存儲PE頭的偏移地址。那爲何要這個呢??DOS頭後面不就是PE頭了麼?也就是+3Ch位置後面不就是PE頭了麼?其實不是我麼這裏的DOS頭不是廣義上的。廣義上的DOS頭還有一個。DOS stub 這個DOS stub的大小是不固定的,既然這個不固定那麼廣義上的DOS頭的大小也就是不固定。廣義DOS頭不固定,那咱們怎麼定位PE頭,那就離不開這個四字節的e_lfanew了。e_lfanew中存儲了PE頭的偏移地址。e_lfanew的位置在+3Ch位置。由於小端存儲方式。因此就是上面圖中畫紅線框中的倒過來,那麼PE頭的開始位置是 "0x00 00 0100",也就是16進制的100處。這樣咱們很容易的就定位到了PE頭。

這裏就提早讓你們看一下PE頭結構吧:

1 typedef struct _IMAGE_NT_HEADERS {
2 +00h    DWORD Signature;
3 +04h    IMAGE_FILE_HEADER FileHeader;
4  ???    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
5 } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;


這個是廣義上的PE頭結構。這個結構的+00h處其實就是e_lfanew中偏移指向的位置總PE文件開始處的+3Ch處就是這個Signature相對文件開始的偏移(咱們稱FOA,也就是文件相對偏移地址,這個要和虛擬地址相對偏移RVA區分開,後續我會介紹FOA和RVA的裝換方式,這樣咱們就能夠在內存中定位數據了)。Signature中的四個字節內容其實就是"PE00",也就是+3Ch中的內容"0x00 00 0100"所指向的位置中的內容,100h位置中的四個字節中ASIIC就是「PE00」,這個是PE文件的標誌符,e_magic,+0地址開始的2個字節中的「MZ」,和Signature 的+3C開始位置的四個字節內容「PE00」共同標誌這就是PE文件。咱們後期寫的PE工具,判斷PE就是有這兩個位置的數據去區分是否是Windows PE文件。

這一節到此位置。後面將和你們探討PE head結構。

 

版權:歸博客園和Egojit全部,轉載請標明出處。
相關文章
相關標籤/搜索