zoukankan      html  css  js  c++  java
  • PE文件学习系列三-PE头详解

    合肥程序员群:49313181。    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)
    Q  Q:408365330     E-Mail:egojit@qq.com

    最近比较忙,只能抽节假日去学习和记录自己的学习,这一节我记录自己学习PE头的学习。在这里给大家介绍一本很好的学习PE的书:Windows PE权威指南。上一节我们一起学习DOS头。DOS头很多内容在16位DOS系统下面才会用到。在现在的Win32系统中,这些事冗余。

    因此我们关注更多的是PE头而非DOS头。首先上图,对着图片看才够清晰:

    PE结构

    以后不管我们学习PE的哪个结构,我们都对着这个图去学习,这样才会有感觉。

    上PE头C结构描述,这个结构还是在WinNT.h中:

    typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

    请查看上面的图片四字节的被称为PE标识符的Signature这四个字节就是图上面的PE00。我猜PE文件的称谓也是这个缘由吧。捧腹大笑。_IMAGE_NT_HEADERS 结构的另外两个成员都是结构体,

    1.PE标准机构-IMAGE_FILE_HEADER

    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;//运行平台
        WORD    NumberOfSections;//PE文件中节的数量
        DWORD   TimeDateStamp;//文件创建时间和日期
        DWORD   PointerToSymbolTable;//指向符合表(用于调试)
        DWORD   NumberOfSymbols;//符合表中符号数量(用于调试)
        WORD    SizeOfOptionalHeader;//扩展头结构的长度
        WORD    Characteristics;//文件属性
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

    我已经给机构成员后面添加了备注,让我们理解这个结构。IMAGE_FILE_HEADER.NumberOfSections。PE节的数量,这个可以对节区信息进行遍历的循环次数。

    2.PE扩展头-IMAGE_OPTIONAL_HEADER32

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //
    
        WORD    Magic;//魔术字
        BYTE    MajorLinkerVersion;//连接器版本号
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;  //所有含代码节的总大小
        DWORD   SizeOfInitializedData;//所有含已初始化数据的节的总大小
        DWORD   SizeOfUninitializedData;//所有含未初始化数据的节的大小
        DWORD   AddressOfEntryPoint;//程序执行入口RVA
        DWORD   BaseOfCode;//代码节的起始RVA
        DWORD   BaseOfData;//数据节的起始RVA
    
        //
        // NT additional fields.
        //
    
        DWORD   ImageBase; //程序的建议装载地址
        DWORD   SectionAlignment;//内存节的对齐粒度
        DWORD   FileAlignment;//文件中节的对齐粒度
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;//操作系统版本号
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;//内存中PE镜像文件尺寸
        DWORD   SizeOfHeaders;
        DWORD   CheckSum;
        WORD    Subsystem;
        WORD    DllCharacteristics;//DLL文件特性
        DWORD   SizeOfStackReserve;
        DWORD   SizeOfStackCommit;
        DWORD   SizeOfHeapReserve;
        DWORD   SizeOfHeapCommit;
        DWORD   LoaderFlags;
        DWORD   NumberOfRvaAndSizes;//下面的数据目录结构的项目数量
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//数据目录
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

    以上我对一些比较关注的机构字段加上了备注。

    查看以上机构我们看到这个IMAGE_OPTIONAL_HEADER32结构内容特别丰富,比PE标准结构丰富多了。

    SectionAlignment这个字段是内存中节的对齐粒度,在这里我要说明下,Windows系统中(默认32位系统),操作系统能识别4G内存,对于每个进程都有一个独立的4G虚拟内存。在这种4G虚拟内存机制中起到最大的作用是内存分页机制,内存分页机制将一部分硬盘空间作为内存。而这个分页机制中的页大小为4K,也就是16进制的1000H。那么我们很容易知道默认的SectionAlignment值就是1000H,也就是4K。当然PE文件在硬盘上是不一样的,PE文件存磁盘上对齐粒度是200H。

    结构最后一个字段IMAGE_DATA_DIRECTORY。该字段定义了PE文件中出现的所有不同类型的数据的目录信息,应用程序中数据被按照用途分成很多种类,如导入表,导出表,资源,重定位表等,DataDirectory数组个数为16。

    typedef struct _IMAGE_DATA_DIRECTORY {
        DWORD   VirtualAddress;//数据起始RVA
        DWORD   Size;//数据块长度
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

    IMAGE_DATA_DIRECTORY.VirtualAddress虚拟地址指定的是相应节的相对虚拟地址(RVA),PE文件中有16个节,严格讲有15个,最后一个是预留的。

    学到这有人会问,看了这么多结构,有什么用呢??这个真的很有用,后期可以写程序区分析这些机构。可以动态改变PE结构,可以给PE文件加密……,等等都是靠对这些机构的理解才能做到。

    -----

    版权:归博客园和Egojit所有,转载请标明出处。
  • 相关阅读:
    HBase On Spark
    Hive安装配置要点
    通过拆分,提高表的访问效率
    使用冗余统计表
    优化表的数据类型
    以题目为鉴,如何做数学笔记
    思维训练素材整理
    三角函数知识点
    穿针引线法的前世今生
    集合知识点
  • 原文地址:https://www.cnblogs.com/egojit/p/3352027.html
Copyright © 2011-2022 走看看