> 文章列表 > PE文件格式

PE文件格式

PE文件格式

目录

介绍

PE文件格式

种类​编辑

基本结构

VA&RVA

PE头

DOS头

NT头:文件头

NT头:文件头

NT头:可选头


暂时看了这么多,后面内容会在补充~~

介绍

PE文件是Windows操作系统下使用的可执行文件。PE文件是指32位的可执行文件,也称为PE32。64位的可执行文件称为PE+或者PE32+,是PE文件的一种扩展形式。

PE文件格式

种类

严格的说,OBJ(对象)文件之外的所有文件都是可执行的,DLL,SYS文件等虽然不能直接在shell中运行,但是可以使用其他方法(调试器,服务等)执行。

基本结构

从DOS头(DOS header)到节区头(Section header)是PE头部分,其他的节区合称PE体。文件使用偏移(offset),内存中使用VA(虚拟地址)来表示位置。各节区头定义各节区在文件或内存中的大小,位置,属性。

VA&RVA

VA指的是进程虚拟内存的绝对地址,RVA是相对地址,他们满足关系
RVA+ImageBase=VA.

PE头

DOS头

为了充分考虑PE文件对DOS文件的兼容性,在PE头前面添加了IMAGE_DOS_HEADER结构体,结构如下:

其结构体大小64字节,其中需要知道2个重要成员:

e_magic:DOS签名

e_lfanew:指示NT头的偏移,即真正的PE文件头(不同文件拥有可变值)

 其中e_lfanew的偏移为+3C,如下演示:

可以看到DOS签名和e_lfanew为100h,那查找一下,正好是PE文件头。

NT头:文件头

IMAGE_NT_HEADERS其中第一个成员为签名结构体,值为50450000h(“PE”00),另外两个成员是文件头与可选头。

IMAGE_NT_HEADERS结构体大小为F8

NT头:文件头

如下演示:
其中第一个,第二个,第六个,第七个比较重要,记住。

NT头:可选头

IMAGE_OPTIONAL_HEADER结构

typedef struct _IMAGE_OPTIONAL_HEADER {
+18h    WORD    Magic;                                  //标志字,ROM映像(0107h),普通可执行文件(010Fh)
+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;
+50h    DWORD   SizeOfImage;    //映像装入内存后的总尺寸
+54h    DWORD   SizeOfHeaders;    //所有头+区块表的尺寸大小
+58h    DWORD   CheckSum;
+5Ch    WORD    Subsystem;             //可执行文件期望的子系统
+5Eh    WORD    DllCharacteristics;
+60h    DWORD   SizeOfStackReserve;
+64h    DWORD   SizeOfStackCommit;
+68h    DWORD   SizeOfHeapReserve;
+6Ch    DWORD   SizeOfHeapCommit;
+70h    DWORD   LoaderFlags;
+74h    DWORD   NumberOfRvaAndSizes;       //下边数据目录的项数,这个字段自windows NT发布以来一直是16
+78h    IMAGE_DATA_DIRECTORY DataDirectory  //数据目录表[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

在 IMAGE_OPTIONAL_HEADER32结构体中需要关注下列成员,这些值是文件运行必须的,错误将导致文件不能正常运行。

#1.Magic

在IMAGE_OPTIONAL_HEADER32结构体时,Magic码为10B,IMAGE_OPTIONAL_HEADER64结构体时,Magic码为20B。

#2.AddressOfEntryPoint

持有EP的RVA值,该值指出程序最先执行的代码起始地址

#3.ImageBsae

进程虚拟内存范围0-FFFFFFFF(32位系统)。EXE,DLL文件被装载到用户内存为0-7FFFFFFF,SYS文件被载入内核内存的80000000-FFFFFFFF,一般而言,使用VC++/VB/Delphi创建exe,其基址为00400000,DLL文件的基地址10000000,。

#4.SectionAlignment,FileAlignment

FileAlignment指定了节区在磁盘文件中的最小单位,SectionAlignment指定了节区在内存中的最小单位。磁盘文件或内存的节区大小必定为FileAlignment或SectionAlignment值的整数倍

#5.SizeOfImage

加载PE文件到内存时,指定了PE IMAGE在虚拟内存中所占空间大小

#6.SizeOfHeaders

指出整个PE头的大小。该值也必须是FileAlignment整数倍。第一节区所在位置与SizeOfHeaders距文件开始偏移的量相同

#7.Subsystem

用来区分系统驱动文件与普通可执行文件

#8.NumberOfRvaAndSizes

用来指定DataDirectory数组的个数

#9.DataDirectory

它是由IMAGE_DATA_DIRECTORY结构体组成的数据,数组的每项都有被定义的值,这个结构分为2个部分:
VirtualAddress Dword ?;  数据起始RVA

isize Dword ?; 数据块的长度

DataDirectory结构体数组:

DataDirectory[0] = EXPORT Directory           //导出表
DataDirectory[1] = IMPORT Directory            //导入表
DataDirectory[2] = RESOURCE Directory      //资源
DataDirectory[3] = EXCEPTION Directory     //异常(具体资料不详)
DataDirectory[4] = SECURITY Directory        //异常(具体资料不详)
DataDirectory[5] = BASERELOC Directory    //重定位表
DataDirectory[6] = DEBUG Directory           //调试信息
DataDirectory[7] = COPYRIGHT Directory   //版权信息
DataDirectory[8] = GLOBALPTR Directory   //具体资料不详
DataDirectory[9] = TLS Directory          //Thread Local Storage
DataDirectory[A] = LOAD_CONFIG Directory  //具体资料不详
DataDirectory[B] = BOUND_IMPORT Directory //具体资料不详
DataDirectory[C] = IAT Directory                 //导入函数地址表
DataDirectory[D] = DELAY_IMPORT Directory //具体资料不详
DataDirectory[E] = COM_DESCRIPTOR Directory  //具体资料不详
DataDirectory[F] = Reserved Directory          //未使用