PE文件格式详解③


PE文件格式详解③
2010年12月04日
  PE可选头部
  Optional Header 结构是 IMAGE_NT_HEADERS 中的最后成员。包含了PE文件的逻辑分布信息。该结构共有31个域,一些是很关键,另一些不太常用。其结构定义:
  typedef struct _IMAGE_OPTIONAL_HEADER {
  WORD    Magic;
  BYTE    MajorLinkerVersion;
  BYTE    MinorLinkerVersion;
  DWORD   SizeOfCode;
  DWORD   SizeOfInitializedData;
  DWORD   SizeOfUninitializedData;
  DWORD   AddressOfEntryPoint;
  DWORD   BaseOfCode;
  DWORD   BaseOfData;
  DWORD   ImageBase;
  DWORD   SectionAlignment;
  DWORD   FileAlignment;
  WORD    MajorOperatingSystemVersion;
  WORD    MinorOperatingSystemVersion;
  WORD    MajorImageVersion;
  WORD    MinorImageVersion;
  WORD    MajorSubsystemVersion;
  WORD    MinorSubsystemVersion;
  DWORD   Win32VersionValue;
  DWORD   SizeOfImage;
  DWORD   SizeOfHeaders;
  DWORD   CheckSum;
  WORD    Subsystem;
  WORD    DllCharacteristics;
  DWORD   SizeOfStackReserve;
  DWORD   SizeOfStackCommit;
  DWORD   SizeOfHeapReserve;
  DWORD   SizeOfHeapCommit;
  DWORD   LoaderFlags;     DWORD   NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
  IMAGE_OPTIONAL_HEADER 结构成员含义:
  1.Magic:用来定义 image 的状态
  0x0107(IMAGE_ROM_OPTIONAL_HDR_MAGIC):一个 ROM image
  0x010B(IMAGE_NT_OPTIONAL_HDR_MAGIC): 一个正常的(一般的)EXE image。大部份PE 文件都含此值。
  2.MajorLinkerVersion、MinorLinkerVersion:产生此PE文件的链接器的版本。以十进制而非十六进制表示。例如2.23 版。
  3.SizeOfCode:所有code section 的总和大小。大部分程序只有一个 code section,所以此域通常就是 .text section 的大小。
  4.SizeOfInitializedData:所有包含初始化内容的 sections(但不包括 code section)的总和大小。似乎不包括 initialized data sections 在内。
  5.SizeOfUninitializedData:所有需要PE装载器将内存地址空间赋予它但是却不占用硬盘空间的所有 sections 的大小总和。这些 sections 在程序启动时并不需要特别内容,所以导致 Uninitialized Data 这种叫法。为初始化的内容通常放在 .bss section 中。
  6.AddressOfEntryPoint:这是PE文件开始执行的位置。这是一个RVA,通常会落在 .text section.此域适用于 exe 或 dll。
  7.BaseOfCode:一个RVA,表示程序中的 code section 从何开始。code section 通常在 data section 之前,在PE 表头之后。微软链接器所产生的exes 中,此值通常为0x1000。Borland 的TLINK32则通常指定此值为0x10000。因为预设情况下TLINK时以64k为对齐粒度的,而MS用的是4k。
  8.BaseOfData:一个RVA,表示程序中的 data section 从何开始。data section 一般位于code section 和 PE 表头之后。
  9.ImageBase:PE文件的优先装载地址(Base Address)。比如,如果该值是400000h,PE装载器将尝试把文件装到虚拟地址空间的400000h处。字眼"优先"表示若该地址区域已被其他模块占用,那PE装载器会选用其他空闲地址。
  10.SectionAlignment:内存中节对齐的粒度。例如,如果该值是4096 (1000h),那么每节的起始地址必须是4096的倍数。若第一节从401000h开始且大小是10个字节,则下一节必定从402000h开始,即使401000h和402000h之间还有很多空间没被使用。
  11.FileAlignment:文件中节对齐的粒度。例如,如果该值是(200h),,那么每节的起始地址必须是512的倍数。若第一节从文件偏移量200h开始且大小是10个字节,则下一节必定位于偏移量400h,即使偏移量512和1024之间还有很多空间没被使用或定义。预设值就是0x200h。
  12.MajorOperatingSystemVersion/MinorOperatingSystemVersion:使用此可执行程序的操作系统的最小版本。WIN32程序的这两个域通常指定为1.0。
  13.MajorSubsystemVersion/MinorSubsystemVersion:WIN32子系统版本。若PE文件是专门为WIN32设计的,该子系统版本必定是4.0否则对话框不会有3维立体感。
  14.MajorImageVersion/MinorImageVersion:使用者自定义的域,允许你拥有不同版本的exe或dll。可以利用链接器的 /VERSION 选项设定其值。例如:LINK /VERSION:2.0 myobj.obj。
  15.Reserved1:似乎总是0。
  16.SizeOfImage:内存中整个PE映像体的尺寸。它是所有头和节经过节对齐处理后的大小。也就是从image base 开始,直到最后一个 section为止。最后一个section 的尾端必需是SectionAlignment 的倍数。
  17.SizeOfHeaders:所有头 + 节表的大小,也就等于文件尺寸减去文件中所有节的尺寸。可以以此值作为PE文件第一节的文件偏移量。
  18.CheckSum:此程序的一个CRC 校验和。PE中此域通常被忽略并被设为0。然而,所有的driver DLLs、所有在开机时载入的DLLs、以及server DLLs 都必须有一个合法的 CheckSum。其演算法可以在IMAGEHLP.DLL中获得。IMAGEHLP.DLL 的代码可以在WIN32 SDK中找到。
  19.Subsystem:用来识别PE文件属于哪个子系统。对于大多数Win32程序,只有两类值: Windows GUI 和 Windows CUI (控制台)。WINNT.h中定义如下:
  #define IMAGE_SUBSYSTEM_UNKNOWN          0 Unknown subsystem.
  #define IMAGE_SUBSYSTEM_NATIVE           1 不需要子系

猜你喜欢

转载自iig669ml.iteye.com/blog/1358005