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

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 閱讀(934) 評論(0)  編輯 收藏 引用 所屬分類: Windows開發

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(17)

隨筆分類(138)

隨筆檔案(137)

網絡開發

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 501927
  • 排名 - 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>
            欧美高清不卡在线| 国产亚洲福利社区一区| 在线亚洲免费| 中文av一区二区| 性欧美videos另类喷潮| 香蕉久久夜色精品国产| 久久gogo国模裸体人体| 久久综合久色欧美综合狠狠 | 欧美精品在线观看| 欧美日韩精品一区二区三区四区| 欧美三日本三级少妇三2023| 国产精品久久久久久久一区探花| 国产午夜亚洲精品不卡| 亚洲精品乱码久久久久久蜜桃91| 亚洲社区在线观看| 久久午夜av| 日韩视频一区二区在线观看 | 亚洲性线免费观看视频成熟| 欧美一区影院| 欧美日韩国产成人在线观看| 国产美女高潮久久白浆| 亚洲精品久久嫩草网站秘色 | 国产日韩亚洲欧美| 亚洲精品久久久一区二区三区| 欧美亚洲网站| 亚洲欧洲一区二区在线播放| 一区二区三区av| 免费精品99久久国产综合精品| 国产精品嫩草99av在线| 亚洲国产精品久久久| 欧美亚洲三区| 99国内精品久久| 美女图片一区二区| 国产视频精品xxxx| 欧美电影资源| 亚洲大胆女人| 午夜精品一区二区三区四区| 欧美激情一二区| 国产亚洲美州欧州综合国| 9l国产精品久久久久麻豆| 久久久久国色av免费观看性色| 99re热这里只有精品视频| 免费观看在线综合| 亚洲电影一级黄| 久久天天躁狠狠躁夜夜爽蜜月 | 亚洲欧美999| 欧美极品aⅴ影院| 影视先锋久久| 久久久噜久噜久久综合| 一本色道久久99精品综合 | 国产精品国产亚洲精品看不卡15 | 麻豆久久婷婷| 亚洲欧美变态国产另类| 欧美日韩一二区| 亚洲人成网站777色婷婷| 狂野欧美激情性xxxx欧美| 亚洲欧美日本伦理| 欧美性猛交xxxx乱大交蜜桃| 日韩视频在线一区二区| 欧美激情黄色片| 欧美高清免费| 亚洲视频一区在线观看| 夜夜爽夜夜爽精品视频| 欧美性猛交xxxx乱大交蜜桃| 亚洲一区二区三区激情| 亚洲天堂男人| 国产日韩视频一区二区三区| 久久久一本精品99久久精品66| 欧美一级精品大片| 狠狠色2019综合网| 国产日产精品一区二区三区四区的观看方式 | 国产日韩欧美在线播放| 久久精品亚洲一区二区| 亚洲一区综合| 国产综合欧美在线看| 久久婷婷麻豆| 欧美jjzz| 午夜欧美大尺度福利影院在线看 | 亚洲电影自拍| 免费成人在线视频网站| 亚洲最新色图| 在线观看欧美亚洲| 一区二区在线观看视频| 亚洲国产精品第一区二区三区| 精品va天堂亚洲国产| 黄色成人av| 日韩一级黄色大片| 国产精品国产三级国产普通话三级| 久久九九久精品国产免费直播| 欧美电影免费观看大全| 亚洲午夜女主播在线直播| 亚洲视频免费观看| 亚洲婷婷在线| 久久精品中文字幕一区二区三区| 韩国av一区二区三区四区| 女女同性精品视频| 久久亚洲春色中文字幕久久久| 一区二区精品| 亚洲免费视频观看| 久久国产加勒比精品无码| 91久久精品网| 亚洲影院在线| 亚洲精品一级| 久久福利影视| 在线午夜精品| 久久一二三区| 羞羞漫画18久久大片| 欧美高清视频一区二区| 久久精品亚洲一区| 欧美人与禽猛交乱配视频| 久久精品一区二区三区四区| 欧美日韩国产123| 美玉足脚交一区二区三区图片| 欧美日本高清| 欧美刺激性大交免费视频| 国产视频观看一区| 亚洲欧美电影院| 亚洲欧美国产日韩天堂区| 欧美激情一区在线| 亚洲电影免费在线观看| 国产一区二区三区不卡在线观看| 99这里只有精品| 日韩天堂在线视频| 免费高清在线视频一区·| 久久亚洲精品伦理| 国产一区二区三区久久 | 男女精品视频| 欧美日韩在线三区| 亚洲大片精品永久免费| 亚洲成人直播| 久久综合久久综合久久综合| 久久夜色精品国产欧美乱极品| 国产人妖伪娘一区91| 亚洲男女自偷自拍图片另类| 亚洲欧美精品| 国产精品有限公司| 性做久久久久久久免费看| 先锋影院在线亚洲| 国产欧美日韩在线视频| 亚洲欧美日韩中文播放| 欧美专区在线| 一区二区三区自拍| 理论片一区二区在线| 欧美高清成人| 亚洲另类在线视频| 欧美日韩欧美一区二区| 中国女人久久久| 久久久成人精品| 亚洲高清视频一区| 欧美精品在线播放| 亚洲综合国产| 美女免费视频一区| 99视频有精品| 国产伦精品一区二区| 久久久精品国产一区二区三区 | 亚洲网站视频| 国产精品大片wwwwww| 亚洲欧美视频在线观看| 美女精品网站| 中文精品视频| 国产日韩欧美中文在线播放| 久久亚洲私人国产精品va| 亚洲第一精品久久忘忧草社区| 亚洲视频久久| 精品999网站| 欧美日韩免费观看一区=区三区| 在线一区二区三区四区五区| 欧美在线一二三四区| 黄网站色欧美视频| 欧美日韩国产小视频| 性欧美大战久久久久久久久| 欧美激情精品久久久久| 性欧美1819sex性高清| 亚洲福利视频在线| 国产精品亚洲综合久久| 欧美aaa级| 久久精品女人天堂| 亚洲视频一二| 亚洲高清网站| 久久男人av资源网站| 亚洲精选成人| 一区二区视频免费在线观看| 国产精品日韩专区| 欧美日韩成人一区二区| 久久精品中文字幕一区| 9i看片成人免费高清| 欧美成人乱码一区二区三区| 欧美亚洲日本国产| 亚洲在线网站| 99国产精品自拍| 在线观看亚洲专区| 国产欧美精品一区aⅴ影院| 欧美精品一区二区在线播放| 久久精品99国产精品日本| 一区二区成人精品 | 亚洲日韩成人| 亚洲成人在线视频播放| 国产久一道中文一区| 欧美日韩另类综合| 欧美精品1区2区3区|