新手学习PE文件结构

我就是学习逆向分析的菜狗,想好好学习下PE文件结构,为后面的逆向分析做基础,现在我就把自己学习PE文件结构的心得铺出来,让自己有个学习记录。

本次PE文件分析主要是64位WIN7系统下的notepad.exe文件。

拿010eidtor打开之后是这个样子:

 

我们开始系统学习,学习前先看一张图,是PE文件的整体结构图,这张图很经典转载于各个PE文件学习的论坛,从图中我们知道PE文件由5个主要结构体构成,还有个OTHERS结构体(此结构体并不重要所以不再讨论范围内),图如果看不清把图下载下来在看:

一、PE文件的组成

首先我们得知道一个PE文件由5个结构构成:

1.【IMAGE_DOS_HEADER】 DOS头部结构体

看一下IMAGE_DOS_HEADER结构体定义内容:

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;

这个结构体占有64个字节*(WORD占2个字节,DWORD占4个字节),重要的有2个字段需要了解,1是e_magic,占2个字节,通常MZ开头,2 是e_lfanew它指明了PE文件的起始位置。

2.【IMAGE_NT_HEADERS】 PE头部结构体

 

该结构体分为32位、64位2种形态,基本相同:

32位:

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

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

其中最重要的是IMAGE_FILE_HEADER FileHeaderIMAGE_OPTIONAL_HEADER这2个结构,这2个结构是单独拿出来讲的,其中Signature是个标识符就是类似MZ开头的那样,在这里是PE\0\0(50 45 00 00);

 

 

 3.【IMAGE_FILE_HEADER】文件头部结构体

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;                        //表示可执行文件的CPU类型
    WORD    NumberOfSections;               //表示PE文件的节区个数
    DWORD   TimeDateStamp;                  //表示文件何时被创建
    DWORD   PointerToSymbolTable;           //很少使用
    DWORD   NumberOfSymbols;                //很少使用
    WORD    SizeOfOptionalHeader;           //表示IMAGE_OPTIONAL_HEADER大小
    WORD    Characteristics;                //表示文件类型
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 

 

 

Machine:
   该字段是WORD类型,占用2字节。表示可执行文件的目标CPU类型。取值如下:

#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2  // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE


NumberOfSections:
  该字段WORD类型,占用2字节。表示PE文件的节区的个数
  
TimeDataStamp:
  该字段表明了文件是合适被创建的,这个值是从1970年1月1日以来用格林威治时间计算的秒数。

PointerToSymbolTable:
  符号表,指向COFF符号表(主要用于调试) 。

NumberOfSymbols:
  符号表中的符号数。

SizeOfOptionalHeader:
  该字段为WORD类型,占用2字节。该字段指定了IMAGE_OPTIONAL_HEADER结构的大小。
这里注意下 在计算IMAGE_OPTIONAL_HEADER的大小是应该从IMAGE_FILE_HEADER的这个字段来获取,而不应该直接使用sizeof(IMAGE_OPTIONAL_HEADER)计算。IMAGE_OPTIONAL_HEADER结构体的大小是可能会改变的。

Characteristics:
  该字段为WORD类型,占用2字节。它指定了文件的类型,例如DLL文件,系统文件.其取值定义如下:

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved external references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Aggressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.


4.【IMAGE_OPTIONAL_HEADER】可选头结构体


5.【IMAGE_SECTION_HEADER】节表结构体

 

posted @ 2020-07-12 16:59  逆向菜狗  阅读(525)  评论(0编辑  收藏  举报