青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

aurain
技術文摘
posts - 137,  comments - 268,  trackbacks - 0
來源:安全中國

零 前言

    PE格式,是Windows的可執行文件的格式。Windows中的 exe文件,dll文件,都是PE格式。PE 就是Portable Executable 的縮寫。Portable 是指對于不同的Windows版本和不同的CPU類型上PE文件的格式是一樣的,當然CPU不一樣了,CPU指令的二進制編碼是不一樣的。只是文件中各種東西的布局是一樣的。

 

圖 1.1

    圖1.1是 JIURL PEDUMP 打開 Win2K 中的 explorer.exe 的截圖。JIURL PEDUMP 是我寫的一個小工具,從文件開始的 Dos Header 一直到 Section Table,打開PE文件之后,點擊相應結構,就會高亮顯示文件中相應的部分。不過沒有Sections。對了解 PE 格式有所幫助,可以很好的配合后面的介紹。可以到我的主頁 http://jiurl.yeah.net/ 上下載。

一   PE文件格式概述

PE文件結構的總體層次分布如下所示

 --------------
|DOS MZ Header |
|--------------|
|DOS Stub      |
|--------------|
|PE Header     |
|--------------|
|Section Table |
|--------------|
|Section 1     |
|--------------|
|Section 2     |
|--------------|
|Section ...   |
|--------------|
|Section n     |
 --------------

 

1.1 DOS Header

    PE文件最開始是一個簡單的 DOS MZ header,它是一個 IMAGE_DOS_HEADER 結構。有了它,一旦程序在DOS下執行,DOS就能識別出這是有效的執行體,然后運行緊隨 MZ Header 之后的 DOS Stub。

 1.2  DOS Stub   

    DOS Stub 是一個有效的 DOS 程序。當程序在DOS下運時,輸出象 "This program cannot be run in DOS mode" 這樣的提示。在 圖1.1中就可以看到字符串 "This program cannot be run in DOS mode"。這是編譯器生成的默認stub程序。你也可以通過鏈接選項 /STUB:filename 指定任何有效的MS-DOS可執行文件來替換它。

1.3 PE Header

    緊接著 DOS Stub 的是 PE Header。它是一個 IMAGE_NT_HEADERS 結構。其中包含了很多PE文件被載入內存時需要用到的重要域。執行體在支持PE文件結構的操作系統中執行時,PE裝載器將從 DOS MZ header 中找到 PE header 的起始偏移量。因而跳過了 DOS stub 直接定位到真正的文件頭 PE header。

1.4 Section Table

    PE Header 接下來的數組結構 Section Table (節表)。如果PE文件里有5個節,那么此 Section Table 結構數組內就有5個成員,每個成員包含對應節的屬性、文件偏移量、虛擬偏移量等。圖1中的節表有4個成員。

1.5 Sections

    PE文件的真正內容劃分成塊,稱之為sections(節)。Sections 是以其起始位址來排列,而不是以其字母次序來排列。通過節表提供的信息,我們可以找到這些節。圖1.1所示的 explorer.exe 中有4個節。程序的代碼,資源等等就放在這些節中。

二  PE文件格式中的結構及其作用

這部分內容請參考下面的幾篇文章,使用工具 JIURL PEDUMP 有助于快速了解。
大家不要因此,而失望不看,本文重點在后三篇,本篇只是為了有個交代,和介紹些相關內容。
注意,在WINNT.H中,有所有PE相關結構的定義。我們用到的結構定義都來自那里。

Microsoft Portable Executable and Common Object File Format Specification
MSDN 

《Windows95系統程式設計大奧秘》
第8章 PE 與COFF OBJ 檔案格式
Matt Pietrek 著 侯杰譯

Iczelion的PE教程

PE學習筆記(一) rivershan
PE學習筆記(二) rivershan

Inside Windows 
An In-Depth Look into the Win32 Portable Executable File Format 
Matt Pietrek 
已經被人翻譯了。

Inside Windows 
An In-Depth Look into the Win32 Portable Executable File Format 
Matt Pietrek

三 幾個要注意的問題

3.1 文件中大量的空白

    在 PE Header結構 中的 OptionalHeader 結構中的成員 FileAlignment 的值是文件中節的對齊粒度,單位是字節,這個值應該是2的n次方,范圍從512到64k。如果這里的值是512,那么PE文件中的節的長度都是512字節的整數倍,內容不夠的部分用0填充。比如一個PE文件的 FileAlignment 為200h(十進制512),它的第一個節在400h處,長度為100h,那么從文件400h到500h中為這一節的內容,而文件對齊粒度是200h,所以為了使這一節長度為FileAlignment的整數倍,500h到600h會被用零填充。而下一個節的開始地址為600h。用16進制編輯器打開PE文件,就可以看到這種情況,PE文件頭的內容結束到第一個節開始之間的地方,每一個節中內容結束到下一節開始的地方都會有大量的空白。VC6編譯鏈接時默認的FileAlignment為1000h(4k),可以使用鏈接選項 /ALIGN:number 來改變這個值。比如把4k改成512時,可以明顯減小生成文件的大小。

3.2 big-endian和little-endian

    PE Header中的 FileHeader 的成員 Machine 中的值,根據WINNT.H中的定義,對于 Intel CPU 應該為 0x014c。但是你用16進制編輯器打開PE文件,看到這個WORD顯示的卻是 4c 01 。你看到的并沒有錯,你看到的 4c 01 就是 0x014c,只不過由于 intel cpu 是ittle-endian,所以顯示出來是這樣的。對于 big-endian 和 little-endian,請看下面的例子。

比如一個整形int變量。長為四個字節。
這個變量的地址比如為n。
則這個變量的4個字節地址分別為n,n+1,n+2,n+3。

當 這個整形變量 的值為 0x12345678 時,

對于 big-endian 來說
地址n+0的那個字節中的值為 0x12
地址n+1的那個字節中的值為 0x34
地址n+2的那個字節中的值為 0x56
地址n+3的那個字節中的值為 0x78

按如下方式就會顯示為
n n+1 n+2 n+3 
12 34 56 78

對于 ittle-endian 來說
地址n+0的那個字節中的值為 0x78
地址n+1的那個字節中的值為 0x56
地址n+2的那個字節中的值為 0x34
地址n+3的那個字節中的值為 0x12

按如下方式就會顯示為
n n+1 n+2 n+3 
78 56 34 12

Intel使用的是 ittle-endian 。

一個整形 int 變量 i,的地址是&i,那么這個i的四個字節是&i,&i+1,&i+2,&i+3。
可以用這樣一個程序看到。

#include <stdio.h>
#include <conio.h>

void main()
{
int i;
char* p;
p=(char*)&i;

printf("i: ");
scanf("%x",&i);
printf("\n");

printf("&i+0: %x\n",*p);
printf("&i+1: %x\n",*(p+1));
printf("&i+2: %x\n",*(p+2));
printf("&i+3: %x\n",*(p+3));

printf("\n");
printf("&i-4: %x\n",*(p-4));
printf("&i-3: %x\n",*(p-3));
printf("&i-2: %x\n",*(p-2));
printf("&i-1: %x\n",*(p-1));

printf("\n");
printf("&i+4: %x\n",*(p+4));
printf("&i+5: %x\n",*(p+5));
printf("&i+6: %x\n",*(p+6));
printf("&i+7: %x\n",*(p+7));

getch();

}

當我們輸入 12345678 的時候可以看到,輸出

i: 12345678

&i+0: 78
&i+1: 56
&i+2: 34
&i+3: 12

&i-4: 7c
&i-3: ffffffff
&i-2: 12
&i-1: 0

&i+4: ffffffc0
&i+5: ffffffff
&i+6: 12
&i+7: 0
正是&i,&i+1,&i+2,&i+3這四個字節中儲存了i的值。

對于int,WORD,DWORD等等都要注意 big-endian 和 little-endian 。

3.3 RVA (Relative Virtual Address) 相對虛擬地址

    RVA是一個簡單的相對于PE載入點的內存偏移。比如,PE載入點為0X400000,那么代碼節中的地址0X401000的RVA為(target address) 0x401000 - (load address)0x400000 = (RVA)0x1000.換句話說 RVA是0x1000,載入點為0X400000,那么該RVA的在內存中的實際地址就是0X401000。注意一下RVA是指內存中,不是指文件中。是指相對于載入點的偏移而不是一個內存地址,只有RVA加上載入點的地址,才是一個實際的內存地址。

3.4 三種不同的地址

    PE的各種結構中,涉及到很多地址,偏移。有些是指在文件中的偏移,有的是指在內存中的偏移。一定要搞清楚,這個地址或者是偏移,是指在文件中,還是指在內存中。第一種,文件中的地址。比如用16進制編輯器打開PE文件,看到的地址(偏移)就是文件中的地址,我們使用某個結構的文件地址,就可以在文件中找到該結構。第二種,文件被整個映射到內存時,比如某些PE分析軟件,把整個PE文件映射到內存中,這時是內存中的地址,如果知道某一個結構在文件中的地址的話,那么這個PE文件被映射到內存之后該結構的在內存中的地址,可以用文件中的地址加上映射內存的地址,就可以得到在該結構內存中的地址。第三種,執行PE時,PE文件會被載入器載入內存,這時經常需要的是RVA。比如知道一個結構的RVA,那么載入點加上RVA就可以得到內存中該結構的實際地址。比如,某個程序,我們用16進制編輯器打開它,看到PE Header開始在16進制編輯器顯示為000000C8的地方。于是我們在16進制編輯器顯示為000000FC的地方找到了OptionalHeader的ImageBase,值為400000h,那么當這個程序被執行時,如果內存中400000h處沒有使用,該程序就會被載入到那里。而我用CreateFileMapping將這個PE文件映射到內存中時,可以得到塊內存的地址為5505024。對于映射入內存的這個PE文件,我們就可以在內存中000000FCh+05505024h=5505120處找到這個PE的OptionalHeader的ImageBase。

3.5 幾個重要結構的說明

PE Header 的 FileHeader 的 NumberOfSections:這是一個很重要的字段,用來確定文件中節的數目。

PE Header 的 OptionalHeader 的 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]:一個IMAGE_DATA_DIRECTORY 結構數組。到目前為止這個數組的長度是固定的,有16個元素,這16個元素分別代表
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
每個元素是一個IMAGE_DATA_DIRECTORY結構,IMAGE_DATA_DIRECTORY定義如下。
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
第一個字段是一個RVA,第二個字段是一個大小。

Section Table 節表緊跟在OptionalHeader之后,是一個IMAGE_SECTION_HEADER結構的數組。該數組中成員的個數由 File Header (IMAGE_FILE_HEADER) 結構中 NumberOfSections 域的域值來定。節表中的成員是IMAGE_SECTION_HEADER 結構,IMAGE_SECTION_HEADER 結構的長度固定,長40個字節。整個Section Table 的長度不固定,等于 NumberOfSections*sizeof(IMAGE_SECTION_HEADER)。IMAGE_SECTION_HEADER 結構中,
VirtualAddress:本節的RVA(相對虛擬地址)。
PointerToRawData:這是本節基于文件的偏移量。

3.6 DOS MZ Header 中的 MZ

    MZ是MZ格式的主要作者 Mark Zbikowski 的名字的縮寫。

posted on 2009-06-29 13:45 閱讀(937) 評論(0)  編輯 收藏 引用 所屬分類: Windows開發

<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(17)

隨筆分類(138)

隨筆檔案(137)

網絡開發

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 502446
  • 排名 - 37

最新隨筆

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久精品欧美丰满| 欧美成人一区二区三区| 性8sex亚洲区入口| 亚洲免费在线看| 欧美一区亚洲一区| 久久精品成人欧美大片古装| 久久精品国产99| 久久亚洲色图| 欧美精品色网| 国产精品狠色婷| 国产亚洲欧美另类一区二区三区| 亚洲午夜羞羞片| 亚洲欧美激情一区| 久久精品国产精品亚洲| 美女露胸一区二区三区| 欧美精品日韩www.p站| 国产精品高清在线| 国产色爱av资源综合区| 亚洲第一福利社区| 一二三区精品福利视频| 午夜视频久久久久久| 久久久久一区二区三区| 欧美激情欧美激情在线五月| 日韩网站免费观看| 午夜精品区一区二区三| 美女日韩欧美| 欧美精品日韩| 国产区精品在线观看| 18成人免费观看视频| 99精品欧美一区二区三区| 午夜在线视频观看日韩17c| 久热精品视频在线观看一区| 91久久精品国产91久久| 亚洲手机视频| 久久色在线播放| 欧美私人啪啪vps| 一区二区三区中文在线观看| 日韩视频在线免费观看| 久久精品成人一区二区三区蜜臀 | 国产精品女主播一区二区三区| 久久久噜噜噜久久中文字免| 欧美精品播放| 国产一区在线免费观看| 亚洲美女一区| 久久久99国产精品免费| 亚洲人成人99网站| 欧美在线视频在线播放完整版免费观看| 亚洲网站在线播放| 久久日韩粉嫩一区二区三区| 国产精品二区二区三区| 一区二区三区在线看| 亚洲一区美女视频在线观看免费| 一区二区电影免费在线观看| 久久久精品tv| 99精品国产在热久久| 久久亚裔精品欧美| 国产精品一二三视频| 日韩午夜av电影| 美女脱光内衣内裤视频久久网站| 美女诱惑一区| 亚洲一区二区三区在线观看视频| 亚洲视频在线一区观看| 乱中年女人伦av一区二区| 国产精品乱码人人做人人爱| 亚洲精选中文字幕| 久久午夜精品一区二区| 亚洲一区二区三区色| 欧美人与禽猛交乱配| 国语自产偷拍精品视频偷 | 午夜精彩视频在线观看不卡| 欧美高清视频www夜色资源网| 欧美精品1区2区3区| 狠狠入ady亚洲精品经典电影| **性色生活片久久毛片| 欧美在线视频导航| 夜夜嗨av一区二区三区| 欧美精品九九| 最新国产精品拍自在线播放| 久久久国产视频91| 亚洲欧美清纯在线制服| 国产精品二区在线| 亚洲在线播放电影| 日韩视频专区| 欧美日韩国产探花| 亚洲精品女av网站| 欧美激情一区二区三区蜜桃视频 | 亚洲精品免费一二三区| 久久午夜影视| 欧美中文在线字幕| 国产日韩欧美亚洲| 欧美在线播放高清精品| 亚洲欧美怡红院| 国产精品视频最多的网站| 国产精品99久久久久久宅男| 亚洲人成网站影音先锋播放| 欧美激情a∨在线视频播放| 亚洲欧洲一区二区三区在线观看 | 久久精品中文| 国产私拍一区| 久久久亚洲国产天美传媒修理工| 亚洲黄色有码视频| 欧美激情精品久久久久久变态| 国产精品美女主播| 亚洲欧美亚洲| 午夜免费日韩视频| 国内在线观看一区二区三区| 另类专区欧美制服同性| 久久久五月婷婷| 亚洲黄色精品| 亚洲日本va午夜在线影院| 欧美日韩精品免费观看视一区二区 | 欧美一区网站| 国产综合久久久久久| 久久久精品999| 久久女同互慰一区二区三区| 亚洲激情啪啪| 99国产精品久久久久久久久久 | 亚洲人成网站色ww在线| 欧美日韩国产丝袜另类| 午夜国产不卡在线观看视频| 亚洲影院一区| 狠狠做深爱婷婷久久综合一区 | 久久精品国产99精品国产亚洲性色| 欧美日韩在线视频观看| 亚洲午夜高清视频| 亚洲一区日本| 狠狠色狠狠色综合人人| 亚洲成人在线视频网站| 欧美日本中文字幕| 欧美一区二区三区男人的天堂| 99国产精品久久久| 国产精品欧美日韩一区二区| 久久综合伊人77777| 欧美激情欧美激情在线五月| 亚洲欧美精品在线观看| 欧美一区影院| 亚洲伦理网站| 亚洲免费在线视频一区 二区| 欧美小视频在线| 久久精品官网| 欧美肥婆bbw| 欧美一级成年大片在线观看| 久久夜色精品国产噜噜av| 亚洲午夜伦理| 久久亚洲国产精品日日av夜夜| 精品不卡在线| 99re6热在线精品视频播放速度 | 久久久久久国产精品mv| 99精品久久久| 性色一区二区| 99精品久久久| 久久精品夜色噜噜亚洲aⅴ| 亚洲视频大全| 久久影院亚洲| 久久aⅴ国产紧身牛仔裤| 欧美激情在线播放| 久久久av网站| 国产精品videosex极品| 欧美成人综合网站| 国产精品自在欧美一区| 亚洲日本视频| 在线观看亚洲a| 亚洲一区二区影院| 亚洲破处大片| 久久国产精品久久久| 亚洲欧美日韩另类| 欧美国产精品久久| 免费成人毛片| 国产视频在线观看一区| 99精品福利视频| 亚洲人成人77777线观看| 欧美在线高清| 亚洲伊人网站| 欧美破处大片在线视频| 免费亚洲一区二区| 国产亚洲一区二区在线观看 | 亚洲第一二三四五区| 国产亚洲一区二区三区在线观看| 久久亚洲捆绑美女| 国产麻豆91精品| 中日韩美女免费视频网址在线观看| 国产美女一区| 中文av一区特黄| 亚洲视频1区| 欧美精品videossex性护士| 蜜臀久久久99精品久久久久久| 欧美激情免费观看| 欧美激情片在线观看| 在线观看日韩专区| 久久www成人_看片免费不卡| 先锋影音久久| 国产精品久久久久久久久久久久久| 久久久免费av| 国产一区在线看| 午夜久久99| 久久久国际精品| 韩国欧美国产1区| 久久精品在这里| 免费观看成人鲁鲁鲁鲁鲁视频| 欧美色视频日本高清在线观看|