PE文件头属性

PE文件头:

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;  //这里枚举的是32位的,还有64位的,所以有两种结构体
}

分为三部分:

1、PE文件头标识 2、PE文件表头 3、可扩展文件表头


1、PE文件头标识:

没啥好讲的,就4个字节,但是不能修改,作为标识使用!


2、标准文件头:占20个字节,是一个_IMAGE_FILE_HEADER结构体

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;  //可以运行在什么样的CPU上,如果是 x64的 那么字节则显示8664
    WORD    NumberOfSections; //表示节的数量
    DWORD   TimeDateStamp; // 编译的时候,编译器填写的当前时间戳
    DWORD   PointerToSymbolTable; //调试相关
    DWORD   NumberOfSymbols; //调试相关
    WORD    SizeOfOptionalHeader; // PE拓展头的大小,32位的默认为E0h,64位的默认为F0h,大小可以自定义
    WORD    Characteristics; // 文件属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

关于该结构体中的Characteristics成员的每个位上的代表含义如下:


3、可扩展文件表头:在x64系统中占0xF0大小,在x32系统中占0xE0大小

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;  // 分辨32位程序还是64位,如果32位则10B,64位则20B
    BYTE    MajorLinkerVersion; //链接器版本号
    BYTE    MinorLinkerVersion; //链接器版本号
    DWORD   SizeOfCode; //所有代码节的总和 文件对齐后的大小 编译器填写的,无用处
    DWORD   SizeOfInitializedData; //已经初始化数据的节的总大小 文件对齐后的大小   编译器填写的,无用处
    DWORD   SizeOfUninitializedData; // 未初始化数据的节的总大小 文件对齐后的大小   编译器填写的,无用处
    DWORD   AddressOfEntryPoint; // 程序入口
    DWORD   BaseOfCode; //代码开始的基址 编译器填写的,无用处
    DWORD   BaseOfData; //数据开始的基址  编译器填写的,无用处

    //
    // NT additional fields.
    //

    DWORD   ImageBase; //内存镜像基址
    DWORD   SectionAlignment; //内存对齐
    DWORD   FileAlignment; //文件对齐
    WORD    MajorOperatingSystemVersion; //操作系统版本号
    WORD    MinorOperatingSystemVersion; //操作系统版本号
    WORD    MajorImageVersion; //PE文件自身的版本号
    WORD    MinorImageVersion; //PE文件自身的版本号
    WORD    MajorSubsystemVersion; //运行所需要子系统的版本号
    WORD    MinorSubsystemVersion; //运行所需要子系统的版本号
    DWORD   Win32VersionValue; //子系统版本的值,必须为0
    DWORD   SizeOfImage; //内存中整个PE文件的映射尺寸,比实际的值大,必须是SectionAlignment整数倍
    DWORD   SizeOfHeaders; //所有的头+节表按照文件对齐后的大小
    DWORD   CheckSum; //校验和,可伪造
    WORD    Subsystem; //子系统, 驱动程序(1) 图形界面(2) DLL(3)
    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;

1、ImageBase决定程序在内存中的什么地方开始加载

2、当程序在内存中运行的时候,真正的入口点地址为AddressOfEntryPoint + ImageBase的地方

3、SizeOfImage比实际的值大是什么意思呢?假如在内存中拉伸过后的大小为0x5000,该值还需要是内存对齐大小(SectionAlignment)整数倍,所以在内存中的大小就可以是0x6000

4、SizeOfHeaders大小是 DOS头 + PE标识 + PE标准头 + PE可选扩展头 + 节表 的总和,再按文件对齐大小(FileAlignment)对齐的,举个例子,如果DOS头 + PE标识 + PE标准头 + PE可选扩展头 + 节表 的总和是0x1800,假如文件对齐大小是0x200,那么SizeOfHeaders也就是0x2000,那么多出来的0x200其实就是空数据!

posted @ 2020-02-15 12:21  zpchcbd  阅读(911)  评论(0编辑  收藏  举报