重读PE文件格式
感覺很有必要重新研究PE格式,所以重讀了PE格式的相關(guān)文檔,心得如下:
1.對于DOS頭,其定義如下:
代碼 typedef?struct?_IMAGE_DOS_HEADER?{??????//?DOS?.EXE?header????WORD???e_magic;?????????????????????//?Magic?number
????WORD???e_cblp;??????????????????????//?Bytes?on?last?page?of?file
????WORD???e_cp;????????????????????????//?Pages?in?file
????WORD???e_crlc;??????????????????????//?Relocations
????WORD???e_cparhdr;???????????????????//?Size?of?header?in?paragraphs
????WORD???e_minalloc;??????????????????//?Minimum?extra?paragraphs?needed
????WORD???e_maxalloc;??????????????????//?Maximum?extra?paragraphs?needed
????WORD???e_ss;????????????????????????//?Initial?(relative)?SS?value
????WORD???e_sp;????????????????????????//?Initial?SP?value
????WORD???e_csum;??????????????????????//?Checksum
????WORD???e_ip;????????????????????????//?Initial?IP?value
????WORD???e_cs;????????????????????????//?Initial?(relative)?CS?value
????WORD???e_lfarlc;????????????????????//?File?address?of?relocation?table
????WORD???e_ovno;??????????????????????//?Overlay?number
????WORD???e_res[4];????????????????????//?Reserved?words
????WORD???e_oemid;?????????????????????//?OEM?identifier?(for?e_oeminfo)
????WORD???e_oeminfo;???????????????????//?OEM?information;?e_oemid?specific
????WORD???e_res2[10];??????????????????//?Reserved?words
????LONG???e_lfanew;????????????????????//?File?address?of?new?exe?header
??}?IMAGE_DOS_HEADER,?*PIMAGE_DOS_HEADER;
?
因為我們開發(fā)的是windows下的程序,所以重要的字段有兩個,一個是e_magic字段,一個是e_lfanew,e_magic字段始終為5A4D,即ASCII字符的MZ,e_lfanew保存的是PE文件頭在文件中的偏移量,我想作為exe程序的裝載器,首先檢查DOS頭的e_magic字段是否為MZ,然后讀取e_lfanew字段的值,以此找到PE文件頭
2.找到PE文件頭,PE文件頭的定義如下:
typedef?struct?_IMAGE_NT_HEADERS?{????DWORD?Signature;
????IMAGE_FILE_HEADER?FileHeader;
????IMAGE_OPTIONAL_HEADER32?OptionalHeader;
}?IMAGE_NT_HEADERS32,?*PIMAGE_NT_HEADERS32;
?
signature字段同DOS頭的e_magic一樣,是個標(biāo)志字段,其值始終為4550,IMAGE_FILE_HEADER結(jié)構(gòu)定義如下:
代碼 typedef?struct?_IMAGE_FILE_HEADER?{????WORD????Machine;//運(yùn)行平臺
????WORD????NumberOfSections;//文件的節(jié)數(shù)目
????DWORD???TimeDateStamp;//文件創(chuàng)建日期和時間
????DWORD???PointerToSymbolTable;//指向符號表(用于調(diào)試)
????DWORD???NumberOfSymbols;//符號表中的符號數(shù)量(用于調(diào)試)
????WORD????SizeOfOptionalHeader;//IMAGE_OPTIONAL_HEADER32結(jié)構(gòu)的長度
????WORD????Characteristics;//文件屬性
}?IMAGE_FILE_HEADER,?*PIMAGE_FILE_HEADER;
?
machine字段表示當(dāng)前文件應(yīng)該運(yùn)行的平臺,對于PC來說,此值應(yīng)該為14C
NumberOfSections這個字段表示文件的節(jié)的數(shù)目,這個值很重要,我試著把一個文件的這個字段加1,然后發(fā)現(xiàn)文件不能正常裝載了,因此系統(tǒng)應(yīng)該是據(jù)此字段來裝載PE文件的節(jié)的
Characteristics指明了當(dāng)前PE文件是什么類型的,如果是exe,則值為10F,如果是DLL,則為210E
IMAGE_OPTIONAL_HEADER32是非常重要的一個結(jié)構(gòu),他里面有很多重要的信息,定義如下:
代碼 typedef?struct?_IMAGE_OPTIONAL_HEADER?{????//
????//?Standard?fields.
????//
????WORD????Magic;//10Bh=exe?Image
????BYTE????MajorLinkerVersion;//鏈接器版本號
????BYTE????MinorLinkerVersion;
????DWORD???SizeOfCode;//所有含代碼的節(jié)的總大小
????DWORD???SizeOfInitializedData;//所有含已初始化數(shù)據(jù)的節(jié)的總大小
????DWORD???SizeOfUninitializedData;//所有含未初始化數(shù)據(jù)的節(jié)的大小
????DWORD???AddressOfEntryPoint;//程序執(zhí)行入口RVA
????DWORD???BaseOfCode;//代碼的節(jié)的起始RVA
????DWORD???BaseOfData;//數(shù)據(jù)的節(jié)的起始RVA
????//
????//?NT?additional?fields.
????//
????DWORD???ImageBase;//程序的建議裝載地址
????DWORD???SectionAlignment;//內(nèi)存中的節(jié)的對齊粒度
????DWORD???FileAlignment;//文件中的節(jié)的對齊粒度
????WORD????MajorOperatingSystemVersion;//操作系統(tǒng)主版本號
????WORD????MinorOperatingSystemVersion;//操作系統(tǒng)副版本號
????WORD????MajorImageVersion;//可運(yùn)行于操作系統(tǒng)的最小版本號
????WORD????MinorImageVersion;//
????WORD????MajorSubsystemVersion;//可運(yùn)行于操作系統(tǒng)的最小子版本號
????WORD????MinorSubsystemVersion;
????DWORD???Win32VersionValue;
????DWORD???SizeOfImage;//內(nèi)存中整個PE映像尺寸
????DWORD???SizeOfHeaders;//所有頭+節(jié)表的大小
????DWORD???CheckSum;//
????WORD????Subsystem;//文件的子系統(tǒng)
????WORD????DllCharacteristics;//
????DWORD???SizeOfStackReserve;//初始化時的堆棧大小
????DWORD???SizeOfStackCommit;//初始化時實際提交的堆棧大小
????DWORD???SizeOfHeapReserve;//初始化時保留的堆大小
????DWORD???SizeOfHeapCommit;//初始化時實際提交的堆大小
????DWORD???LoaderFlags;//
????DWORD???NumberOfRvaAndSizes;//下面的數(shù)據(jù)目錄結(jié)構(gòu)的數(shù)量
????IMAGE_DATA_DIRECTORY?DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//!!重要字段
}?IMAGE_OPTIONAL_HEADER32,?*PIMAGE_OPTIONAL_HEADER32;
?
以上是簡單的注釋,詳細(xì)解釋放在下一篇文章,下午來寫
轉(zhuǎn)載于:https://www.cnblogs.com/feiyucq/archive/2010/03/31/1701206.html
總結(jié)
- 上一篇: ASP.NET MVC 环境配置,从1.
- 下一篇: 让人期待的Visual Studio 2