《Windows PE》3.2.3 NT头-扩展头

扩展头(可选标头仅限映像文件)

OptionalHeader字段描述了可执行文件的更多细节和布局信息,如图像基址、入口点、数据目录、节表等。它的具体结构取决于文件的机器架构,可以是IMAGE_OPTIONAL_HEADER32(32位)或IMAGE_OPTIONAL_HEADER64(64位)结构体。

PE文件的扩展头位于文件头之后,其结构可以根据具体的文件类型和操作系统的架构而有所不同。

每个映像文件都有一个用于向加载程序提供信息的可选标头。 此标头是可选标头,因为某些文件(特别是obj对象文件)没有此标头。 对于映像文件,此标头是必需的。对象文件可以具有可选标头,但通常此标头在对象文件中没有函数,只是为了增加其大小。

 注意

1.可选标头的大小不是固定的。 COFF 标头中的 SizeOfOptionalHeader 字段必须用于验证对特定数据目录的文件的探测是否未超出 SizeOfOptionalHeader。 有关详细信息,请参阅MSDN COFF 文件标头(对象和映像)。

2.还应该使用可选标头的 NumberOfRvaAndSizes 字段(数据目录的项目数量)来确保对特定数据目录条目的探测不会超出可选标头。 此外,请务必验证可选标头魔数,以确保格式兼容性。

可选标头魔数确定映像是 PE32 还是 PE32+ (64位PE可执行文件。

PE 格式

0x10b

PE32

0x20b

PE32+

PE32+ 映像允许使用 64 位地址空间,同时会将映像大小限制为 2 GB。 其他 PE32+ 修改会在各自的部分中进行介绍。

可选标头本身具有三个主要部分。

偏移量 (PE32/PE32+)

大小 (PE32/PE32+)

标头部分

说明

0

28/24

标准字段

为 COFF 的所有实现(包括 UNIX)定义的字段。

28/24

68/88

特定于 Windows 的字段

用于支持 Windows(例如子系统)的特定功能的其他字段。

96/112

变量

数据目录

在映像文件中找到并由操作系统使用的特殊表(例如,导入表和导出表)的地址/大小对。

●可选标头标准字段(仅限映像)

可选标头的前八个字段是为 COFF 的每个实现定义的标准字段。 这些字段包含可用于加载和运行可执行文件的常规信息。 对于 PE32+ 格式,它们保持不变。

Offset

大小

字段

说明

0

2

Magic

标识映像文件状态的无符号整数。 最常见的数字是 0x10B,它将映像文件标识为普通可执行文件。 0x107 将映像文件标识为 ROM 映像,0x20B 将映像文件标识为 PE32+ 可执行文件。

2

1

MajorLinkerVersion

链接器主版本号。

3

1

MinorLinkerVersion

链接器次要版本号。

4

4

SizeOfCode

代码(文本)段的大小,或者如果有多个部分,则是所有代码段的和。

8

4

SizeOfInitializedData

初始化数据部分的大小,或者如果有多个数据部分,则是所有此类部分的和。

12

4

SizeOfUninitializedData

未初始化数据部分 (BSS) 的大小,或者如果有多个 BSS 部分,则是所有此类部分的和。

16

4

AddressOfEntryPoint

可执行文件加载到内存中时相对于映像基址的入口点地址。 对于程序映像,这是起始地址。 对于设备驱动程序,这是初始化函数的地址。 入口点对于 DLL 是可选的。 不存在入口点时,此字段必须为零。

20

4

BaseOfCode

加载到内存中后相对于代码开头部分映像基址的地址。

【注】PE32 包含位于 BaseOfCode 之后的此附加字段,此字段在 PE32+ 中不存在。

Offset

大小

字段

说明

24

4

BaseOfData

加载到内存中后相对于数据开头部分映像基址的地址。

●可选标头 Windows 特定字段(仅限映像)

接下来的 21 个字段是 COFF 可选标头格式的扩展。 它们包含 Windows 中的链接器和加载程序所需的其他信息。

偏移量 (PE32/PE32+)

大小(PE32/PE32+)

字段

说明

28/24

4/8

ImageBase

映像加载到内存中后第一个字节的首选地址;必须是 64 K 的倍数。DLL 的默认值为 0x10000000 Windows CE EXE 的默认值为 0x00010000。 Windows NT、Windows 2000、Windows XP、Windows 95、Windows 98 和 Windows Me 的默认值为 0x00400000。

32/32

4

SectionAlignment

各部分加载到内存中时的对齐值(以字节为单位)。 它必须大于或等于 FileAlignment(4KB)。 默认值为体系结构的页面大小。

36/36

4

FileAlignment

用于使映像文件中各部分的原始数据一致的对齐系数(以字节为单位)。 该值应为 2 的幂次方,介于 512 和 64K 之间(含)。 默认值为 512。 如果 SectionAlignment 小于体系结构的页面大小,则 FileAlignment 必须与 SectionAlignment 匹配。

40/40

2

MajorOperatingSystemVersion

所需操作系统的主版本号。

42/42

2

MinorOperatingSystemVersion

所需操作系统的次要版本号。

44/44

2

MajorImageVersion

映像的主版本号。

46/46

2

MinorImageVersion

映像的次要版本号。

48/48

2

MajorSubsystemVersion

子系统的主版本号。

50/50

2

MinorSubsystemVersion

子系统的次要版本号。

52/52

4

Win32VersionValue

保留,必须为零。

56/56

4

SizeOfImage

映像加载到内存中时的映像大小(以字节为单位),包括所有标头。 它必须是 SectionAlignment (4KB)的倍数。

60/60

4

SizeOfHeaders

MS DOS 存根、PE 标头和节标头的组合大小,其向上舍入到 FileAlignment (200H)的倍数。

64/64

4

CheckSum

映像文件的校验和。 用于计算校验和的算法已合并到 IMAGHELP.DLL 中。 加载时会检查以下内容是否有效:所有驱动程序、启动时加载的任何 DLL 以及加载到关键 Windows 进程中的任何 DLL。链接器选项可设置。

68/68

2

子系统

运行此映像所需的子系统。 有关详细信息,请参阅MSDN Windows 子系统。

70/70

2

DllCharacteristics

有关详细信息,请参阅MSDN此规范后面的 DLL 特征。

72/72

4/8

SizeOfStackReserve

要保留的堆栈的大小。 仅提交 SizeOfStackCommit;其余部分一次提供一页,直到达到保留大小。默认1MB大小。

76/80

4/8

SizeOfStackCommit

要提交的堆栈的大小。默认4KB大小。

80/88

4/8

SizeOfHeapReserve

要保留的本地堆空间的大小。 仅提交 SizeOfHeapCommit;其余部分一次提供一页,直到达到保留大小。默认1MB大小。

84/96

4/8

SizeOfHeapCommit

要提交的本地堆空间的大小。默认4KB大小。

88/104

4

LoaderFlags

保留,必须为零。

92/108

4

NumberOfRvaAndSizes

可选标头剩余部分中数据目录项的数目。 每项都描述位置和大小。

下面是在winnt.h头文件中扩展头结构体的定义:

●IMAGE_OPTIONAL_HEADER32

typedef struct _IMAGE_OPTIONAL_HEADER {

    //

    // Standard fields.

    //

    WORD    Magic;                   // PE文件的魔数,标识文件类型和操作系统架构

    BYTE    MajorLinkerVersion;        //链接器的主版本号

    BYTE    MinorLinkerVersion;        //链接器的次版本号

    DWORD   SizeOfCode;               //执行代码的大小(字节)

    DWORD   SizeOfInitializedData;     //已初始化数据的大小(字节)

    DWORD   SizeOfUninitializedData;   //未初始化数据的大小(字节)

    DWORD   AddressOfEntryPoint;       //程序的入口点(相对于映像基址的偏移量)

    DWORD   BaseOfCode;               //代码节的起始虚拟地址

    DWORD   BaseOfData;               //数据节的起始虚拟地址

    //

    // NT additional fields.

    //

    DWORD   ImageBase;                //可执行文件的首选基址(32位虚拟内存地址)

    DWORD   SectionAlignment;         //节在内存中对齐的大小

    DWORD   FileAlignment;            //节在文件中对齐的大小

    WORD    MajorOperatingSystemVersion;//操作系统的主版本号要求

    WORD    MinorOperatingSystemVersion;//操作系统的次版本号要求

    WORD    MajorImageVersion;        //可执行文件的主要版本号

    WORD    MinorImageVersion;        //可执行文件的次要版本号

    WORD    MajorSubsystemVersion;     //子系统的主要版本号要求

    WORD    MinorSubsystemVersion;     //子系统的次要版本号要求

    DWORD   Win32VersionValue;        //保留字段,用于兼容性

    DWORD   SizeOfImage;              //可执行文件在内存中的大小

    DWORD   SizeOfHeaders;            //文件头和节表的总大小(字节)

    DWORD   CheckSum;                 // PE文件的校验和

    WORD    Subsystem;                //可执行文件所依赖的子系统

    WORD    DllCharacteristics;        // DLL文件的特性

    DWORD   SizeOfStackReserve;        //为堆栈保留的内存大小(32位,1MB)

    DWORD   SizeOfStackCommit;        //实际分配给堆栈的内存大小(32位,4KB)

    DWORD   SizeOfHeapReserve;        //为堆保留的内存大小(32位,1MB)

    DWORD   SizeOfHeapCommit;         //实际分配给堆的内存大小(32位,4KB)

    DWORD   LoaderFlags;              //加载器标志

    DWORD   NumberOfRvaAndSizes;       //数据目录项的数量

    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//数据目录表

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

●IMAGE_OPTIONAL_HEADER64

typedef struct _IMAGE_OPTIONAL_HEADER64 {

    //

    // Standard fields.

    //

    WORD    Magic;                  // PE文件的魔数,标识文件类型和操作系统架构

    BYTE    MajorLinkerVersion;      //链接器的主版本号

    BYTE    MinorLinkerVersion;      //链接器的次版本号

    DWORD   SizeOfCode;              //执行代码的大小(字节)

    DWORD   SizeOfInitializedData;    //已初始化数据的大小(字节)

    DWORD   SizeOfUninitializedData;  //未初始化数据的大小(字节)

    DWORD   AddressOfEntryPoint;     //程序的入口点(相对于映像基址的偏移量)

    DWORD   BaseOfCode;              //代码节的起始虚拟地址

    //DWORD   BaseOfData;             //数据节的起始虚拟地址(缺失字段

    //

    // NT additional fields.

    //

    ULONGLONG ImageBase;                   //可执行文件的首选基址(64位虚拟内存地址)

    DWORD   SectionAlignment;            //节在内存中对齐的大小

    DWORD   FileAlignment;               //节在文件中对齐的大小

    WORD    MajorOperatingSystemVersion;  //操作系统的主版本号要求

    WORD    MinorOperatingSystemVersion;  //操作系统的次版本号要求

    WORD    MajorImageVersion;           //可执行文件的主要版本号

    WORD    MinorImageVersion;           //可执行文件的次要版本号

    WORD    MajorSubsystemVersion;        //子系统的主要版本号要求

    WORD    MinorSubsystemVersion;        //子系统的次要版本号要求

    DWORD   Win32VersionValue;           //保留字段,用于兼容性

    DWORD   SizeOfImage;                 //可执行文件在内存中的大小

    DWORD   SizeOfHeaders;               //文件头和节表的总大小(字节)

    DWORD   CheckSum;                   // PE文件的校验和

    WORD    Subsystem;                   //可执行文件所依赖的子系统

    WORD    DllCharacteristics;          // DLL文件的特性

    ULONGLONG SizeOfStackReserve;          //为堆栈保留的内存大小(64位,1MB)

    ULONGLONG SizeOfStackCommit;           //实际分配给堆栈的内存大小(64位,4KB)

    ULONGLONG SizeOfHeapReserve;           //为堆保留的内存大小(64位,1MB)

    ULONGLONG SizeOfHeapCommit;            //实际分配给堆的内存大小(64位,4KB)

    DWORD   LoaderFlags;                 //加载器标志

    DWORD   NumberOfRvaAndSizes;         //数据目录项的数量

    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//数据目录表

} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

●Magic Number(魔数):一个2字节的字段,指示文件类型和操作系统架构。常见的值有:

1.PE32(32位):0x10B

2.PE32+(64位):0x20B

我们可以通过这个字段来判断一个PE文件是32位PE文件还是64位PE文件。

●MajorLinkerVersion、MinorLinkerVersion:链接器的版本号。指示用于创建PE文件的链接器的主要和次要版本号。对执行PE文件没有任何影响。

●SizeOfCode:代码段的大小,以字节为单位。指示代码段的实际大小。该大小是基于文件对齐后的大小,而非内存对齐后的大小。PE文件以200H(512)字节为单位对齐。

●SizeOfInitializedData:已初始化数据段的大小,以字节为单位。指示已初始化数据段的实际大小。同样是基于文件对齐后的大小。

●SizeOfUninitializedData:未初始化数据段的大小,以字节为单位。指示未初始化数据段的实际大小。同样是基于文件对齐后的大小。

●AddressOfEntryPoint:程序入口点的RVA地址,相对于映像基址的偏移量。它指示PE文件在加载到内存后执行的第一条指令的地址。

程序的入口地址+ImageBase基址=程序在内存中开始执行的首地址(虚拟内存地址)。

●BaseOfCode:代码段的起始虚拟RVA地址。它指示代码段在内存中的起始位置。

●BaseOfData:数据段的起始虚拟RVA地址。它指示数据段在内存中的起始位置。

●ImageBase:可执行文件的首选基址(虚拟内存地址)。它指示PE文件在内存中加载时的首选基址。

●SectionAlignment:节在内存中的对齐大小。它指示节在内存中的边界对齐方式。通常内存以1000H(4KB)为单位对齐。

●FileAlignment:节在文件中的对齐大小。它指示节在PE文件中的边界对齐方式。通常内存以2000H(512)字节为单位对齐。

●MajorOperatingSystemVersion、MinorOperatingSystemVersion:所需的主操作系统版本号和次操作系统版本号。指示PE文件所需的最低操作系统版本。

●MajorImageVersion、MinorImageVersion:可执行文件的主要版本号和次要版本号。本PE映像文件的版本号。如果在这里存放版本号,则软件更新,网络升级时可以用于比对版本号。

●MajorSubsystemVersion、MinorSubsystemVersion:所需的主子系统版本号和次子系统版本号。指示PE文件所需的最低子系统版本。

●Win32VersionValue:保留字段,必须设置为0,用于兼容性。

●SizeOfImage:映像在内存中的大小,以字节为单位。指示PE文件(包括所有节区)在内存中占用的总大小。

●SizeOfHeaders:文件头和节表的总大小,以字节为单位。指示PE文件头部和节表的实际大小。

●CheckSum:PE文件的校验和。用于验证文件的完整性。校验和,在大多数的PE文件中,该值是0。但在一些内核模式的驱动程序和系统DLL中,该值则是必须存在且是正确的,比如kernel32.dll中PE的校验和是 0011E97Eh。在VS编译器的“项目属性”>“链接器”>“高级”>“设置校验和”选项中默认是关闭的。

●Subsystem:可执行文件所依赖的子系统类型。常见的值有:IMAGE_SUBSYSTEM_WINDOWS_GUI(2)表示图形用户界面子系统。IMAGE_SUBSYSTEM_WINDOWS_CUI(3)表示控制台用户界面子系统等。

我们可以在winnt.h头文件中查到这个字段的值,如下所示:

常量

Value

说明

IMAGE_SUBSYSTEM_UNKNOWN

0

未知子系统

IMAGE_SUBSYSTEM_NATIVE

1

设备驱动程序和本机 Windows 进程

IMAGE_SUBSYSTEM_WINDOWS_GUI

2

Windows 图形用户界面 (GUI) 子系统

IMAGE_SUBSYSTEM_WINDOWS_CUI

3

Windows 字符子系统

IMAGE_SUBSYSTEM_OS2_CUI

5

OS/2 字符子系统

IMAGE_SUBSYSTEM_POSIX_CUI

7

Posix 字符子系统

IMAGE_SUBSYSTEM_NATIVE_WINDOWS

8

本机 Win9x 驱动程序

IMAGE_SUBSYSTEM_WINDOWS_CE_GUI

9

Windows CE

IMAGE_SUBSYSTEM_EFI_APPLICATION

10

可扩展固件接口 (EFI) 应用程序

IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER

11

具有启动服务的 EFI 驱动程序

IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER

12

具有运行时服务的 EFI 驱动程序

IMAGE_SUBSYSTEM_EFI_ROM

13

EFI ROM 映像

IMAGE_SUBSYSTEM_XBOX

14

XBOX

IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION

16

Windows 启动应用程序。

●DllCharacteristics:DLL文件的特性标志。这个字段指定了DLL文件的一些特性和行为,如是否支持ASLR(地址空间布局随机化)、是否支持DEP(数据执行保护)、是否终止线程时卸载DLL等。常见的标志值包括IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE(0x40)表示支持ASLR,IMAGE_DLLCHARACTERISTICS_NX_COMPAT(0x100)表示支持DEP等。

常量

Value

说明

0x0001

保留,必须为零。

0x0002

保留,必须为零。

0x0004

保留,必须为零。

0x0008

保留,必须为零。

IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA

0x0020

映像可处理高熵 64 位虚拟地址空间。

IMAGE_DLLCHARACTERISTICS_
DYNAMIC_BASE

0x0040

DLL 可以在加载时重定位。

IMAGE_DLLCHARACTERISTICS_
FORCE_INTEGRITY

0x0080

强制实施了代码完整性检查。

IMAGE_DLLCHARACTERISTICS_
NX_COMPAT

0x0100

该映像与 NX 兼容。

IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION

0x0200

隔离感知,但不隔离映像。

IMAGE_DLLCHARACTERISTICS_ NO_SEH

0x0400

不使用结构化异常 (SE) 处理。 该映像中无法调用任何 SE 处理程序。

IMAGE_DLLCHARACTERISTICS_ NO_BIND

0x0800

请勿绑定此映像。

IMAGE_DLLCHARACTERISTICS_APPCONTAINER

0x1000

映像必须在 AppContainer 中执行。

IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER

0x2000

WDM 驱动程序。

IMAGE_DLLCHARACTERISTICS_GUARD_CF

0x4000

映像支持控制流保护。

IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE

0x8000

终端服务器感知。

   

以HelloWorld32.exe为例,其PE文件该字段的值为8140H,即支持终端服务器,应在AppContainer中执行,DLL可以被加载器基址随机化,例如X64 PE文件如果使用固定基址,则需要将DllCharacteristics字段改为8120H。而X86 PE文件改为8100H

以VS2017版本为例,在使用VS编译时,关于基址的设置如图3-8所示。默认为随机基址。我们也可以将其改为“否”,设置固定基址。

基址随机化是一种安全机制,旨在增加系统的抵抗力,防止恶意攻击者利用已知的内存布局来定位和执行恶意代码。基址随机化通过在每次加载可执行文件时随机分配基址(基地址)来实现。这意味着可执行文件的代码和数据的实际内存位置在每次加载时都会发生变化。

为了支持基址随机化,PE文件中的重定位节区记录了需要进行地址重定位的位置和方式。重定位节区包含了可执行文件中使用绝对地址或固定偏移的位置,这些位置需要在加载时进行动态调整,以适应新的基址。当加载器加载PE文件时,会根据重定位节区的信息,计算并更新这些位置的值,使它们指向正确的内存位置。

因此,在Windows 10环境下编译的PE文件会包含重定位节区,以便在加载时进行地址重定位,实现基址随机化的安全机制。这有助于提高系统的安全性,减少恶意攻击的成功率。

图3-8 VS链接器关于基址的设置选项

●SizeOfStackReserve:为栈保留的内存大小。指定在进程初始化时为栈分配的虚拟内存大小。

●SizeOfStackCommit:实际分配给栈的内存大小。指定在进程运行时实际使用的栈内存大小。

●SizeOfHeapReserve:为堆保留的内存大小。指定在进程初始化时为堆分配的虚拟内存大小。

●SizeOfHeapCommit:实际分配给堆的内存大小。指定在进程运行时实际使用的堆内存大小。

图3-9 修改链接器选项设置堆栈大小

通常编译器初始化时保留栈和堆的大小为1MB,而实际为栈和堆提交的大小为4KB。

这4个值可以在链接时修改的,如图3-9所示。在VS项目属性“链接器”可以设置。例如我们观察WinHex中的32位和64位记事本程序堆和栈的大小。

1.32位记事本

    DWORD   SizeOfStackReserve;        //为堆栈保留的内存大小(32位,256KB)

    DWORD   SizeOfStackCommit;        //实际分配给堆栈的内存大小(32位,68KB)

    DWORD   SizeOfHeapReserve;        //为堆保留的内存大小(32位,1MB)

    DWORD   SizeOfHeapCommit;         //实际分配给堆的内存大小(32位,4KB)

2.64位记事本

    ULONGLONG SizeOfStackReserve;      //为堆栈保留的内存大小(64位,512KB)

    ULONGLONG SizeOfStackCommit;       //实际分配给堆栈的内存大小(64位,68KB)

    ULONGLONG SizeOfHeapReserve;       //为堆保留的内存大小(64位,1MB)

    ULONGLONG SizeOfHeapCommit;        //实际分配给堆的内存大小(64位,4KB)

练习

       请读者将HelloWorld.c分别编译生成32位和64位程序,然后在WinHex中观察默认堆和栈的大小。

●LoaderFlags:加载器标志。这个字段保留供操作系统使用,用于指定加载器的一些行为和配置。

●NumberOfRvaAndSizes:数据目录项的数量。指示数据目录表中的目录项数量。

在32位和64位PE文件中,扩展头中的数据目录表中的目录项数量都是16个。这个字段的值是可以修改的。接下来我们就动手修改并测试。

实验十四:验证并修改32位和64位PE文件数据目录项的数量

我们分别在Windows10和XP两个不同操作系统环境中测试32位和64位HelloWorld.exe PE文件。我们分别在Windows10和XP系统中,分别编译HelloWorld.exe的汇编版本和C语言版本。在Windows10中编译环境为masm32和VS2017,XP系统中使用的编译环境为masm32和VC6.0。

●Windows 10操作系统测试环境

1.32位HelloWorld.exe(Win10汇编版本)文件偏移地址00000164H地址处,将默认0010H修改为0000~0010H之间的任一值,我们会发现,当数据目录项的数目大于等于6时,PE文件可以在Windows 10系统正常运行。如果数据目录项的数目小于6时,PE文件可以在Windows 10系统则不能正常运行。

2.32位HelloWorld32.exe(Win10 C语言版本)同样如此。

3.64位HelloWorld32.exe(Win10 C语言版本)同样如此。

4.32位HelloWorld.exe(Win XP汇编版本)文件偏移地址0000013CH地址处,将默认0010H修改为0000~0010H之间的任一值,我们会发现,当数据目录项的数目大于等于2时,PE文件可以在Windows 10系统正常运行。如果数据目录项的数目小于2时,PE文件可以在Windows 10系统则不能正常运行。

5.32位HelloWorld32.exe(Win XP C语言版本)同样如此。

●Windows XP操作系统测试环境

1.32位HelloWorld.exe(Win XP汇编版本)文件偏移地址0000013CH地址处,将默认0010H修改为0000~0010H之间的任一值,我们会发现,当数据目录项的数目大于等于2时,PE文件可以在Windows 10系统正常运行。如果数据目录项的数目小于2时,PE文件可以在Windows 10系统则不能正常运行。

2.32位HelloWorld32.exe(Win XP C语言版本)同样如此。

练习

       请读者分别修改测试32位和64位记事本程序数据目录表中的目录项数量。

 

结论

       1.数据目录表中的目录项数量是可以被修改的。

       2.数据目录表中的目录项数量的最小值与编译器的版本和操作系统的运行环境相关。

       3.PE文件所需数据目录项与具体的PE文件相关,不同的PE文件所依赖的数据目录项有所不同。

       稍后我们将详细分析各个数据目录项所代表的含义。

●DataDirectory:数据目录表。这是一个由IMAGE_DATA_DIRECTORY结构组成的数组,用于指定PE文件中各个数据结构的位置和大小

每个数据目录都提供 Windows 使用的表或字符串的地址和大小。 这些数据目录条目已全部加载到内存中,以便系统可以在运行时使用它们。数据目录是具有以下声明的 8 字节字段:

1.IMAGE_DATA_DIRECTORY结构

struct IMAGE_DATA_DIRECTORY

{

    public uint VirtualAddress;  // 数据结构的虚拟地址

    public uint Size;                 // 数据结构的大小

};

第一个字段 (VirtualAddress) 实际上是表的 RVA。 RVA 是加载表后相对于映像基址的表地址。 第二个字段提供以字节为单位的大小。 下表中列出了构成可选标头的最后一部分的数据目录。

 注意

目录数不是固定的。在查找特定目录之前,请检查可选标头中的 NumberOfRvaAndSizes 字段。此外,不要假定此表中的 RVA 指向节的开头,或者包含特定表的节具有特定名称。

偏移量 (PE/PE32+)

大小

字段

说明

96/112

8

导出表

导出表地址和大小。 有关详细信息,请参阅MSDN .edata 部分(仅限映像)

104/120

8

导入表

导入表地址和大小。 有关详细信息,请参阅MSDN  .idata 部分

112/128

8

资源表

资源表地址和大小。 有关详细信息,请参阅MSDN  .rsrc 部分

120/136

8

异常表

异常表地址和大小。 有关详细信息,请参阅MSDN  .pdata 部分

128/144

8

证书表

属性证书表地址和大小。 有关详细信息,请参阅MSDN  属性证书表(仅限映像)

136/152

8

基址重定位表

基址重定位表地址和大小。 有关详细信息,请参阅MSDN  .reloc 部分(仅限映像)

144/160

8

调试

调试数据起始地址和大小。 有关详细信息,请参阅 MSDN  .debug 部分

152/168

8

体系结构

已保留,必须为 0

160/176

8

全局指针

要存储在全局指针寄存器中的值的 RVA 此结构的大小成员必须设置为零。

168/184

8

TLS

线程本地存储 (TLS) 表地址和大小。 有关详细信息,请参阅 MSDN  .tls 部分

176/192

8

加载配置表

加载配置表地址和大小。 有关详细信息,请参阅MSDN  加载配置结构(仅限映像)

184/200

8

绑定导入

绑定导入表地址和大小。

192/208

8

IAT

导入地址表地址和大小。 有关详细信息,请参阅MSDN  导入地址表

200/216

8

延迟导入描述符

延迟导入描述符地址和大小。 有关详细信息,请参阅MSDN  延迟加载导入表(仅限映像)

208/224

8

CLR 运行时标头

CLR 运行时标头地址和大小。 有关详细信息,请参阅MSDN  .cormeta 部分(仅限对象)

216/232

8

保留,必须为零

3.16个数据目录表的目录项说明

■导出表(Export Table)

存储可执行文件导出的函数和符号信息,使其他模块可以访问这些导出。

■导入表(Import Table)

存储可执行文件导入的函数和符号信息,描述了可执行文件所依赖的其他模块和它们所提供的函数。

■资源表(Resource Table)

存储可执行文件使用的资源(如图标、位图、字符串等)的位置和大小信息。

■异常表(Exception Table)

存储可执行文件中的异常处理程序信息,用于处理程序中可能发生的异常情况。

■安全表(Security Table)

存储有关可执行文件的安全性设置和数字签名等信息。

■基址重定位表(Base Relocation Table)

存储基址重定位信息,用于处理可执行文件在加载时的基址变化,以便正确地调整内存中的地址。

■调试表(Debug Table)

存储调试符号和调试信息,用于程序的调试和错误追踪。

■体系结构相关(Architecture-specific)

存储与特定体系结构相关的数据,如IA-32特定的扩展数据。

■全局指针寄存器表(Global Pointer Register Table)

存储全局指针寄存器(如GP)的位置和大小信息。

■TLS表(Thread Local Storage Table)

存储线程本地存储(Thread Local Storage)相关的数据结构和信息。

■加载配置表(Load Configuration Table)

存储可执行文件的加载配置信息,如安全设置、堆栈大小等。

■绑定导入表(Binding Table)

存储可执行文件中的模块绑定信息,用于实现延迟绑定(lazy binding)和符号决议。

■导入函数地址表(Import Address Table)

存储导入函数的地址信息,用于在运行时解析和更新导入函数的地址。

■延迟加载导入表(Delay Load Import Table)

存储延迟加载导入函数的信息,用于在需要时才加载并解析导入函数。

■ CLR运行时头(CLR Runtime Header)

存储与托管代码和CLR(Common Language Runtime)相关的信息。

■保留(Reserved)

保留未使用的数据目录项。

 注意

具体的数据目录表的目录项可能会因不同的可执行文件格式而有所不同。上述列表是PE格式下常见的数据目录表的目录项,其他格式可能具有不同的目录项和描述。在实际使用中,建议参考相应可执行文件格式的文档以获得准确的目录项注释和描述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1552045.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【论文笔记】Flamingo: a Visual Language Model for Few-Shot Learning

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: Flamingo: a Visual Langu…

html空单元格的占位

先上代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title></head><body> <H1>我的WEB页面</H1><table border"2px" bgcolor"#7fffd4&…

【Ubuntu】安装常用软件包-mysql

我的几个服务是部署在docker的同一个网络里&#xff0c;这样相互访问就可以通过docker容器的名字访问&#xff0c;比如容器A访问容器B&#xff0c;就可以http://B:8080/xxx 这样访问&#xff0c;不用关心ip是多少。 所以mysql前面文章给安装到主机里&#xff0c;感觉有点坑自己…

JavaScript 网页设计案例 简单的电商案例 页面切换 数据搜索 动态网页

JavaScript 网页设计案例 简单的电商案例 页面切换 数据搜索 动态网页 1. 案例描述 以下是一个简单的产品展示网页&#xff0c;用户可以通过点击不同的产品类别按钮来查看相应的产品&#xff0c;且在鼠标悬停时显示产品详情。页面还将包含一个搜索框&#xff0c;用户可以输入…

深蕾半导体Astra™ SL1620详细介绍,嵌入式物联网处理器

一&#xff0c;SL1620是什么 Astra™ SL系列是深蕾半导体推出的高度集成的嵌入式物联网处理器SoC&#xff08;System on Chip&#xff09;系列产品&#xff0c;专为多模式消费者、企业和工业物联网工作负载而设计。SL1620是Astra™ SL系列中的一款成本和功耗优化的安全嵌入式So…

解决 Failed to connect to 127.0.0.1 port XXXX: Connection refused问题

查看自己的代理&#xff0c;如果有设置&#xff0c;取消即可。注意https还是http&#xff0c;或者都取消算了 git config --global http.proxy git config --global --unset http.proxygit config --global https.proxy git config --global --unset https.proxy注意如果有人在…

进程的管道

进程之间的通信有两种&#xff0c;无名管道通信和有名管道通信&#xff0c; 为什么有通信呢&#xff0c;可以理解为你有一个同事&#xff0c;你两干一件事从不同的方向&#xff0c;哪一件事你干&#xff0c;哪一件事他干&#xff0c;你俩得知道吧&#xff0c;差不多是这个意思…

AMD硬件分析工具简介

Introduction to profiling tools for AMD hardware — ROCm Blogs **注意:** 本文博客内容此前为[ AMD实验室笔记]博客系列的一部分。 让代码功能正确只是基础&#xff0c;在许多行业中&#xff0c;还要求应用程序及其复杂的软件栈尽可能高效地运行以满足操作需求。这尤为具有…

Linux gadget 模拟触控屏 支持多点触控

通过gadget命令行生成hid设备 下面xxx自己根据需要修改&#xff0c;例如VID,PID&#xff0c;产品名称 const char *INSTALL_GADGET_CMDS[] {"modprobe libcomposite","mkdir /sys/kernel/config/usb_gadget/g1","echo xxx > /sys/kernel/config/…

华为 海思22AP10(SS524)H.265 编解码处理器用户指南

1.1 概述 22AP10 是针对多路高清 / 超高清&#xff08; 1080p/4M/5M/4K &#xff09; DVR 产品应用开发的新一代专 业 SoC 芯片。 22AP10 集成了 ARM Cortex-A7 四核处理器和性能强大的 图像分析工具 推理引擎&#xff0c;支持多种智能算法应用。同时&#xff0c; 2…

智能招聘系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;企业管理&#xff0c;招聘信息管理&#xff0c;应聘信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;招聘信息&#xff0c;我的 开发系统&…

启动服务并登录MySQL9数据库

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) Windows平台下安装与配置MyS…

QSqlDatabase在多线程中的使用

Qt中多线程使用数据库_qt数据库管理类支持多数据库,多线程-CSDN博客 1. 代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError>…

Chainlit集成LlamaIndex并使用通义千问实现和数据库交互的网页对话应用(text2sql)

前言 我在之前的几篇文章中写了如何使用Chainlit集成Langchain并使用通义千问实现和数据库交互的网页对话应用&#xff0c;但是发现Langchain的几种和数据库交互的组件都不够让我满意&#xff0c;虽然已经满足了大部分场景的需求&#xff0c;但是问题还是很多&#xff0c;比如…

无人机协同作业中的多网融合技术详解

无人机协同作业中的多网融合技术是一种复杂且高效的技术体系&#xff0c;它旨在通过整合多种通信网络和技术&#xff0c;实现多架无人机之间的无缝协同作业&#xff0c;从而提升任务执行效率、增强系统可靠性和扩展应用场景。以下是对该技术的详细解析&#xff1a; 一、多网融…

【C++】多态练习题(面试常考)

学习之前&#xff0c;建议观看&#xff1a;【C】多态&#xff1a;深度剖析&#xff08;多态、虚函数、抽象类、底层原理&#xff09;_c 多态和虚函数,虚函数的实现原理-CSDN博客https://blog.csdn.net/2301_80555259/article/details/142178677?spm1001.2014.3001.5501 一.概念…

解决 Macos下 Orbstack docker网络问题

两种解决方法&#xff0c;第一种开代理 参考 —— 但是我这一种没成功&#xff0c;第二种方法是换镜像源 { "registry-mirrors": ["http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https://mirrors.tencent.com&q…

《向量数据库指南》——Milvus 和 Fivetran 如何为 AI 构建基础

哈哈,说起 Milvus 和 Fivetran 如何为 AI 构建基础,这可真是个有意思的话题!来,让我这个向量数据库领域的“老司机”给你详细讲解一番,保证让你听得津津有味,还能学到不少干货! Milvus 和 Fivetran:AI 搜索解决方案的黄金搭档 在当今这个数据爆炸的时代,AI 已经成为…

使用MTVerseXR SDK实现VR串流

1、概述​ MTVerseXR SDK 是摩尔线程GPU加速的虚拟现实&#xff08;VR&#xff09;流媒体平台&#xff0c;专门用于从远程服务器流式传输基于标准OpenXR的应用程序。MTVerseXR可以通过Wi-Fi和USB流式将VR内容从Windows服务器流式传输到XR客户端设备, 使相对性能低的VR客户端可…

【10000字pandas数据可视化超全笔记整理】Numpy Pandas | 常用API介绍 | 缺失值处理 matplotlib数据可视化介绍

文章目录 Numpy 部分NumPy的数组类被称作ndarray&#xff0c;通常被称作数组。属性创建方法内置函数运算基本运算矩阵运算 Pandas部分总述Serise 对象创建属性方法运算 DataFrame属性索引操作添加删除插入列 保存读取文件保存读取 数据加载分组聚合语法格式: 基本绘图 数据组合…