当前位置: 首页 > news >正文

【逆向基础】十七、PE文件格式(二)

一、简介

本篇章主要PE文件组成部分中使用的结构体;根据结构体的成员变量去了解各个字节的含义。(ps:我们依旧以”cmd.exe“为例展开解析;)
在这里插入图片描述

二、DOS Header

1、结构体:IMAGE_DOS_HEADER

IMAGE_DOS_HEADER结构体的背景是为了兼容DOS文件,即拓展当时被人们广泛使用DOS文件的DOS EXE头。
下图是使用UE使用Hex Editor打开的cmd.exe文件中DOS Header的内容。以及大小为0x40个字节的结构体信息。
在这里插入图片描述

typedef struct _IMAGE_DOS_HEADER { // DOS的.EXE头部USHORT e_magic; 		// 魔术数字(0x5A4D  "MZ")****************USHORT e_cblp; 			// 文件最后页的字节数USHORT e_cp; 			// 文件页数USHORT e_crlc; 			// 重定义元素个数USHORT e_cparhdr; 		// 头部尺寸,以区块落为单位USHORT e_minalloc; 		// 所需的最小附加区块USHORT e_maxalloc; 		// 所需的最大附加区块USHORT e_ss; 			// 初始的SS值(相对偏移量)USHORT e_sp; 			// 初始的SP值USHORT e_csum; 			// 校验和USHORT e_ip; 			// 初始的IP值USHORT e_cs; 			// 初始的CS值(相对偏移量)USHORT e_lfarlc; 		// 重分配表文件地址USHORT e_ovno; 			// 覆盖号USHORT e_res[4]; 		// 保留字USHORT e_oemid; 		// OEM标识符(相对e_oeminfo)USHORT e_oeminfo; 		// OEM信息USHORT e_res2[10];		// 保留字LONG e_lfanew;     		// 新NT头的地址,************
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
1.1 e_magic:

e_magic表示DOS签名,所有未被加密的PE文件开始部分都有DOS签名(“MZ”:PE文件设计者Mark Zbikowski),

1.2 e_lfanew:

e_lfanew表示Name Table Heard的偏移地址;占用四个字节内存;

三、DOS Stub

DOS存根(Stub)位于DOS Header下方。可有可无,且大小不固定;由代码和数据混合而成。下图是使用UE使用Hex Editor打开的cmd.exe文件中DOS Stub的内容。
在这里插入图片描述

以下位对应汇编指令内容。PE文件带有MS-DOS兼容模式,可以在Dos环境下运行,输出“This program cannot be run in DOS mode”后终止。(在DOS环境中运行16位DOS代码,在Winsows环境中运行32位Windows代码)。
在这里插入图片描述

四、NameTable Header

1、结构体:IMAGE_NT_HEADERS32

IMAGE_NT_HEADERS32头主要由3个成员组成,下图是使用UE使用Hex Editor打开的cmd.exe文件中NT Header的内容。以及大小为0xF8个字节的结构体信息。

typedef struct _IMAGE_NT_HEADERS {DWORD Signature;							//签名IMAGE_FILE_HEADER FileHeader;				//文件头结构体IMAGE_OPTIONAL_HEADER32 OptionalHeader;		//可选头结构体
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
1.1、Signature

占用四个字节,其值位0x50450000 (“PE..”).

1.2、结构体:IMAGE_FILE_HEADER

IMAGE_FILE_HEADER结构体、文件内容、较为重要的结构体部分成员如下所示:
在这里插入图片描述

typedef struct _IMAGE_FILE_HEADER {USHORT Machine; 							//运行平台USHORT NumberOfSections;					//文件的区块数ULONG TimeDateStamp;						//文件创建日期和时间ULONG PointerToSymbolTable;					//指向符号表(用于调试)ULONG NumberOfSymbols;						//符号表中符号的个数(用于调试)USHORT SizeOfOptionalHeader;				//IMAGE_OPTIONAL_HEADER32结构的大小USHORT Characteristics;						//文件属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
1.2.1 Machine

MachineCUP芯片对应的专属ID;以下是定义在winnt.h文件中的Machine码; 当前cmd.exe对应的Machine = 0x8664;

#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
...
Endian
#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE
1.2.2 NumberOfSections

NumberOfSections表示当前文件中存在的节区数量,当前值必须大于零且与实际节区数一样,否则程序运行错误。

1.2.3 NumberOfOptionalHeader

NumberOfOptionalHeader表示IMAGE_OPTIONAL_HEADER32结构体的大小。
因为PE32+格式使用的是IMAGE_OPTIONAL_HEADER64结构体,所以PE文件需要区分结构体大小;

1.2.4 Characteristics

Characteristics表示文件属性。比如文件是否可运行,是否是exe文件等; 一下是winnt.h文件中的Characteristics值表示的属性;当前文件的characteristics = 0x0022; 即兼容两种属性IMAGE_FILE_EXECUTABLE_IMAGEIMAGE_FILE_LARGE_ADDRESS_AWARE; (注意:PE文件也存在不可执行的属性,类似".obj"文件)

#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_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#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_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.
1.3 节构体:IMAGE_OPTIONAL_HEADER32

IMAGE_OPTIONAL_HEADER32是PE头中占用空间最大的结构体。

typedef struct _IMAGE_OPTIONAL_HEADER {// Standard fields.WORD    Magic;								//标志字BYTE    MajorLinkerVersion;					//链接器主版本号BYTE    MinorLinkerVersion;					//链接器次版本号DWORD   SizeOfCode;							//所有含有代码的区块的大小DWORD   SizeOfInitializedData;				//所有初始化数据区块的大小DWORD   SizeOfUninitializedData;			//所有未初始化数据区块的大小DWORD   AddressOfEntryPoint;				//程序执行人口 RVADWORD   BaseOfCode;							//代码区块起始RVADWORD   BaseOfData;							//数据区块起始RVA// NT additional fields.DWORD   ImageBase;							//程序默认载人基地址DWORD   SectionAlignment;					//内存中区块的对齐值DWORD   FileAlignment;						//文件中区块的对齐值WORD    MajorOperatingSystemVersion;		//操作系统主版本号WORD    MinorOperatingSystemVersion;		//操作系统次版本号WORD    MajorImageVersion;					//用户自定义主版本号WORD    MinorImageVersion;					//用户自定义次版本号WORD    MajorSubsystemVersion;				//所需子系统主版本号WORD    MinorSubsystemVersion;				//所需子系统次版本号DWORD   Win32VersionValue;					//保留,通常被设置为0DWORD   SizeOfImage;						//映像载入内存后的总大小DWORD   SizeOfHeaders;						//MS-DOS头部、PE文件头、区块表总大小DWORD   CheckSum;							//映像校验和WORD    Subsystem;							//文件子系统WORD    DllCharacteristics;					//显示 DLL特性的旗标DWORD   SizeOfStackReserve;					//初始化时栈的大小DWORD   SizeOfStackCommit;					//初始化时实际提交栈的大小DWORD   SizeOfHeapReserve;					//初始化时保留堆的大小DWORD   SizeOfHeapCommit;					//初始化时实际保留堆的大小DWORD   LoaderFlags;						//与调试相关,默认值为0DWORD   NumberOfRvaAndSizes;				//数据目录表的项数IMAGE_DATA_DIRECTORY DataDirectory[16];		//数据目录表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
1.3.1 Magic

Magic = 0x010B时,表示使用结构体IMAGE_OPTIONAL_HEADER32Magic = 0x020B时,表示使用结构体IMAGE_OPTIONAL_HEADER64

1.3.2 AddressOfEntryPoint

AddressOfEntryPoint表示PE程序的入口点,是最先执行程序代码的地方,所以它的值表示程序执行代码的起始地址;其中地址值使用RVA(Relative
Virtual Address)值表示;

1.3.3 ImageBase

ImageBase表示基址;是PE文件被加载到内存时优先装入的地址;可通过编译器设置;
其中DLL文件的ImageBase默认值是0x00100000
其中exe文件的ImageBase默认值是0x00400000
执行PE文件是,PE装载其先创建进程(进行内存范围0~0xFFFFFFFF),再将文件载入内存,最后把EIP寄存器的值设置位`ImageBase

  • AddressOfEntryPoint`;
1.3.4 SectionAlignment

SectionAlignment表示节区在磁盘文件中的最小单位;不对齐则用null填充;

1.3.5 FileAlignment

FileAlignment表示节区在内存中的最小单位;不对齐则用null填充;

1.3.6 SizeOfImage

SizeOfImage表示加载PE文件到内存时,PE Image在虚拟内存中所占空间的大小;

1.3.7 SizeOfHeader

SizeOfHeader表示整个PE头的占用空间的大小,当前文件中SizeOfHeader = 0x400;
第一节区的起始位置在PE头位置之后;

1.3.8 Subsystem

Subsystem表示文件类型,也可称为子系统;如下图表示值对应含义。
在这里插入图片描述

1.3.8 NumberOfRvaAndSizes

NumberOfRvaAndSizes表示成员变量DataDirectory的个数(数组大小不一定是16个);即数据目录表的实际数量;

1.3.9 DataDirectory

DataDirectory表示IMAGE_DATA_DIRECTORY的结构体类型;数组表示每张表对应的虚拟地址和大小;结构体数组指定下标含义如下所示:

typedef struct _IMAGE_DATA_DIRECTORY {DWORD VirtualAddress;DWORD Size;
}IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
    DataDirectory[0] = "EXPORT Directory";        //函数导出表DataDirectory[1] = "IMPORT Directory";        //函数导入表DataDirectory[2] = "RESOURCE Directory";DataDirectory[3] = "EXCEPTION Directory";DataDirectory[4] = "SECURITY Di rectory";DataDirectory[5] = "BASERELOC Directory";DataDirectory[6] = "DEBUG Directory";DataDirectory[7] = "COPYRIGHT Directory";DataDirectory[8] = "GLOBALPTR Directory";DataDirectory[9] = "TLS Directory";          //线程局部存储器;用于反调试DataDirectory[10] = "LOAD CONFIG Directory";DataDirectory[11] = "BOUND IMPORT Directory";DataDirectory[12] = "IAT Directory";		//导入地址表,用于设置钩子DataDirectory[13] = "DELAY IMPORT Directory";DataDirectory[14] = "COM DESCRIPTOR Directory";DataDirectory[15] = "Reserved Directory";

五、Section Header

1、节构体:IMAGE_SECTION_HEADER

PE文件中包含如code(代码)、data(数据)、resource(资源)等节区。节区头定义了PE文件中各个节区的属性。并同故宫为每个截取设置不同特性,访问权限等,可以提高程序的安全性。
在这里插入图片描述
节区头是由IMAGE_SECTION_HEADER结构体组成的数组,每个结构体对应一个节区。

typedef struct _IMAGE_SECTION_HEADER {BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];//8字节的块名区块大小union {DWORD   PhysicalAddress;DWORD   VirtualSize;			//内存中节区所占大小} Misc;DWORD   VirtualAddress;				//区块的RVA地址DWORD   SizeOfRawData;				//在文件中对齐后的大小DWORD   PointerToRawData;			//在文件中的偏移,即节区起始位置DWORD   PointerToRelocations;		//在 OBJ文件中使用,重定位的偏移DWORD   PointerToLinenumbers;		//行号表的偏移(供调试用)WORD    NumberOfRelocations;		//在OBJ文件中使用,重定位项数目WORD    NumberOfLinenumbers;		//行号表中行号的数目DWORD   Characteristics;			//节区的属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
1.1 Name

Name表示节区名称,但是不一定用NULL结束;

1.2 VirtualAddress

VirtualAddress表示虚拟地址,是当前节区在内存的起始地址;

1.3 SizeOfRawData

SizeOfRawData表示文件偏移,是当前节区在磁盘文件中的偏移

1.4 Characteristics

Characteristics在头文件“winnt.h”的定义如下:

#define IMAGE_SCN_TYPE_NO_PAD                0x00000008  // Reserved.
#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.contents comdat.
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP
#define IMAGE_SCN_ALIGN_8BYTES               0x00400000  //
#define IMAGE_SCN_ALIGN_16BYTES              0x00500000  // Default alignment if no others are specified.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

六、小结

文本章详细讲解了PE文件头的信息。包括Dos HeaderDos StubNT HeaderSection Header等四个主要部分,并列举了其中包含的结构体信息。通过注释,举例的方式快速帮助我们了解PE文件最初的样子。时而观之,温故知新呀。


http://www.mrgr.cn/news/58358.html

相关文章:

  • itext自定义pdf
  • 2024源鲁杯CTF网络安全技能大赛题解-Round1
  • 系统架构图设计(轻量级架构)
  • ArcGIS计算落入面图层中的线的长度或面的面积
  • Android 图片相识度比较(pHash)
  • 上传大文件到Github
  • 16 使用宏定义定义常量
  • OFFER攻略 08| 130+个offer背后:AIGC产品经理成长之路,零基础入门到精通,收藏这一篇就够了
  • 汇编教程 最终:文件管理与内存管理
  • Jvm中的堆和栈
  • Docker容器的基础镜像:构建现代应用程序的基石
  • 讲一讲AOP的原理,AOP在哪些场景下会失效?
  • openresty安装
  • Ubuntu 下安装 Nginx
  • NativeCrash 率从万分位降到十万分位,我做了这几件事...
  • 对比两个el-table,差异数据突显标记
  • springboot仓库管理系统-计算机毕业设计源码19585
  • 集群分发脚本
  • WUP-MY-POS-PRINTER 旻佑热敏打印机票据打印uniapp插件使用说明
  • 被面试官怼了,对nacos的原理都不理解,还多年的微服务工作经验?
  • CTF-RE 从0到N 1-1-1 开始之前-c函数手册
  • 一年四起供应链投毒事件的幕后黑手
  • 储能蓝海:技术革新与成本骤降引爆市场
  • python_删除二维列表的制定列
  • 商汤科技裁员动真格,战略转型组织大变革
  • 基于STM32设计的智能鱼缸(蓝牙版)