freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

windows下的可執(zhí)行文件格式詳解(編輯修改稿)

2024-10-11 20:33 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 的值。它首先決定每個(gè)段需要多少字節(jié),并且最后將頁(yè)面總數(shù)向上取整至最接近的 SectionAlignment 邊界,然后總數(shù)就是每個(gè)段個(gè)別需求之和了。 SizeOfHeaders。這個(gè)域表示文件中有多少空間用來(lái)保存所有的文件頭部,包括 MSDOS 頭部、PE 文件頭部、 PE 可選頭部以及 PE 段 頭部。文件中所有的段實(shí)體就開(kāi)始于這個(gè)位置。 CheckSum。校驗(yàn)和是用來(lái)在裝載時(shí)驗(yàn)證可執(zhí)行文件的,它是由鏈接器設(shè)置并檢驗(yàn)的。由于創(chuàng)建這些校驗(yàn)和的算法是私有信息,所以在此不進(jìn)行討論。 Subsystem。用于標(biāo)識(shí)該可執(zhí)行文件目標(biāo)子系統(tǒng)的域。每個(gè)可能的子系統(tǒng)取值列于 的IMAGE_OPTIONAL_HEADER 結(jié)構(gòu)之后。 DllCharacteristics。用來(lái)表示一個(gè) DLL 映像是否為進(jìn)程和線程的初始化及終止包含入口點(diǎn)的標(biāo)記。 SizeOfStackReserve、 SizeOfStackCommit、 SizeOfHeapReserve、 SizeOfHeapCommit。這些域控制要保留的地址空間數(shù)量,并且負(fù)責(zé)棧和默認(rèn)堆的申請(qǐng)。在默認(rèn)情況下,棧和堆都擁有 1 個(gè)頁(yè)面的申請(qǐng)值以及 16 個(gè)頁(yè)面的保留值。這些值可以使用鏈接器開(kāi)關(guān) STACKSIZE:與 HEAPSIZE:來(lái)設(shè)置。 LoaderFlags。告知裝載器是否在裝載時(shí)中止和調(diào)試,或者默認(rèn)地正常運(yùn)行。 NumberOfRvaAndSizes。這個(gè)域標(biāo)識(shí)了接下來(lái)的 DataDirectory 數(shù)組。請(qǐng) 注意它被用來(lái)標(biāo)識(shí)這個(gè)數(shù)組,而不是數(shù)組中的各個(gè)入口數(shù)字,這一點(diǎn)非常重要。 DataDirectory。數(shù)據(jù)目錄表示文件中其它可執(zhí)行信息重要組成部分的位置。它事實(shí)上就是一個(gè)IMAGE_DATA_DIRECTORY 結(jié)構(gòu)的數(shù)組,位于可選頭部結(jié)構(gòu)的末尾。當(dāng)前的 PE 文件格式定義了 16 種可能的數(shù)據(jù)目錄,這之中的 11 種現(xiàn)在在使用中。 數(shù)據(jù)目錄 之中所定義的數(shù)據(jù)目錄為: // // 目錄入口 // 導(dǎo)出目錄 define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // 導(dǎo)入目錄 define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // 資源目錄 define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // 異常目錄 define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // 安全目錄 define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // 重定位基本表 define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // 調(diào) 試目錄 define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // 描述字串 define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // 機(jī)器值( MIPS GP) define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // TLS 目錄 define IMAGE_DIRECTORY_ENTRY_TLS 9 // 載入配置目錄 define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 基本上 ,每個(gè)數(shù)據(jù)目錄都是一個(gè)被定義為 IMAGE_DATA_DIRECTORY 的結(jié)構(gòu)。雖然數(shù)據(jù)目錄入口本身是相同的,但是每個(gè)特定的目錄種類卻是完全唯一的。每個(gè)數(shù)據(jù)目錄的定義在本文的以后部分被描述為 “預(yù)定義段 ”。 // typedef struct _IMAGE_DATA_DIRECTORY { ULONG VirtualAddress。 ULONG Size。 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY。 每個(gè)數(shù)據(jù)目錄入口指定了該目錄的尺寸 和相對(duì)虛擬地址。如果你要定義一個(gè)特定的目錄的話,就需要從可選頭部中的數(shù)據(jù)目錄數(shù)組中決定相對(duì)的地址,然后使用虛擬地址來(lái)決定該目錄位于哪個(gè)段中。一旦你決定了哪個(gè)段包含了該目錄,該段的段頭部就會(huì)被用于查找數(shù)據(jù)目錄的精確文件偏移量位置。 所以要獲得一個(gè)數(shù)據(jù)目錄的話,那么首先你需要了解段的概念。我在下面會(huì)對(duì)其進(jìn)行描述,這個(gè)討論之后還有一個(gè)有關(guān)如何定位數(shù)據(jù)目錄的示例。 PE 文件段 PE 文件規(guī)范由目前為止定義的那些頭部以及一個(gè)名為 “段 ”的一般對(duì)象組成。段包含了文件的內(nèi)容,包括代碼、數(shù)據(jù)、資源以及其它 可執(zhí)行信息,每個(gè)段都有一個(gè)頭部和一個(gè)實(shí)體(原始數(shù)據(jù))。我將在下面描述段頭部的有關(guān)信息,但是段實(shí)體則缺少一個(gè)嚴(yán)格的文件結(jié)構(gòu)。因此,它們幾乎可以被鏈接器按任何的方法組織,只要它的頭部填充了足夠能夠解釋數(shù)據(jù)的信息。 段頭部 PE 文件格式中,所有的段頭部位于可選頭部之后。每個(gè)段頭部為 40 個(gè)字節(jié)長(zhǎng),并且沒(méi)有任何的填充信息。段頭部被定義為以下的結(jié)構(gòu): // define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_SECTION_HEADER { UCHAR Name[IMAGE_SIZEOF_SHORT_NAME]。 union { ULONG PhysicalAddress。 ULONG VirtualSize。 } Misc。 ULONG VirtualAddress。 ULONG SizeOfRawData。 ULONG PointerToRawData。 ULONG PointerToRelocations。 ULONG PointerToLinenumbers。 USHORT NumberOfRelocations。 USHORT NumberOfLinenumbers。 ULONG Characteristics。 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER。 你如何才能獲得一個(gè)特定段的段頭部信息?既然段頭部是被連續(xù)的組織起來(lái)的,而且沒(méi)有一個(gè)特定的順序,那么段頭部必須由名稱來(lái)定位。以下的函數(shù)示范了如何從一個(gè)給定了段名稱的 PE 映像文件中獲得一個(gè)段頭部: // BOOL WINAPI GetSectionHdrByName(LPVOID lpFile, IMAGE_SECTION_HEADER *sh, char *szSection) { PIMAGE_SECTION_HEADER psh。 int nSections = NumOfSections (lpFile)。 int i。 if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET(lpFile)) != NULL) { /* 由名稱查找段 */ for (i = 0。 i nSections。 i++) { if (!strcmp(pshName, szSection)) { /* 向頭部復(fù)制數(shù)據(jù) */ CopyMemory((LPVOID)sh, (LPVOID)psh, sizeof(IMAGE_SECTION_HEADER))。 return TRUE。 } else psh++。 } } return FALSE。 } 這個(gè)函數(shù)通過(guò) SECHDROFFSET 宏將第一個(gè)段頭部定位,然后它開(kāi)始在所有段中循環(huán),并將要尋找的段名稱和每個(gè)段的名稱相比較,直到找到了正確的那一個(gè)為止。當(dāng)找到了段的時(shí)候,函數(shù)將內(nèi)存映像文件的數(shù)據(jù)復(fù)制到傳入函數(shù)的結(jié) 構(gòu)中,然后 IMAGE_SECTION_HEADER 結(jié)構(gòu)的各域就能夠被直接存取了。 段頭部的域 Name。每個(gè)段都有一個(gè) 8 字符長(zhǎng)的名稱域,并且第一個(gè)字符必須是一個(gè)句點(diǎn)。 PhysicalAddress 或 VirtualSize。第二個(gè)域是一個(gè) union 域,現(xiàn)在已不使用了。 VirtualAddress。這個(gè)域標(biāo)識(shí)了進(jìn)程地址空間中要裝載這個(gè)段的虛擬地址。實(shí)際的地址由將這個(gè)域的值加上可選頭部結(jié)構(gòu)中的 ImageBase 虛擬地址得到。切記,如果這個(gè)映像文件是一個(gè) DLL,那么這個(gè)DLL 就不一定會(huì)裝載到 ImageBase 要求的位置。所以一旦這個(gè)文件被裝載進(jìn)入了一個(gè)進(jìn)程,實(shí)際的ImageBase 值應(yīng)該通過(guò)使用 GetModuleHandle 來(lái)檢驗(yàn)。 SizeOfRawData。這個(gè)域表示了相對(duì) FileAlignment 的段實(shí)體尺寸。文件中實(shí)際的段實(shí)體尺寸將少于或等于 FileAlignment 的整倍數(shù)。一旦映像被裝載進(jìn)入了一個(gè)進(jìn)程的地址空間,段實(shí)體的尺寸將會(huì)變得少于或等于 FileAlignment 的整倍數(shù)。 PointerToRawData。這是一個(gè)文件中段實(shí)體位置的偏移量。 PointerToRelocations、 PointerToLinenumbers、 NumberOfRelocations、 NumberOfLinenumbers。這些域在 PE 格式中不使用。 Characteristics。定義了段的特征。這些值可以在 及本光盤(pán)(譯注: MSDN 的光盤(pán))的PE 格式規(guī)范中找到。 值 定義 0x00000020 代碼段 0x00000040 已初始化數(shù)據(jù)段 0x00000080 未初始化數(shù)據(jù)段 0x04000000 該 段數(shù)據(jù)不能被緩存 0x08000000 該段不能被分頁(yè) 0x10000000 共享段 0x20200000 可執(zhí)行段 0x40000000 可讀段 0x80000000 可寫(xiě)段 定位數(shù)據(jù)目錄 數(shù)據(jù)目錄存在于它們相應(yīng)的數(shù)據(jù)段中。典型地來(lái)說(shuō),數(shù)據(jù)目錄是段實(shí)體中的第一個(gè)結(jié)構(gòu),但不是必需的。由于這個(gè)緣故,如果你需要定位一個(gè)指定的數(shù)據(jù)目錄的話,就需要從段頭部和可選頭部中獲得信息。 為了讓這個(gè)過(guò)程簡(jiǎn)單一點(diǎn),我編寫(xiě)了以下的函數(shù)來(lái)定位任何一個(gè)在 之中定義的數(shù)據(jù)目錄。 // LPVOID WINAPI ImageDirectoryOffset(LPVOID lpFile, DWORD dwIMAGE_DIRECTORY) { PIMAGE_OPTIONAL_HEADER poh。 PIMAGE_SECTION_HEADER psh。 int nSections = NumOfSections(lpFile)。 int i = 0。 LPVOID VAImageDir。 /* 必須為 0 到 (NumberOfRvaAndSizes1)之間 */ if (dwIMAGE_DIRECTORY = pohNumberOfRvaAndSizes) return NULL。 /* 獲得可選頭部和段頭部的偏移量 */ poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(lpFile)。 psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET(lpFile)。 /* 定位映像目錄的相對(duì)虛擬地址 */ VAImageDir = (LPVOID)pohDataDirectory [dwIMAGE_DIRECTORY].VirtualAddress。 /* 定位包含映像目錄的段 */ while (i++ nSections) { if (pshVirtualAddress = (DWORD)VAImageDir amp。amp。 pshVirtualAddress + pshSizeOfRawData (DWORD)VAImageDir) break。 psh++。 } if (i nSections) return NULL。 /* 返回映像導(dǎo)入目錄的偏移量 */ return (LPVOID)(((int)lpFile + (int)VAImageDir. pshVirtualAddress) + (int)pshPointerToRawData)。 } 該函數(shù)首先確認(rèn)被請(qǐng)求的數(shù)據(jù)目錄入口數(shù)字,然后它分別獲取指向可選頭部和第一個(gè)段頭部的兩個(gè)指針。它從可選頭部決定數(shù)據(jù)目錄的虛擬地址,然后它使用這個(gè)值來(lái) 決定數(shù)據(jù)目錄定位在哪個(gè)段實(shí)體之中。如果適當(dāng)?shù)亩螌?shí)體已經(jīng)被標(biāo)識(shí)了,那么數(shù)據(jù)目錄特定的位置就可以通過(guò)將它的相對(duì)虛擬地址轉(zhuǎn)換為文件中地址的方法來(lái)找到 PE 文件格式詳解 (下 ) 作
點(diǎn)擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1