PE简介

PE文件衍生于早期建立的COFF文件格式,EXE和DLL文件实际上用的是同一种文件格式,唯一的区别就是用一个字段标识出这个文件是EXE还是DLL。64位Windows格式为PE32+。只是简单的将以前的32位字段扩展到64位。

重要要点

要认识到PE文件不是作为单一内存映射文件被装入内存的。
PE加载器通过遍历PE文件决定哪一部分被映射
磁盘上的数据结构布局和内存中的数据结构布局是一致的。
PE文件被装入内存后,内存中的版本称为模块。起始地址(也被称为基地址ImageBase)被当做模块句柄
按照默认设置,用VC++建立起来的EXE文件基地址是00400000h,DLL文件基地址是10000000h
PE尽管有一个首选的载入基址,但是他们可以载入到进程空间的任何地方,所以不能依赖PE的载入点,所以出现了相对虚拟地址RVA(Relative Virtual Address).PE用语里,实际的内存基址称为VA(Virtual Address)
VA = ImageBase + RVA

PE文件结构:

DOS头

由DOS MZ头和DOS stub组成,其中最重要的是e_magic 和 e_lfanew(file address of new header)
**e_magic **为固定的5A4Dh,其ascii值为“MZ”
e_lfanew为真正的PE文件头(PE Header)的相对偏移(很重要!!!) 位于开始的3C处,占用四个字节。

Portable Execution 文件分析

PE文件头

PE文件头是NT映像头的简称,即IMAGE_NT_HEADER
由三个字段组成
IMAGE_NT_HEADERS STRUCT
Signatrue DWORD ;其ASCII值为”PE00”
FileHeader IMAGE_FILE_HEADER
OptionalHeader IMAGE_OPTIONAL_HEADER32

IMAGE_FILE_HEADER STRUCT
Machine				WORD		运行平台
NumberOfSections	WORD		区块数目
TimeDateStamp		DWORD		时间戳(自从GMT开始的秒数)
PointerToSymbolTable	DWORD		符号表指针(用于调试)
NumberOfSymbols	DWORD		符号表符号个数
SizeOfOptionalHeader	WORD		可选头大小(IMAGE_OPTIONAL_HEADER32)
Characteristics		WORD		文件属性(通过相关的位运算得到的)
IMAGE_FILE_HEADER ENDS

可选映像头(IMAGE_OPTIONAL_HEADER32):

IMAGE_OPTIONAL_HEADER32 STRUCT
+18h    WORD    Magic;         // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
+1Ah    BYTE      MajorLinkerVersion;     // 链接程序的主版本号
+1Bh    BYTE      MinorLinkerVersion;     // 链接程序的次版本号
+1Ch    DWORD   SizeOfCode;     // 所有含代码的节的总大小
+20h    DWORD   SizeOfInitializedData;    // 所有含已初始化数据的节的总大小
+24h    DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h    DWORD   AddressOfEntryPoint;    // 程序执行入口RVA
+2Ch    DWORD   BaseOfCode;      // 代码的区块的起始RVA
+30h    DWORD   BaseOfData;      // 数据的区块的起始RVA
+34h    DWORD   ImageBase;      // 程序的首选装载地址
+38h    DWORD   SectionAlignment;      // 内存中的区块的对齐大小
+3Ch    DWORD   FileAlignment;      // 文件中的区块的对齐大小
+40h    WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
+42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
+44h    WORD    MajorImageVersion;       // 可运行于操作系统的主版本号
+46h    WORD    MinorImageVersion;       // 可运行于操作系统的次版本号
+48h    WORD    MajorSubsystemVersion;  // 要求最低子系统版本的主版本号
+4Ah    WORD    MinorSubsystemVersion;  // 要求最低子系统版本的次版本号
+4Ch    DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0
+50h    DWORD   SizeOfImage;       // 映像装入内存后的总尺寸
+54h    DWORD   SizeOfHeaders;       // 所有头 + 区块表的尺寸大小
+58h    DWORD   CheckSum;       // 映像的校检和
+5Ch    WORD    Subsystem;       // 可执行文件期望的子系统
+5Eh    WORD    DllCharacteristics;       // DllMain()函数何时被调用,默认为 0
+60h    DWORD   SizeOfStackReserve;       // 初始化时的栈大小
+64h    DWORD   SizeOfStackCommit;       // 初始化时实际提交的栈大小
+68h    DWORD   SizeOfHeapReserve;        // 初始化时保留的堆大小
+6Ch    DWORD   SizeOfHeapCommit;        // 初始化时提交的堆大小
+70h    DWORD   LoaderFlags;        // 与调试有关,默认为 0
+74h   DWORD   NumberOfRvaAndSizes;  // 下边数据目录的项数,这个字段自Windows NT 发布以来一直是16
+78h    IMAGE_DATA_DIRECTORY DataDirectory[16];  // 数据目录表(数目固定为16,很重要!!!)
IMAGE_OPTIONAL_HEADER32 ENDS

数据目录表成员如下:

•  #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
•  #define 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   -

先记录这两部分 后面的区块之后再补上~





相关文章:

  • 2021-08-22
  • 2021-06-23
  • 2021-06-17
  • 2021-07-09
  • 2021-09-01
  • 2022-01-24
  • 2021-06-17
猜你喜欢
  • 2021-11-20
  • 2021-10-04
  • 2022-03-10
  • 2021-07-20
  • 2021-07-22
  • 2021-10-04
  • 2021-07-12
相关资源
相似解决方案