appsion 发表于 2020-10-30 19:59

PE 文件解析

本帖最后由 appsion 于 2020-10-30 22:00 编辑

PE 文件解析
新手学习PE文件解析记录,持续更新. 部分参考来源于网络, 无法逐一标注, 如果侵权,请及时联系. 如有错误请指正,误喷.


概念:PE:    Portable Executable, 可移植的可执行的文件, 常见的EXE、DLL、OCX、SYS、COM都是PE文件, PE文件是微软Windows操作系统上的程序文件.
COFF:
    common object file format, 通用对象文件格式, 指可执行文件(映像)和对象文件 32 位编程的格式,该格式可跨平台移植
ImageBase:
    映象基址, 项目加载到内存的起始地址.
VA:
    Virtual Address, 虚拟地址, 项目加载到内存后的实际地址
RVA:
    Relative Virtual Address, 相对虚拟地址, 在映射文件中, 项目加载到内存后从映象文件的基址偏移的地址.


更多请参考: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table

1.1 PE文件结构:         

   


结构体: IMAGE_DOS_HEADER
说明: MS-DOS兼容的PE头
长度: 64字节
头文件: winnt.h
帮助文档: 无
参考文档: 来源于网络

typedef struct _IMAGE_DOS_HEADER    // DOS .EXE header
{
      WORD   e_magic;             // 1. 文件标识
      WORD   e_cblp;            // 2. 文件最后页的字节数
      WORD   e_cp;                // 3. 文件页数
      WORD   e_crlc;            // 4. 重定义元素个数
      WORD   e_cparhdr;         // 5. 头部尺寸,以段落为单位
      WORD   e_minalloc;          // 6. 所需的最小附加段
      WORD   e_maxalloc;          // 7. 所需的最大附加段
      WORD   e_ss;                // 8. 初始的SS值(相对偏移量)
      WORD   e_sp;                // 9. 初始的SP值
      WORD   e_csum;            // 10. 校验和
      WORD   e_ip;                // 11. 初始的IP值
      WORD   e_cs;                // 12. 初始的CS值(相对偏移量)
      WORD   e_lfarlc;            // 13. 重分配表文件地址
      WORD   e_ovno;            // 14. 覆盖号
      WORD   e_res;            // 15. 保留字
      WORD   e_oemid;             // 16. OEM标识符(相对e_oeminfo)
      WORD   e_oeminfo;         // 17. OEM信息
      WORD   e_res2;          // 18. 保留字
      LONG    e_lfanew;         // 19. PE标头格式偏移地址, IMAGE_NT_HEADERS 的地址
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

参数说明: 仅供参考, 详细说明请参考原文.
      e_magic:
                DOS映像, "MZ".         #define IMAGE_DOS_SIGNATURE 0x5A4D
      e_lfanew:
                PE标头格式偏移地址, 指向 IMAGE_NT_HEADERS 结构



结构体: IMAGE_NT_HEADERS
说明: PE标头格式
头文件: winnt.h
帮助文档: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_nt_headers32

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

参数说明: 仅供参考, 详细说明请参考原文.
      Signature:
                PE映像的4字节签名 “PE00”.                IMAGE_NT_SIGNATURE      0x00004550      // PE00
      FileHeader:
                通用文件头, IMAGE_FILE_HEADER 结构
      OptionalHeader:                可选文件头, IMAGE_OPTIONAL_HEADER 结构






结构体: IMAGE_SECTION_HEADER
说明: 映像节表格式
头文件: winnt.h
帮助文档: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_section_header

typedef struct _IMAGE_SECTION_HEADER
{
BYTEName;
union {
    DWORD PhysicalAddress;
    DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORDNumberOfRelocations;
WORDNumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

参数说明: 仅供参考, 详细说明请参考原文.
      Name:
                节表名称, 8字节字符串。不支持长度超过8个字符的节名称。
      Misc.PhysicalAddress:
                节表的虚拟大小
      Misc.PhysicalAddress
                文件地址
      VirtualAddress:
                节表的RVA
      SizeOfRawData
                节表的文件数据大小
      PointerToRawData
                节表Raw(磁盘文件)的偏移
      PointerToRelocations
                节表的重新定位偏移。
      PointerToLinenumbers
                节表的行号项偏移。
      NumberOfRelocations
                节表的重新定位数量
      NumberOfLinenumbers
                节表的行号项数量。
      Characteristics
                特征

Characteristics 成员如下:

0x00000000Reserved.
0x00000001Reserved.
0x00000002Reserved.
0x00000004Reserved.
IMAGE_SCN_TYPE_NO_PAD0x00000008The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES.
0x00000010Reserved.
IMAGE_SCN_CNT_CODE0x00000020The section contains executable code.
IMAGE_SCN_CNT_INITIALIZED_DATA0x00000040The section contains initialized data.
IMAGE_SCN_CNT_UNINITIALIZED_DATA0x00000080The section contains uninitialized data.
IMAGE_SCN_LNK_OTHER0x00000100Reserved.
IMAGE_SCN_LNK_INFO0x00000200The section contains comments or other information. This is valid only for object files.
0x00000400Reserved.
IMAGE_SCN_LNK_REMOVE0x00000800The section will not become part of the image. This is valid only for object files.
IMAGE_SCN_LNK_COMDAT0x00001000The section contains COMDAT data. This is valid only for object files.
0x00002000Reserved.
IMAGE_SCN_NO_DEFER_SPEC_EXC0x00004000Reset speculative exceptions handling bits in the TLB entries for this section.
IMAGE_SCN_GPREL0x00008000The section contains data referenced through the global pointer.
0x00010000Reserved.
IMAGE_SCN_MEM_PURGEABLE0x00020000Reserved.
IMAGE_SCN_MEM_LOCKED0x00040000Reserved.
IMAGE_SCN_MEM_PRELOAD0x00080000Reserved.
IMAGE_SCN_ALIGN_1BYTES0x00100000Align data on a 1-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_2BYTES0x00200000Align data on a 2-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_4BYTES0x00300000Align data on a 4-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_8BYTES0x00400000Align data on a 8-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_16BYTES0x00500000Align data on a 16-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_32BYTES0x00600000Align data on a 32-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_64BYTES0x00700000Align data on a 64-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_128BYTES0x00800000Align data on a 128-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_256BYTES0x00900000Align data on a 256-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_512BYTES0x00A00000Align data on a 512-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_1024BYTES0x00B00000Align data on a 1024-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_2048BYTES0x00C00000Align data on a 2048-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_4096BYTES0x00D00000Align data on a 4096-byte boundary. This is valid only for object files.
IMAGE_SCN_ALIGN_8192BYTES0x00E00000Align data on a 8192-byte boundary. This is valid only for object files.
IMAGE_SCN_LNK_NRELOC_OVFL0x01000000The section contains extended relocations. The count of relocations for the section exceeds the 16 bits that is reserved for it in the section header. If the NumberOfRelocations field in the section header is 0xffff, the actual relocation count is stored in the VirtualAddress field of the first relocation. It is an error if IMAGE_SCN_LNK_NRELOC_OVFL is set and there are fewer than 0xffff relocations in the section.
IMAGE_SCN_MEM_DISCARDABLE0x02000000The section can be discarded as needed.
IMAGE_SCN_MEM_NOT_CACHED0x04000000The section cannot be cached.
IMAGE_SCN_MEM_NOT_PAGED0x08000000The section cannot be paged.
IMAGE_SCN_MEM_SHARED0x10000000The section can be shared in memory.
IMAGE_SCN_MEM_EXECUTE0x20000000The section can be executed as code.
IMAGE_SCN_MEM_READ0x40000000The section can be read.
IMAGE_SCN_MEM_WRITE0x80000000The section can be written to.



结构体: IMAGE_FILE_HEADER
说明: 通用文件头格式.
头文件: winnt.h
帮助文档: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_file_header
typedef struct _IMAGE_FILE_HEADER {
WORDMachine;
WORDNumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORDSizeOfOptionalHeader;
WORDCharacteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

参数说明: 仅供参考, 详细说明请参考原文.
      Machine
                处理器类型
      NumberOfSections
                创建映像日期和时间
      PointerToSymbolTable
                符号表的偏移量
      NumberOfSymbols
                符号表中的符号数。
      SizeOfOptionalHeader
                可选映像头(IMAGE_OPTIONAL_HEADER)的长度
      Characteristics
                特征


Machine 成员如下:

IMAGE_FILE_MACHINE_UNKNOWN0x0The content of this field is assumed to be applicable to any machine type
IMAGE_FILE_MACHINE_AM330x1d3Matsushita AM33
IMAGE_FILE_MACHINE_AMD640x8664x64
IMAGE_FILE_MACHINE_ARM0x1c0ARM little endian
IMAGE_FILE_MACHINE_ARM640xaa64ARM64 little endian
IMAGE_FILE_MACHINE_ARMNT0x1c4ARM Thumb-2 little endian
IMAGE_FILE_MACHINE_EBC0xebcEFI byte code
IMAGE_FILE_MACHINE_I3860x14cIntel 386 or later processors and compatible processors
IMAGE_FILE_MACHINE_IA640x200Intel Itanium processor family
IMAGE_FILE_MACHINE_M32R0x9041Mitsubishi M32R little endian
IMAGE_FILE_MACHINE_MIPS160x266MIPS16
IMAGE_FILE_MACHINE_MIPSFPU0x366MIPS with FPU
IMAGE_FILE_MACHINE_MIPSFPU160x466MIPS16 with FPU
IMAGE_FILE_MACHINE_POWERPC0x1f0Power PC little endian
IMAGE_FILE_MACHINE_POWERPCFP0x1f1Power PC with floating point support
IMAGE_FILE_MACHINE_R40000x166MIPS little endian
IMAGE_FILE_MACHINE_RISCV320x5032RISC-V 32-bit address space
IMAGE_FILE_MACHINE_RISCV640x5064RISC-V 64-bit address space
IMAGE_FILE_MACHINE_RISCV1280x5128RISC-V 128-bit address space
IMAGE_FILE_MACHINE_SH30x1a2Hitachi SH3
IMAGE_FILE_MACHINE_SH3DSP0x1a3Hitachi SH3 DSP
IMAGE_FILE_MACHINE_SH40x1a6Hitachi SH4
IMAGE_FILE_MACHINE_SH50x1a8Hitachi SH5
IMAGE_FILE_MACHINE_THUMB0x1c2Thumb
IMAGE_FILE_MACHINE_WCEMIPSV20x169MIPS little-endian WCE v2


Characteristics 成员如下:

IMAGE_FILE_RELOCS_STRIPPED 0x0001Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the file does not contain base relocations and must therefore be loaded at its preferred base address. If the base address is not available, the loader reports an error. The default behavior of the linker is to strip base relocations from executable (EXE) files.
IMAGE_FILE_EXECUTABLE_IMAGE 0x0002Image only. This indicates that the image file is valid and can be run. If this flag is not set, it indicates a linker error.
IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004COFF line numbers have been removed. This flag is deprecated and should be zero.
IMAGE_FILE_LOCAL_SYMS_STRIPPED0x0008COFF symbol table entries for local symbols have been removed. This flag is deprecated and should be zero.
IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010Obsolete. Aggressively trim working set. This flag is deprecated for Windows 2000 and later and must be zero.
IMAGE_FILE_LARGE_ADDRESS_ AWARE 0x0020Application can handle > 2-GB addresses.
0x0040This flag is reserved for future use.
IMAGE_FILE_BYTES_REVERSED_LO 0x0080Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. This flag is deprecated and should be zero.
IMAGE_FILE_32BIT_MACHINE 0x0100Machine is based on a 32-bit-word architecture.
IMAGE_FILE_DEBUG_STRIPPED 0x0200Debugging information is removed from the image file.
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP 0x0400If the image is on removable media, fully load it and copy it to the swap file.
IMAGE_FILE_NET_RUN_FROM_SWAP0x0800If the image is on network media, fully load it and copy it to the swap file.
IMAGE_FILE_SYSTEM 0x1000The image file is a system file, not a user program.
IMAGE_FILE_DLL 0x2000The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes, although they cannot be directly run.
IMAGE_FILE_UP_SYSTEM_ONLY 0x4000The file should be run only on a uniprocessor machine.
IMAGE_FILE_BYTES_REVERSED_HI 0x8000Big endian: the MSB precedes the LSB in memory. This flag is deprecated and should be zero.



结构体: IMAGE_OPTIONAL_HEADER
说明: 可选的映像头格式。
头文件: winnt.h
帮助文档: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header32
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD               Magic;
BYTE               MajorLinkerVersion;
BYTE               MinorLinkerVersion;
DWORD                SizeOfCode;
DWORD                SizeOfInitializedData;
DWORD                SizeOfUninitializedData;
DWORD                AddressOfEntryPoint;
DWORD                BaseOfCode;
DWORD                BaseOfData;
DWORD                ImageBase;
DWORD                SectionAlignment;
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;
DWORD                NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory;
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

参数说明: 仅供参考, 详细说明请参考原文.
      Magic
                映像类型
      MajorLinkerVersion
                链接器的主要版本号。      
      MinorLinkerVersion
                链接器的次要版本号。
      SizeOfCode
                代码段的大小.
      SizeOfInitializedData
                初始化数据段的大小.
      SizeOfUninitializedData
                未初始化数据段的大小.
      AddressOfEntryPoint
                入口点地址.
      BaseOfCode
                代码基址.
      BaseOfData
                数据基址.
      ImageBase
                映像基址.
      SectionAlignment
                内存对齐.
      FileAlignment
                文件对齐
      MajorOperatingSystemVersion
                主操作系统的主要版本号.
      MinorOperatingSystemVersion
                主操作系统的次要版本号.
      MajorImageVersion
                映像的主要版本号.
      MinorImageVersion
                映像的次要版本号.
      MajorSubsystemVersion
                子系统的主要版本号.
      MinorSubsystemVersion
                子系统的次要版本号.
      Win32VersionValue
                此成员为保留成员.
      SizeOfImage
                映像内存大小.
      SizeOfHeaders
                DOS头、PE头、区块表的总大小.
      CheckSum
                映像文件校验和.
      Subsystem
                运行此映像所需的子系统
      DllCharacteristics
                映像的DLL特性
      SizeOfStackReserve
                初始化时的栈大小.
      SizeOfStackCommit
                初始化时实际提交的栈大小。
      SizeOfHeapReserve
                初始化时保留的堆大小.
      SizeOfHeapCommit
                初始化时实际提交的堆大小.
      LoaderFlags
                此成员已过时。
      NumberOfRvaAndSizes
                数据目录表的数量.
      DataDirectory
                数据目录表


Magic成员如下:

IMAGE_NT_OPTIONAL_HDR32_MAGIC0x10bThe file is an executable image.
IMAGE_NT_OPTIONAL_HDR64_MAGIC0x20bThe file is an executable image.
IMAGE_ROM_OPTIONAL_HDR_MAGIC0x107The file is a ROM image.


Subsystem成员如下:

      MAGE_SUBSYSTEM_UNKNOWN            0            Unknown subsystem.      
      IMAGE_SUBSYSTEM_NATIVE            1            No subsystem required (device drivers and native system processes).      
      IMAGE_SUBSYSTEM_WINDOWS_GUI            2            Windows graphical user interface (GUI) subsystem.      
      IMAGE_SUBSYSTEM_WINDOWS_CUI            3            Windows character-mode user interface (CUI) subsystem.      
      IMAGE_SUBSYSTEM_OS2_CUI            5            OS/2 CUI subsystem.      
      IMAGE_SUBSYSTEM_POSIX_CUI            7            POSIX CUI subsystem.      
      IMAGE_SUBSYSTEM_WINDOWS_CE_GUI            9            Windows CE system.      
      IMAGE_SUBSYSTEM_EFI_APPLICATION            10            Extensible Firmware Interface (EFI) application.      
      IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER            11            EFI driver with boot services.      
      IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER            12            EFI driver with run-time services.      
      IMAGE_SUBSYSTEM_EFI_ROM            13            EFI ROM image.      
      IMAGE_SUBSYSTEM_XBOX            14            Xbox system.      
      IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION            16            Boot application.      


DllCharacteristics成员如下:

0x0001Reserved.
0x0002Reserved.
0x0004Reserved.
0x0008Reserved.
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE0x0040The DLL can be relocated at load time.
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY0x0080Code integrity checks are forced. If you set this flag and a section contains only uninitialized data, set the PointerToRawData member ofIMAGE_SECTION_HEADER for that section to zero; otherwise, the image will fail to load because the digital signature cannot be verified.
IMAGE_DLLCHARACTERISTICS_NX_COMPAT0x0100The image is compatible with data execution prevention (DEP).
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION0x0200The image is isolation aware, but should not be isolated.
IMAGE_DLLCHARACTERISTICS_NO_SEH0x0400The image does not use structured exception handling (SEH). No handlers can be called in this image.
IMAGE_DLLCHARACTERISTICS_NO_BIND0x0800Do not bind the image.
0x1000Reserved
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER0x2000A WDM driver.
0x4000Reserved.


DataDirectory成员如下:

MAGE_DIRECTORY_ENTRY_ARCHITECTURE7Architecture-specific data
IMAGE_DIRECTORY_ENTRY_BASERELOC5Base relocation table
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT11Bound import directory
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR14COM descriptor table
IMAGE_DIRECTORY_ENTRY_DEBUG6Debug directory
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT13Delay import table
IMAGE_DIRECTORY_ENTRY_EXCEPTION3Exception directory
IMAGE_DIRECTORY_ENTRY_EXPORT0Export directory
IMAGE_DIRECTORY_ENTRY_GLOBALPTR8The relative virtual address of global pointer
IMAGE_DIRECTORY_ENTRY_IAT12Import address table
IMAGE_DIRECTORY_ENTRY_IMPORT1Import directory
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG10Load configuration directory
IMAGE_DIRECTORY_ENTRY_RESOURCE2Resource directory
IMAGE_DIRECTORY_ENTRY_SECURITY4Security directory
IMAGE_DIRECTORY_ENTRY_TLS9Thread local storage directory

1.2 PE文件关键结构图:

1.3 获取PE头信息
    1. DOS头
      文件地址 + 0
    2. PE头
      文件地址 + IMAGE_DOS_HEADER.e_lfanew
    3. 节表头
      文件地址 + IMAGE_DOS_HEADER.e_lfanew + sizeof(IMAGE_NT_HEADERS)
      或使用宏 IMAGE_FIRST_SECTION

      // 读取文件
      CFile m_file;
      CFileException m_fileEx;
      m_file.Open(FilePathName, CFile::modeRead | CFile::typeBinary, &m_fileEx);
      unsigned int FileLenght = (unsigned int)m_file.GetLength();
      DataBuff = new char;
      m_file.Read(DataBuff, FileLenght);
      m_file.Close();

      // DOS头
      IMAGE_DOS_HEADER * DosHead = (IMAGE_DOS_HEADER *)(DataBuff + 0);
               
      // NT头
      IMAGE_NT_HEADERS * NTHead = (IMAGE_NT_HEADERS *)(DataBuff + DosHead->e_lfanew);

      // 节表头
      IMAGE_SECTION_HEADER *SectionHead = (IMAGE_SECTION_HEADER *)(DataBuff + DosHead->e_lfanew + sizeof(IMAGE_NT_HEADERS));



Avenshy 发表于 2020-10-30 22:28

太高深了

风逝998 发表于 2020-10-30 22:36

高深,幸苦楼主

jzf1987 发表于 2020-10-30 22:55

楼主大神

liujieboss 发表于 2020-10-30 23:41

谢谢楼主

whngomj 发表于 2020-10-31 07:25

谢谢楼主

花好s月圆 发表于 2020-10-31 07:38

小甲鱼有一套讲PE的视频不错的。

yushunjian 发表于 2020-10-31 07:57

高深,幸苦楼主{:1_927:}

appsion 发表于 2020-10-31 10:25

花好s月圆 发表于 2020-10-31 07:38
小甲鱼有一套讲PE的视频不错的。

谢谢, 有空去看看

飞龙project 发表于 2020-10-31 11:24

问下怎么才能制作自己的pe系统呢?多谢了
页: [1] 2
查看完整版本: PE 文件解析