PE文件学习(1)DOS和NT

大致结构

  • DOS头和NT头之间通常还有个DOS Stub
    在这里插入图片描述

DOS头

  • DOS头的作用是兼容MS-DOS操作系统中的可执行文件
  • 一般没啥用
  • 记录着PE头的位置
  • DOS头定义部分
typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
  • 主要主要两个域
  • e_magic:DOS头的开始,即MZ
  • e_lfanew:DOS头结尾,存放着NT头的地址一般为80(值),位置是在文件偏移32的位置,0x3c
  • 以下即是DOS头
    在这里插入图片描述

DOS Stub

  • 是链接器链接执行文件的时候加入的部分数据,一般是“This program must be run under Microsoft Windows”。这个可以通过修改链接器的设置来修改成自己定义的数据。
    在这里插入图片描述

NT头

  • 定义:
typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;"双字节的数字签名,一般为PE.. | 50 45 00 00 "
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
  • IMAGE_FILE_HEADER: PE文件头
  • 定义:
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;"文件的运行平台 如Intel386 (01 4c)"
    WORD    NumberOfSections;"文件节信息,节表中的项数"
    DWORD   TimeDateStamp;"文件创建时间"
    DWORD   PointerToSymbolTable; "COFF文件符号表在文件中的偏移"
    DWORD   NumberOfSymbols; "符号表的数量"
    WORD    SizeOfOptionalHeader; '可选头的大小'
    WORD    Characteristics; '可执行文件的属性'
    "如 0x2000 // File is a DLL, "
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
  • 0x014c:运行平台 Intel386
  • 0x0010:节表项数
  • 5E3FA758:创建时间
  • COFF偏移:0E78
  • 符号表数量 ;052c
  • 可选头大小:00E0
  • 属性:0107

在这里插入图片描述

PE可选头

32位:IMAGE_OPTIONAL_HEADER32
64位:IMAGE_OPTIONAL_HEADER64

  • IMAGE_OPTIONAL_HEADER32
    定义:
typedef struct _IMAGE_OPTIONAL_HEADER {
    WORD    Magic; '可选头的类型'
    BYTE    MajorLinkerVersion;"链接器的版本号"
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;'代码段的长度,如果有多个代码段,则是代码段长度的总和'
    DWORD   SizeOfInitializedData;'初始化的数据长度'
    DWORD   SizeOfUninitializedData;'未初始化的数据长度'
    DWORD   AddressOfEntryPoint; '程序入口的RVA(偏移地址),程序入口地址'
    DWORD   BaseOfCode;'代码段起始地址的RVA'
    DWORD   BaseOfData;'数据段起始地址的RVA'
    DWORD   ImageBase;'映象(加载到内存中的PE文件)的基地址,这个基地址是建议'
    DWORD   SectionAlignment;'节对齐,PE中的节被加载到内存时会按照这个域指定的值来对齐,比如这个值是0x1000,那么每个节的起始地址的低12位都为0。'
    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;'0'
    DWORD   NumberOfRvaAndSizes;'数据目录的项数'
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;'数据目录'

数据目录:(数组)

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

DataDirectory是个数组,数组中的每一项对应一个特定的数据结构,包括导入表,导出表等

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

参考:https://blog.csdn.net/evileagle/article/details/11903197

原文地址:https://www.cnblogs.com/l0nmar/p/12553845.html