PE文件相关内容

1.PE header:

如何加载到内存、从何处开始运行、运行中需要的DLL文件有哪些、需要多大的栈/堆内存等,大量信息以结构体形式存储在PE头中。
PE文件格式如下:
DOS头+DOS存根+节区头=PE头
PE文件相关内容

1.DOS头

在PE头最前面的是IMAGE_DOS_HEADER结构体,用来扩展已知的的DOS EXE头,该结构体共40个字节,我们必须要知道其中两个重要成员,分别是:

  • e_magic
    代表DOS签名,其16进制值为4D5A(ASCII值为“MZ”)
  • e_flanew
    指示NT头的偏移(根据不同的文件拥有可变值)
    Intel系列的CUP使用逆序存储数据(小端序)

2.DOS存根

DOS存根是可选项,大小不固定,即使没有DOS存根文件也能正常运行。由代码和数据混合而成,但是其中代码被忽略不会执行。

3.NT头

NT头结构体是IMAGE_NT_HEADERAS,其由三个成员组成,分别是:Signature结构体File HeaderOptionalHeader结构体

  • Signature结构体
    签名结构体,其值为50450000h("PE"00)
  • FIle Header
    文件头是表现文件大致属性的IMAGE_FILE_HEADER结构体
    PE文件相关内容
    以下四种成员变量十分重要,若设置不正确将导致文件无法正常运行
    1.Machine
    每个CPU都有唯一的Machine码,可以在winnt.h中查看定义的Machine码。
    2.NumberOfSectons
    用来指出文件中存在的节区数量。该值一定要大于0,且定义的节区数量与实际节区不同时,将发生运行错误。
    3.SizeOfOptionalHeader
    其用来指出可选头(IMAGE_OPTIONAL_HEADER32)的长度
    PE32+格式的文件中使用的是IMAGE_OPTIONAL_HEADER64结构体,而不是IMAGE_OPTIONAL_HEADER32结构体,两者的尺寸是不同的,所以需要在SizeOfOptionalHeader成员中明确指出结构体的大小。
    4.Characteristics
    该字段用来标识文件的属性,文件是否是可运行的形态、是否为DLL文件等信息,若该值为0x0002,代表文件是可执行的,若值为0x2000,则代表该文件是DLL文件。
  • Optional Header
    IMAGE_OPTIONAL_HEADER32结构体很大,在其中我们需要关注以下成员:
    1.Magic
    为IMAGE_OPTIONAL_HEADER32结构体时,Magic码为10B,为IMAGE_OPTIONAL_HEADER64时,Magic码为20B。
    2.AddressOfEntryPoint
    持有EP的RVA(相对虚拟地址)值。该值指出程序最先执行的代码起始地址,相当重要。
    3.ImageBase
    指出文件的优先装入地址。执行PE文件时,PE装载器先创建进程,再将文件载入内存,然后把EIP寄存器的值设置为ImageBase+AddressOfEntryPoint(对于操作系统来说都是虚拟地址)
    4.SectionAlignment,FileAlignment
    FileAlignment指定了节区在磁盘文件中的最小单位,SectionAlignment指定了节区在内存中的最小单位。磁盘文件或内存的节区大小必定为FileAlignment或SectionAlignment值的整数倍。
    5.SIzeOfImage
    指定了PE Image在虚拟内存中所占空间的大小。文件的大小与加载到内存中的大小一般是不同的。
    6.SizeOfHeader
    指出整个PE头的大小。
    7.Subsystem
    用来区分系统驱动文件(.sys)与普通可执行文件(.exe,*.dll)。
    8.NumberOfRvaAndSizes
    用来指定DataDirectory数组的个数
    #9.DataDirectory
    是由IMAGE_DATA_DIRECTORY结构体组成的数组,数组的每项都有被定义的值。
    PE文件相关内容

4.节区头

节区头中定义了各节区的属性。