• PE文件结构


    由于一些原因,需要学习安全方面的一些知识,所以学习了PE文件的结构,这篇随笔是学习的一些心得,作为复习。希望对各位有所帮助,如果行文中有什么错误,还请各位指正。


    Microsoft Windows Portable Executable是微软可迁移可执行软件的全称,简称PE文件。对PE文件结构的学习虽然并不是程序员必须学的,但是学习对PE文件结构的学习过程中能够提升我们的个人编程能力,从中学到很多东西。而对PE文件的详细学习对我们在安全、病毒检测的工作有很大的帮助。

    PE 文件结构

    PE文件的结构如下表所示

      +-------------------+
      | DOS MZ header     |
      +-------------------+
      | DOS-stub          |
      +-------------------+
      | file-header       |
      +-------------------+
      | optional header   |
      |- - - - - - - - - -|
      |                   |
      | data directories  |
      |                   |
      +-------------------+
      |                   |
      | section headers   |
      |                   |
      +-------------------+
      |                   |
      | section 1         |
      |                   |
      +-------------------+
      |                   |
      | section 2         |
      |                   |
      +-------------------+
      |                   |
      | ...               |
      |                   |
      +-------------------+
      |                   |
      | section n         |
      |                   |
      +-------------------+
    

    DOS-header & DOS-stub

    所有的PE文件都是由一个简单DOS MZ header头开始,后面紧跟着一个DOS-stub。这么做的目的是为了向后兼容性。当全世界在从DOS到Win32转变时
    为了DOS的向后兼容性,引入了这两个区域在PE文件的开头。DOS MZ headerDOS-stub是用来兼容DOS运行环境的。当DOS看到这个头时,便知道这是一个可执行文件,接着DOS便会紧接着运行DOS-stub的内容,DOS-stub实际上就是一个EXE文件。在那个时候,有一些程序将DOS版本和Win32版本整合到一个PE文件中,具体的做法就是在DOS-stub中存放DOS版本的程序。现在的DOS-stub中的内容仅仅只是一句话 "This program cannot run in DOS mode",现在DOS-stub这个块的内容已经很少被关注。为并且有一些工作试图将DOS-stub块删除。下图显示的是分析rufus程序的DOS-headerDOS-stub截图

    其中在DOS-header的最后一个字给出了PE-header的偏移量(0x00000080)。根据这个就能够找到PE-header。即PE文件中最重要的部分。

    PE-header

    PE-header是PE文件中最重要的内容,PE-header中包含了PE加载程序需要的许多字段。PE-header实际上是一个名为IMAGE_NT_HEADERS的结构体。结构体的定义如下:

    IMAGE_NT_HEADERS STRUCT 
       Signature dd ? 
       FileHeader IMAGE_FILE_HEADER <> 
       OptionalHeader IMAGE_OPTIONAL_HEADER32 <> 
    IMAGE_NT_HEADERS ENDS
    

    字段:

    • Signature:PE-header的签名是一个魔数(0x00004550),转换成文本就是"PE"。该成员是PE签名,因此我们将使用它来验证给定文件是否是有效的PE文件。
    • FileHeader:FileHeader包含的是PE的物理布局信息(physical layout)例如Section的数量,PE文件所针对的机器等。
    • OptionalHeader:虽然说这个头部是可选的(Optional),但是在所有的PE文件中都有出现。

    微软定义了几个常量用来作为MZ头和PE头的签名,其中IMAGE_DOS_SIGNATURE是DOS头签名,IMAGE_NT_SIGNATURE是PE头签名
    IMAGE_DOS_SIGNATURE equ 5A4Dh
    IMAGE_OS2_SIGNATURE equ 454Eh
    IMAGE_OS2_SIGNATURE_LE equ 454Ch
    IMAGE_VXD_SIGNATURE equ 454Ch
    IMAGE_NT_SIGNATURE equ 4550h

    所以,为了验证一个PE文件是否是有效的,只需要知道PE-header前两个字节是不是等于0x4550就能够知道是不是合法的PE文件。验证一个文件是不是合法的PE文件,步骤如下所示:

    1. 比较一个给定的文件是否有MZ头。
    2. 如果包含了MZ头,使用MZ头的e_lfanew成员,查找PE-header的位置,e_lfanew0x3C地址上。
    3. 将PE-header的第一第二个字节和IMAGE_NT_SIGNATURE进行对比,如果相等,则证明是有效的PE文件。

    FileHeader

    FileHeader是PE-header 中的一个结构体,虽然我们最感兴趣的部分在于OptionalHeader中,但是FileHeader也包含了一些重要的字段,对FileHeader的定义如下

    IMAGE_FILE_HEADER STRUCT 
        Machine WORD ? 
        NumberOfSections WORD ? 
        TimeDateStamp dd ? 
        PointerToSymbolTable dd ? 
        NumberOfSymbols dd ? 
        SizeOfOptionalHeader WORD ? 
        Characteristics WORD ? 
    IMAGE_FILE_HEADER ENDS
    

    下表将表示各个字段的意思

    字段名 意义
    Machine PE文件所针对的CPU平台。
    NumberOfSections PE文件中Section的数量
    TimeDateStamp PE文件创建的时间,基本没什么用
    PointerToSymbolTable DEBUG 用途
    NumberOfSymbols DEBUG 用途
    SizeOfOptionalHeader OptionalHeader的大小
    Characteristics 包含文件的标识,例如这个文件是dll还是exe

    Optional Header

    虽说Optional Header 名称中含有Optional字样,但是却是PE header中最大、最重要的一个部分。Optional HeaderIMAGE_NT_HEADERS结构体中的最后一个元素,包含了PE文件的逻辑内容。在OptionalHeader中有31个字段,其中某些字段对我们十分有用。在Optional Header中存储的位置,都是RVA。关于RVA的详细内容,参考这篇笔记
    下面列举在Optional Header中对我们比较有用的字段:

    字段名 意义
    AddressOfEntryPoint 这个字段存储的是PE文件加载到内存后第一个执行命令的RVA。如果想要从开始就改变PE文件的执行顺序,就可以修改这一个字段。
    ImageBase PE文件加载的首选的RVA。假如这个值是0x400000h那么PE-loader将在该虚拟地址没有被占用的情况下,将映像文件加载到0x400000h地址上。
    SizeOfImage PE映像在内存中的大小。

    还有其他的字段信息,可以查看这个教程

    Section Table

    Section Table是一个跟在PE header后的数组。该数组的长度由IMAGE_FILE_HEADER中的NumberOfSection决定。Section Table包含了这些有用的信息

    字段 意义
    Name1 实际上这个字段应该称为"name",但是由于"name"是MSAM关键字,所以这个字段就成为Name1。这个字段中包含的是Section的名称,并且最大的长度是8个字节。可以使用任何名称,甚至将这个字段留为空。
    VirtualAddress Section的RVA,所以如果这个字段的值是1000h,而PE文件中FileHeader中ImageBase字段是400000h的话,这个Section将会加载到内存为401000h的地址上。
    SizeOfRawData 见名知意
    PointerToRawData 见名知意
    Characteristics 包含了一些标志,这些标志说明了Section中是否包含可执行代码/初始化数据/未初始化数据,以及可读性。

    Import Table

    Import Table内容比较多,重新开一个笔记来记录

  • 相关阅读:
    《ERP从内部集成起步》读书笔记——第2章 从优化业务流程谈信息集成的必要性 2.1从流程优化的需要理解信息化与管理的关系 2.1.1全局观念和全流程
    《ERP从内部集成起步》读书笔记——第一章 Garthner公司是如何提出ERP的 1.4 ERP内部集成与MRP II
    Reporting Service中Rdlc导出为pdf中文字乱码解决方法
    善用Wink将电脑操作录屏为Flash文件
    树本来就是疯的
    关于启动BIM工程硕士教育的思考
    AIRPAK3.0用户指导手册第一部分手册简介
    梦想
    How to Deal With Bullies 如何应对欺负你的人
    为什么说面试荒诞
  • 原文地址:https://www.cnblogs.com/pluviophile/p/pe-file-structure.html
Copyright © 2020-2023  润新知