3.PE文件的结构
3.2 NT头
由一个IMAGE_NT_HEADERS结构组成,该结构中包含了PE文件被载入内存时需要用到的重要域。通过DOS header中的e_lfanew,可以直接定位到真正的PE Header部分。该结构体的大小为0xf8字节。
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE签名
IMAGE_FILE_HEADER FileHeader; //PE头
IMAGE_OPTIONAL_HEADER32 OptionalHeader; //PE可选头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
3.2.1 Signature
该数据大小为0x04字节,其值固定位0x4550,ASCII字符显示为PE标识。由上面计算到PE头的起始位置0x00e0处看到,开始的4个字节确实为PE。
3.2.2 FileHeader
PE文件头数据由IMAGE_FILE_HEADER结构体组成,该结构体大小为0x14字节,该结构体的具体内容如下:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //CPU的MAchine码,Intel 386为0x014c
WORD NumberOfSections; //节区数目
DWORD TimeDateStamp; //文件创建日期
DWORD PointerToSymbolTable; //COFF文件符号表在文件中的偏移
DWORD NumberOfSymbols; //符号表的数量
WORD SizeOfOptionalHeader; //可选头大小,固定值0xe0
WORD Characteristics; //文件信息标志如dll、exe
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
每个成员的具体信息如下:
-
Machine
该数据大小为2字节,标识该文件的运行平台其值具体为以下部分:
#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 #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
可以看到该文件的机器码为0x014c,从上述信息中查找为Intel 386。
-
NumberOfSections
该数据大小为2字节,标识该PE文件包含多少个节区。
可以看到该PE文件的节区数量为0x0005,即5个,使用PE tools查看,该PE包含5个节区
-
TimeDateStamp
该数据大小为4字节,标识PE文件的创建时间。
该PE文件的创建时间为0x61767c9c,该时间表示的是从1970年1月1日0时0分到创建时经过的秒数。
可以使用PE tools查看该数据解析得到具体时间。
-
PointerToSymbolTable
该数据大小为4字节,表示COFF文件符号表在文件中的偏移,该PE文件中的值为0。
-
NumberOfSymbols
该数据大小为4字节,表示符号表的数量,该PE文件中的值为0。
-
SizeOfOptionalHeader
该数据大小为2字节,标识PE可选头部的大小,其值固定为0xE0,可选头将在下一小节中讲解。
-
Characteristics
该数据大小为2字节,标识可执行文件的属性。其2个字节一共16位,从低到高每一位都代表一种属性(第7位不表示),每位的1表示具有该属性,0表示不具有该属性。其属性的具体内容如下所示:
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // 第1位 Relocation info stripped from file. #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // 第2位 File is executable (i.e. no unresolved externel references). #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // 第3位 Line nunbers stripped from file. #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // 第4位 Local symbols stripped from file. #define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // 第5位 Agressively trim working set #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // 第6位 App can handle >2gb addresses #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // 第8位 Bytes of machine word are reversed. #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 第9位 32 bit word machine. #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // 第10位 Debugging info stripped from file in .DBG file #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // 第11位 If Image is on removable media, copy and run from the swap file. #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // 第12位 If Image is on Net, copy and run from the swap file. #define IMAGE_FILE_SYSTEM 0x1000 // 第13位 System File. #define IMAGE_FILE_DLL 0x2000 // 第14位 File is a DLL. #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // 第15位 File should only be run on a UP machine #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // 第16位 Bytes of machine word are reversed.
可以看到该文件的属性值为0x0102,即0000 0001 0000 0010,文件的第2位和第9位为1,表示该文件为可执行文件,需要32位机器。
3.2.3 OptionalHeader
该数据由IMAGE_OPTIONAL_HEADER32结构组成,该结构大小为0xE0字节,和FileHeader中SizeOfOptionalHeader标识的一致。可选头部包含了很多关于可执行映像的重要信息,是不可缺少的头部信息。该结构的具体内容如下:
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
// 标准域
WORD Magic; //可选头类型
BYTE MajorLinkerVersion; //主链接器的版本号
BYTE MinorLinkerVersion; //副链接器的版本号
DWORD SizeOfCode; //代码段大小
DWORD SizeOfInitializedData; //初始化数据大小
DWORD SizeOfUninitializedData; //未初始化数据大小
DWORD AddressOfEntryPoint; //程序入口点地址RVA
DWORD BaseOfCode; //代码段起始基址RVA
DWORD BaseOfData; //数据段起始基址RVA
// NT附加域
DWORD ImageBase; //镜像基址
DWORD SectionAlignment; //节在内存中的对齐大小
DWORD FileAlignment; //节在文件中的对齐大小
WORD MajorOperatingSystemVersion;//主操作系统版本号
WORD MinorOperatingSystemVersion;//副操作系统版本号
WORD MajorImageVersion; //主镜像版本号
WORD MinorImageVersion; //副镜像版本号
WORD MajorSubsystemVersion; //主子系统版本号
WORD MinorSubsystemVersion; //副子系统版本号
DWORD Win32VersionValue; //Win32版本值,必须为0
DWORD SizeOfImage; //镜像在内存中大小
DWORD SizeOfHeaders; //PE头物理大小,使用FileAlignment对齐后的
DWORD CheckSum; //校验和
WORD Subsystem; //子系统
WORD DllCharacteristics; //DLL标志
DWORD SizeOfStackReserve; //运行时为每个线程栈保留内存的大小
DWORD SizeOfStackCommit; //运行时每个线程栈初始占用内存大小
DWORD SizeOfHeapReserve; //运行时为进程堆保留内存大小
DWORD SizeOfHeapCommit; //运行时进程堆初始占用内存大小
DWORD LoaderFlags; //载入器标志,必须为0
DWORD NumberOfRvaAndSizes; //数据目录的项数即IMAGE_NUMBEROF_DIRECTORY_ENTRIES为0x0010
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//数据目录
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
接下来介绍每个成员的具体内容:
-
Magic
该数据大小为2字节,标识可选头的类型,主要有以下几种:
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010B //32位应用程序 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020B //64位应用程序 #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107 //ROM镜像
该PE文件可选头的magic为0x010B,说明为32位应用程序。
-
MajorLinkerVersion and MinorLinkerVersion
这个两个数据大小都为1字节,标识主/副链接器的版本
从图中看出该PE的主链接器值为0x0A,副链接器为0。
-
SizeOfCode
该数据大小为4字节,标识PE文件中代码段(.text)的物理大小。
可以看出该PE文件的.text段大小为0x0C00,使用PE tools查看节区大小也为该值。
-
SizeOfInitializedData and SizeOfUninitializedData
两个数据大小都为4字节,分别标识已初始化和未初始化数据的大小
可以看出该PE文件已初始化数据大小为0x1400字节,未初始化大小为0。
-
AddressOfEntryPoint
该数据大小为4字节,标识程序的入口地址。PE文件在装载到内存后时,将会根据该RVA地址加上ImageBase基址,计算程序的入口VA,并从该处执行整个程序。
可以看出该PE文件的EP(RVA)为0x15A8,一般PE文件的基址都是0x400000,因此当该PE文件装载到内存中时,将会从0x4015A8处开始执行程序指令。
-
BaseOfCode
该数据大小为4字节,标识代码段(.text)起始地址的RVA
该PE文件的.text段的RVA为0x1000,从PE tools中查看
-
BaseOfData
该数据大小为4字节,标识数据段(.rdata、.data、.idata)起始地址的RVA
该PE文件的.text段的RVA为0x2000,从PE tools中查看
-
ImageBase
该数据大小为4字节,标识PE文件加载到虚拟内存中的基地址,一般的PE文件都会加载到0x400000处。
该PE文件的基址也是0x400000。
-
SectionAlignment
该数据大小为4字节,标识所有节区加载到内存中时需要对齐的大小,即每个节区大小都应该是此数据的整数倍。
该PE文件的节对齐大小为0x1000字节,从PE tools查看节区信息
可以看到每个节区的虚拟内存起始偏移都是0x1000的整数倍。
-
FileAlignment
该数据大小为4字节,标识所有节区在物理磁盘中需要对齐的大小,即每个节区大小都应该是此数据的整数倍。
该PE文件中物理对齐大小为0x0200字节,从PE tools查看节区信息
可以看到每个节区的物理起始偏移都是0x0200的整数倍。
-
MajorOperatingSystemVersion and MinorOperatingSystemVersion
两个数据大小都为2字节,标识运行该PE文件所需主/副操作系统版本号,该数据并不重要。
该PE文件的主OS版本号为0x05,副OS版本号为0x01。
-
MajorImageVersion and MinorImageVersion
两个数据大小都为2字节,标识镜像的主/副版本,由开发者指定
该PE文件的主镜像版本号为0,副镜像版本号为0。
-
MajorSubsystemVersion and MajorSubsystemVersion
两个数据大小都为2字节,标识标识运行该PE文件所需主/副子操作系统版本号,该数据并不重要。
该PE文件的主OS版本号为0x05,副OS版本号为0x01。
-
Win32VersionValue
该数据大小为4字节,其值必须为0。
-
SizeOfImage
该数据大小为4字节,标识PE文件加载到内存中时占虚拟地址空间的大小,从基址开始。该值根据SectionAlignment对齐。如果SectionAlignment和FileAlignment值相等,则该PE文件在物理磁盘的大小也是该值。
该PE文件的占虚拟地址空间镜像大小为0x6000字节。
-
SizeOfHeaders
该数据大小为4字节,标识PE头部的大小(从文件开始到节区表结束)
该PE文件的PE头大小为0x0400字节。
-
CheckSum
该数据大小为4字节,标识PE文件的校验和。
该PE文件的校验和为0x5D6B
-
Subsystem
该数据大小为2字节,标识运行该PE文件所需子系统,其值具体为以下几种:
#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. #define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. #define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. #define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. #define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. #define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 // Image runs in the Windows CE subsystem. #define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 // #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 // #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 // #define IMAGE_SUBSYSTEM_EFI_ROM 13 #define IMAGE_SUBSYSTEM_XBOX 14 #define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16
该PE文件子系统值为0x0003。
-
DllCharacteristics
该数据大小为2字节,标识DLL的文件属性,只对DLL有效。其2个字节一共16位,从低7位到高16位,每位代表一种属性,1表示具有该属性,0表示不具有该属性。其属性的具体内容如下所示:
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 // 第7位 DLL can move. #define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 // 第8位 Code Integrity Image #define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 // 第9位 Image is NX compatible #define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 // 第10位 Image understands isolation and doesn't want it #define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 // 第11位 Image does not use SEH. No SE handler may reside in this image #define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 // 第12位 Do not bind this image. // 0x1000 // 第13位 Reserved. #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 // 第14位 Driver uses WDM model // 0x4000 // 第15位 Reserved. #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 //第16位
该PE文件DLL标志值为0x8140
-
SizeOfStackReserve and SizeOfStackCommit
两个数据大小都为4字节,标识PE文件运行时为每个线程栈保留的虚拟内存大小,以及初始占用大小。
默认线程栈分配0x100000字节(1MB),初始占用0x1000字节(4KB,一个内存页)。
-
SizeOfHeapReserve and SizeOfHeapCommit
两个数据大小都为4字节,标识PE文件运行时为进程堆保留的虚拟内存大小,以及初始占用大小。
默认进程堆分配0x100000字节(1MB),初始占用0x1000字节(4KB,一个内存页)。
-
LoaderFlags
该数据大小为4字节,与调试有关,默认为0。
-
NumberOfRvaAndSizes
该数据大小为4字节,标识下面的数据目录表的项数,其值默认为0x0010,和IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16宏常量一致。
-
DataDirectory
该数据由IMAGE_DATA_DIRECTORY结构数据构成,该数组一共16项,每个IMAGE_DATA_DIRECTORY结构大小为0x08字节,一共占用0x80字节,该结构的具体内容如下:
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; //数据起始RVA地址 DWORD Size; //数据长度 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
该结构指明一个数据区域在虚拟地址空间的位置和大小。而DataDirectory其中每个数组成员的IMAGE_DATA_DIRECTORY结构都指向PE文件的一个特定的数据区域,其指向的数据区域由索引值给出,具体索引值对应的数据区域如下:
#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 // 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
通过索引值在计算数组中的偏移,即可获得出具体数据域在PE文件中的RVA和大小。
例如查看PE文件中一个重要的数据区域导入表,导入表记录程序所需导入的DLL及其使用的函数地址。该数据的索引为1,即偏移整个数组开始0x08字节,数组开始位置为0x158,因此该数据其开始在0x160。
其VirtualAddress和Size各占4个字节,因此导入表的RVA为0x2308,大小为0x0050。使用PE tools查看目录信息。
可以根据RVA TO RAW公式计算器在PE中的物理偏移。查看区段信息,该数据位于.rdata节区,.rdata节区的VirtualAddress为0x2000,PointerToRawData为0x1000,使用公式计算
RAW-0x1000=0x2308-0x2000,得出RAW为0x1308即为导入表所在的物理地址,后续介绍了导入表的详细结构后,将会从该地址解析导入表区域。
3.3 节区表
节区表位于PE文件NT头之后,也是PE头的最后一个部分。节区表记录了PE文件中所有节区的相关属性,节区表由一系列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序是一致的。全部有效结构的最后以一个空的IMAGE_SECTION_HEADER结构作为结束,所以节表中IMAGE_SECTION_HEADER结构数量等于节的数量加一。IMAGE_SECTION_HEADER结构体大小0x28字节,为该结构体的内容如下:
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //节表名称
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;
接下来介绍每个具体的成员变量:
-
Name
该数据为BYTE的数组,数组长度为8,大小为8个字节。该数据标识此节区表的名称,节区的名称和含义主要有以下几种:
节区名称 描述 .text 默认的代码区块,其内容为指令代码 .data 默认的读/写数据区块 .rdata 默认的只读数据区块 .idata 存放导入表信息 .edata 存放导出表信息 .rsrc 资源,包含模块的全部资源 .bss 存放未初始化数据 .crt 用于支持C++运行时(CRT)添加的数据 .tls 线程本地存储区 .reloc 可执行文件的基址重定位 该PE文件的该节区表的Name为.text
-
Misc
该数据为共用体,数据大小为4字节,一般为VirtualSize标识节区在虚拟内存中的大小,是该节在没有进行SectionAlignment对齐前的实际大小。
该PE文件的.text节区的VirtualSize为0x0B65字节。
-
VirtualAddress
该数据的大小为4字节,标识该节区被装载到虚拟内存中时的偏移地址(RVA),该地址已按照SectionAlignment大小对齐。
该PE文件的.text节区的起始虚拟内存地址为0x1000。
-
SizeOfRawData
该数据的大小为4字节,标识该节区在磁盘中所占物理大小,该值已按照FileAlignment大小对齐。
该PE文件的.text节区的物理大小为0x0C00。
-
PointerToRawData
该数据的大小为4字节,标识该节区在磁盘上的PE文件中的偏移量。
该PE文件的.text节区从0x0400字节处开始。
-
PointerToRelocations
该数据的大小为4字节,标识OBJ文件中,本区块重定位信息的偏移值,指向一个IMAGE_RELOCATION结构的数组。在exe文件中一般没用。
该PE文件的.text节区的重定向值为0。
-
PointerToLinenumbers
该数据的大小为4字节,标识行号表在文件中的偏移,主要用于调试相关,并不重要。
该PE文件的.text节区的行号表偏移为0。
-
NumberOfRelocations
该数据的大小为2字节,标识OBJ文件中重定位表中重定位数目。
该PE文件的.text节区的重定位数目为0。
-
NumberOfLinenumbers
该数据的大小为2字节,标识行号表中的行号数目,用于调试相关不重要。
该PE文件的.text节区的行号表行数为0。
-
Characteristics
该数据的大小为4字节,标识节区的相关属性,按位指出该节区的属性,若某一位为1则该节区具有该位代表的属性。节区的具体属性值如下所示,仅列出有含义的位属性:
//位数从低到高 #define IMAGE_SCN_SCALE_INDEX 0x00000001 //第1位 Tls index is scaled #define IMAGE_SCN_CNT_CODE 0x00000020 //第6位 Section contains code. #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 //第7位 Section contains initialized data. #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 //第8位 Section contains uninitialized data. #define IMAGE_SCN_LNK_INFO 0x00000200 //第10位 Section contains comments or some other type of information. #define IMAGE_SCN_LNK_REMOVE 0x00000800 //第12位 Section contents will not become part of image. #define IMAGE_SCN_LNK_COMDAT 0x00001000 //第13位 Section contents comdat. #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 //第15位 Reset speculative exceptions handling bits in the TLB entries for this section. #define IMAGE_SCN_GPREL 0x00008000 //第16位 Section content can be accessed relative to GP #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 //第25位 Section contains extended relocations. #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 //第26位 Section can be discarded. #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 //第27位 Section is not cachable. #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 //第28位 Section is not pageable. #define IMAGE_SCN_MEM_SHARED 0x10000000 //第29位 Section is shareable. #define IMAGE_SCN_MEM_EXECUTE 0x20000000 //第30位 Section is executable. #define IMAGE_SCN_MEM_READ 0x40000000 //第31位 Section is readable. #define IMAGE_SCN_MEM_WRITE 0x80000000 //第32位 Section is writeable.
该PE文件的.text节区的属性值为0x60000020,即第6位,第30位,和第31位为1,标识.text节区是可读,可执行,包含代码的节区。