您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 招标投标 > 60PE文件格式详解
PE文件格式一、PE文件概述PE文件是Windows平台上可执行文件的总称,常见的有动态链接库(扩展名.dll)、可执行文件(扩展名.exe)、目标文件(扩展名.obj)、设备驱动程序(扩展名.sys)等。事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任何扩展名。二、PE文件的基本结构PE文件由四部分组成:DOS头、NT头、节表和节数据,如图1所示。下面将分别介绍PE文件的各个组成部分。图1PE文件的基本结构1.DOS头DOS头的存在仅仅是为了兼容以前的MS-DOS系统,其中嵌入了一段代码可在MS-DOS环境下打印出“ThisprogramcannotberuninDOSmode”字样的提示信息。下面是DOS头的具体定义:1.typedefstruct_IMAGE_DOS_HEADER{//DOS.EXEheader2.WORDe_magic;//Magicnumber3.WORDe_cblp;//Bytesonlastpageoffile4.WORDe_cp;//Pagesinfile5.WORDe_crlc;//Relocations6.WORDe_cparhdr;//Sizeofheaderinparagraphs7.WORDe_minalloc;//Minimumextraparagraphsneeded8.WORDe_maxalloc;//Maximumextraparagraphsneeded9.WORDe_ss;//Initial(relative)SSvalue10.WORDe_sp;//InitialSPvalue11.WORDe_csum;//Checksum12.WORDe_ip;//InitialIPvalue13.WORDe_cs;//Initial(relative)CSvalue14.WORDe_lfarlc;//Fileaddressofrelocationtable15.WORDe_ovno;//Overlaynumber16.WORDe_res[4];//Reservedwords17.WORDe_oemid;//OEMidentifier(fore_oeminfo)18.WORDe_oeminfo;//OEMinformation;e_oemidspecific19.WORDe_res2[10];//Reservedwords20.LONGe_lfanew;//Fileaddressofnewexeheader21.}IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;其中最重要的域是e_lfanew,它用来表示NT头相对于整个PE文件起始地址的偏移量。2.NT头根据DOS头中的e_lfanew域,可以很容易地找到NT头。NT头有三部分组成:PE签名、PE文件名、PE可选头。NT头定义如下:1.typedefstruct_IMAGE_NT_HEADERS{2.DWORDSignature;3.IMAGE_FILE_HEADERFileHeader;4.IMAGE_OPTIONAL_HEADER32OptionalHeader;5.}IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;2.1PE签名Signature:类似于DOS头中的e_magic,其高16位是0,低16是0x4550,用字符表示是“PE”。2.2PE文件头IMAGE_FILE_HEADER是PE文件头,定义如下:1.typedefstruct_IMAGE_FILE_HEADER{2.WORDMachine;3.WORDNumberOfSections;4.DWORDTimeDateStamp;5.DWORDPointerToSymbolTable;6.DWORDNumberOfSymbols;7.WORDSizeOfOptionalHeader;8.WORDCharacteristics;9.}IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;每个域的具体含义如下:Machine:该文件的运行平台,是x86、x64还是I64等等。NumberOfSections:该PE文件中有多少个节,也就是节表中的项数。TimeDateStamp:PE文件的创建时间,一般有链接器填写。PointerToSymbolTable:COFF文件符号表在文件中的偏移。NumberOfSymbols:符号表的数量。SizeOfOptionalHeader:紧随其后的可选头的大小。Characteristics:可执行文件的属性,例如其值为0x2000时,表示这是一个dll文件,其值为0x0002时,表示这是一个exe可执行文件。可以看出,PE文件头定义了PE文件的一些基本信息和属性,这些属性会在PE加载器加载PE文件时用到,如果加载器发现PE文件头中定义的一些属性不满足当前的运行环境,将会终止加载该PE。2.3PE可选头IMAGE_OPTIONAL_HEADER32是PE可选头,定义如下:1.typedefstruct_IMAGE_OPTIONAL_HEADER{2.WORDMagic;3.BYTEMajorLinkerVersion;4.BYTEMinorLinkerVersion;5.DWORDSizeOfCode;6.DWORDSizeOfInitializedData;7.DWORDSizeOfUninitializedData;8.DWORDAddressOfEntryPoint;9.DWORDBaseOfCode;10.DWORDBaseOfData;11.DWORDImageBase;12.DWORDSectionAlignment;13.DWORDFileAlignment;14.WORDMajorOperatingSystemVersion;15.WORDMinorOperatingSystemVersion;16.WORDMajorImageVersion;17.WORDMinorImageVersion;18.WORDMajorSubsystemVersion;19.WORDMinorSubsystemVersion;20.DWORDWin32VersionValue;21.DWORDSizeOfImage;22.DWORDSizeOfHeaders;23.DWORDCheckSum;24.WORDSubsystem;25.WORDDllCharacteristics;26.DWORDSizeOfStackReserve;27.DWORDSizeOfStackCommit;28.DWORDSizeOfHeapReserve;29.DWORDSizeOfHeapCommit;30.DWORDLoaderFlags;31.DWORDNumberOfRvaAndSizes;32.IMAGE_DATA_DIRECTORYDataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];33.}IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;每个域的具体含义如下:Magic:表示可选头的类型,其值为0x10b时,表示32位PE可选头,其值为0x20b时,表示64位可选头。MajorLinkerVersion和MinorLinkerVersion:链接器的版本号。SizeOfCode:代码段的长度,如果有多个代码段,则是代码段长度的总和。SizeOfInitializedData:初始化的数据长度。SizeOfUninitializedData:未初始化的数据长度。AddressOfEntryPoint:程序入口的RVA。BaseOfCode:代码段起始地址的RVA。BaseOfData:数据段起始地址的RVA。ImageBase:映象(加载到内存中的PE文件)的基地址,这个基地址只是建议,对于DLL来说,如果无法加载到这个地址,系统会自动为其选择地址。SectionAlignment:节对齐,PE中的节被加载到内存时会按照这个域指定的值来对齐,比如这个值是0x1000,那么每个节的起始地址的低12位都为0.FileAlignment:节在文件中按此值对齐,SectionAlignment必须大于或等于FileAlignment,一般都是0x200.MajorOperatingSystemVersion、MinorOperatingSystemVersion:所需操作系统的版本号,随着操作系统版本越来越多,这个好像不是那么重要了。MajorImageVersion、MinorImageVersion:映象的版本号,这个是开发者自己指定的,由链接器填写。MajorSubsystemVersion、MinorSubsystemVersion:所需子系统版本号。Win32VersionValue:保留,必须为0。SizeOfImage:映象的大小,PE文件加载到内存中空间是连续的,这个值指定占用虚拟空间的大小。SizeOfHeaders:所有文件头(包括节表)的大小,这个值是以FileAlignment对齐的,也就是说,它是FileAlignment的整数倍。CheckSum:映象文件的校验和。Subsystem:运行该PE文件所需的子系统,例如。其值为2时,表示在WindowsGUI子系统下运行。DllCharacteristics:DLL的文件属性,只对DLL文件有效。SizeOfStackReserve:运行时为每个线程栈保留内存的大小。SizeOfStackCommit:运行时每个线程栈初始占用内存大小。SizeOfHeapReserve:运行时为进程堆保留内存大小。SizeOfHeapCommit:运行时进程堆初始占用内存大小。LoaderFlags:保留,必须为0。NumberOfRvaAndSizes:数据目录的项数,即下面这个数组的项数。DataDirectory:数据目录,这是一个数组,数组的项定义如下:1.typedefstruct_IMAGE_DATA_DIRECTORY{2.DWORDVirtualAddress;3.DWORDSize;4.}IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;其中VirtualAddress是一个RVA,Size是一个大小。可以看出这个数据目录项定义的是一个区域。那他定义的是什么东西的区域呢?前面说了,DataDirectory是个数组,数组中的每一项对应一个特定的数据结构,包括导入表、导出表、资源表、重定位表等,根据不同的数组索引就能找到对应表的起始位置和大小(虚拟内存中)。例如,数组第一项对应的是导出表,第二项对应的是导入表,第三项对应的是资源表。如图2所示,这是某个PE文件的真实NT头,我们可以从中发现许多关于此PE文件的有用信息。图2一个真实的NT头3.节表NT头后面是节表,节表由一个结构体数组来维护,属于线性结构。节表中的每一项指示了节的名称、节的虚拟地址位置和大小等信息。节表的项定义如下:#defineIMAGE_SIZEOF_SHORT_NAME8typedefstruct_IMAGE_SECTION_HEADER{BYTEName[IMAGE_SIZEOF_SHORT_NAME];union{DWORDPhysicalAddress;DWORDVirtualSize;}Misc;DWORDVirtualAddress;DWORDSizeOfRawData;DWORDPointerToRawData;DWORDPointerToRelocations;DWORDPointerToLinenumbers;WORDNumberOfRelocations;WORDNumberOfLine
本文标题:60PE文件格式详解
链接地址:https://www.777doc.com/doc-3778714 .html