值
| 描述
|
IMAGE_DIRECTORY_ENTRY_EXPORT
| 指向导出表(一个IMAGE_EXPORT_DIRECTORY结构)。
|
IMAGE_DIRECTORY_ENTRY_IMPORT
| 指向导入表(一个IMAGE_IMPORT_DESCRIPTOR结构数组)。
|
IMAGE_DIRECTORY_ENTRY_RESOURCE
| 指向资源(一个IMAGE_RESOURCE_DIRECTORY结构。
|
IMAGE_DIRECTORY_ENTRY_EXCEPTION
| 指向异常处理表(一个IMAGE_RUNTIME_FUNCTION_ENTRY结构数组)。CPU特定的并且基于表的异常处理。用于除x86之外的其它CPU上。
|
IMAGE_DIRECTORY_ENTRY_SECURITY
| 指向一个WIN_CERTIFICATE结构的列表,它定义在WinTrust.H中。不会被映射到内存中。因此,VirtualAddress域是一个文件偏移,而不是一个RVA。
|
IMAGE_DIRECTORY_ENTRY_BASERELOC
| 指向基址重定位信息。
|
IMAGE_DIRECTORY_ENTRY_DEBUG
| 指向一个IMAGE_DEBUG_DIRECTORY结构数组,其中每个结构描述了映像的一些调试信息。早期的Borland链接器设置这个IMAGE_DATA_DIRECTORY结构的Size域为结构的数目,而不是字节大小。要得到IMAGE_DEBUG_DIRECTORY结构的数目,用IMAGE_DEBUG_DIRECTORY 的大小除以这个Size域。
|
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
| 指向特定架构数据,它是一个IMAGE_ARCHITECTURE_HEADER结构数组。不用于x86或IA-64,但看来已用于DEC/Compaq Alpha。
|
IMAGE_DIRECTORY_ENTRY_GLOBALPTR
| 在某些架构体系上VirtualAddress域是一个RVA,被用来作为全局指针(gp)。不用于x86,而用于IA-64。Size域没有被使用。参见2000年11月的Under The Hood 专栏可得到关于IA-64 gp的更多信息。
|
IMAGE_DIRECTORY_ENTRY_TLS
| 指向线程局部存储初始化节。
|
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
| 指向一个IMAGE_LOAD_CONFIG_DIRECTORY结构。IMAGE_LOAD_CONFIG_DIRECTORY中的信息是特定于Windows NT、Windows 2000和 Windows XP的(例如 GlobalFlag 值)。要把这个结构放到你的可执行文件中,你必须用名字__load_config_used 定义一个全局结构,类型是IMAGE_LOAD_CONFIG_DIRECTORY。对于非x86的其它体系,符号名是_load_config_used (只有一个下划线)。如果你确实要包含一个IMAGE_LOAD_CONFIG_DIRECTORY,那么在 C++ 中要得到正确的名字比较棘手。链接器看到的符号名必须是__load_config_used (两个下划线)。C++ 编译器会在全局符号前加一个下划线。另外,它还用类型信息修饰全局符号名。因此,要使一切正常,在 C++ 中就必须像下面这样使用:
extern "C"
IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {...}
|
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
| 指向一个 IMAGE_BOUND_IMPORT_DESCRIPTOR结构数组,对应于这个映像绑定的每个DLL。数组元素中的时间戳允许加载器快速判断绑定是否是新的。如果不是,加载器忽略绑定信息并且按正常方式解决导入API。
|
IMAGE_DIRECTORY_ENTRY_IAT
| 指向第一个导入地址表(IAT)的开始位置。对应于每个被导入DLL的IAT都连续地排列在内存中。Size域指出了所有IAT的总的大小。在写入导入函数的地址时加载器使用这个地址和Size域指定的大小临时地标记IAT为可读写。
|
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
| 指向延迟加载信息,它是一个CImgDelayDescr结构数组,定义在Visual C++的头文件DELAYIMP.H中。延迟加载的DLL直到对它们中的API进行第一次调用发生时才会被装入。Windows中并没有关于延迟加载DLL的知识,认识到这一点很重要。延迟加载的特征完全是由链接器和运行时库实现的。
|
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
| 在最近更新的系统头文件中这个值已被改名为IMAGE_DIRECTORY_ENTRY_COMHEADER。它指向可执行文件中.NET信息的最高级别信息,包括元数据。这个信息是一个IMAGE_COR20_HEADER结构。
|
大小
| 域
| 描述
|
WORD
| Machine
| 可执行文件的目标CPU。通常的值是:
IMAGE_FILE_MACHINE_I386 0x014c // Intel 386
IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
|
WORD
| NumberOfSections
| 指出节表中有多少个节。节表紧跟在IMAGE_NT_HEADERS之后。
|
DWORD
| TimeDateStamp
| 指出这个文件被创建的时间。这个值是用格林尼治时间(GMT)计算的自从1970年1月1日以来所经过的秒数。这个值比文件系统的日期/时间更准确地指出了文件被创建的时间。使用_ctime 函数(对时区敏感)可以很容易地把这个值转换为人们可读的字符串形式。另一个有用的函数是gmtime。
|
DWORD
| PointerToSymbolTable
| COFF符号表的文件偏移,描述于Microsoft规范的5.4节。COFF符号表在PE文件中很少见,因为出现了新的调试格式。Visual Studio .NET之前,可通过指定链接器选项/DEBUGTYPE:COFF来创建COFF符号表。COFF符号表几乎总是会出现在OBJ文件中。如果没有符号表则设此值为0。
|
DWORD
| NumberOfSymbols
| 如果存在COFF符号表,此域表示其中的符号的数目。COFF符号是一个固定大小的结构,要找到COFF符号表的末尾就必须用到此域。紧跟COFF符号之后是一个用来保存较长符号名的字符串表。
|
WORD
| SizeOfOptionalHeader
| IMAGE_FILE_HEADER 之后的可选数据的大小。在PE文件中,这个数据称为IMAGE_OPTIONAL_HEADER。这个大小在32位和64位的文件中是不同的。对于32位PE文件,这个域通常是224。对于64位PE32+文件,它通常是240。然而,这些值只是所要求的最小值,更大的值也可能会出现。
|
WORD
| Characteristics
| 一组指示文件属性的位标。这些标记的有效值是定义于WINNT.H文件中的IMAGE_FILE_xxx值。一些常用的值在图4中列出。
|
值
| 描述
|
IMAGE_FILE_RELOCS_STRIPPED
| 文件中不包括重定位信息。
|
IMAGE_FILE_EXECUTABLE_IMAGE
| 文件是可执行的。
|
IMAGE_FILE_AGGRESIVE_WS_TRIM
| 让操作系统强制整理工作区。
|
IMAGE_FILE_LARGE_ADDRESS_AWARE
| 应用程序可处理超过2GB的地址。
|
IMAGE_FILE_32BIT_MACHINE
| 需要一个32位的机器。
|
IMAGE_FILE_DEBUG_STRIPPED
| 调试信息位于一个.DBG文件中。
|
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
| 如果映像在可移动媒体中,那么复制到交换文件并从交换文件中运行。
|
IMAGE_FILE_NET_RUN_FROM_SWAP
| 如果映像在网络上,那么复制到交换文件并从交换文件中运行。
|
IMAGE_FILE_DLL
| 是一个DLL文件。
|
IMAGE_FILE_UP_SYSTEM_ONLY
| 只能在单处理器机器中运行。
|
Size
| Structure Member
| Description
|
WORD
| Magic
| 一个签名,确定这是什么类型的头。两个最常用的值是IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b和IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b.
|
BYTE
| MajorLinkerVersion
| 创建可执行文件的链接器的主版本号。对于Microsoft的链接器生成的PE文件,这个版本号的Visual Studio的版本号相一致(例如,版本6表示Visual Studio 6.0)。
|
BYTE
| MinorLinkerVersion
| 创建可执行文件的链接器的次版本号。
|
DWORD
| SizeOfCode
| 所有具有IMAGE_SCN_CNT_CODE属性的节的总的大小。
|
DWORD
| SizeOfInitializedData
| 所有包含已初始数据的节的总的大小。
|
DWORD
| SizeOfUninitializedData
| 所有包含未初始化数据的节的总的大小。这个域总是0,因为链接器可以把未初始化数据附加到常规数据节的末尾。
|
DWORD
| AddressOfEntryPoint
| 文件中将被执行的第一个代码字节的RVA。对于DLL,这个进入点将在进程初始化和关闭时以及线程被创建和销毁时调用。在大多数可执行文件中,这个地址并不直接指向main,WinMain或DllMain函数,而是指向运行时库代码,由运行时库调用前述函数。在DLL中,这个域可以被设为0,这样的话上面所说的通知就不能被接收到。链接器选项/NOENTRY可以设置这个域为0。
|
DWORD
| BaseOfCode
| 加载到内存后代码的第一个字节的RVA。
|
DWORD
| BaseOfData
| 理论上,它表示加载到内存后数据的第一个字节的RVA。然而,这个域的值对于不同版本的Microsoft链接器是不一致的。在64位的可执行文件中这个域不出现。
|
DWORD
| ImageBase
| 文件在内存中的首选加载地址。加载器尽可能地把PE文件加载到这个地址(就是说,如果当前这块内存没有被占用,它是对齐的并且是一个合法的地址,等等)。如果可执行文件被加载到这个地址,加载器就可以跳过进行基址重定位(在这篇文章的第二部分描述)这一步。对于EXE,缺省的ImageBase是0x400000。对于DLL,缺省是0x10000000。在链接时可以通过/BASE 选项来指定ImageBase,或者以后用REBASE工具重新设置。
|
DWORD
| SectionAlignment
| 加载到内存后节的对齐大小。这个值必须大于等于FileAlignment(下一个域)。缺省的对齐值是目标CPU的页大上。对于运行在Windows 9x或Windows Me下的用户模式可执行文件,最小对齐大小是一页(4KB)。这个域可以通过链接器选项/ALIGN来设置。
|
DWORD
| FileAlignment
| 在PE文件中节的对齐大小。对于x86下的可执行文件,这个值通常是0x200或0x1000。不同版本的Microsoft链接器缺省值不同。这个值必须是2的幂,并且如果SectionAlignment小于CPU的页大小,这个域必须和SectionAlignment相匹配。链接器选项/OPT:WIN98可设置x86可执行文件的文件对齐为0x1000,/OPT:NOWIN98设置文件对齐为0x200。
|
WORD
| MajorOperatingSystemVersion
| 所要求的操作系统的主版本号。随着那么多版本Windows的出现,这个域的值就变得很不确切。
|
WORD
| MinorOperatingSystemVersion
| 所要求的操作系统的次版本号。
|
WORD
| MajorImageVersion
| 这个文件的主版本号。不被系统使用并可设为0。可以通过链接器选项/VERSION来设置。
|
WORD
| MinorImageVersion
| 这个文件的次版本号。
|
WORD
| MajorSubsystemVersion
| 可执行文件所要求的操作子系统的主版本号。它曾经被用来表示需要较新的Windows 95或Windows NT用户界面,而不是老版本的Windows NT界面。今天随着各种不同版本Windows的出现,这个域已不被系统使用,并且通常被设为4。可通过链接器选项/SUBSYSTEM设置这个域的值。
|
WORD
| MinorSubsystemVersion
| 可执行文件所要求的操作子系统的次版本号。
|
DWORD
| Win32VersionValue
| 另一个不被使用的域,通常设为0。
|
DWORD
| SizeOfImage
| 映像的大小。它表示了加载文件到内存中时系统必须保留的内存的数量。这个域的值必须是SectionAlignmnet的倍数。
|
DWORD
| SizeOfHeaders
| MS-DOS头,PE头和节表的总的大小。PE文件中所有这些项目出现在任何代码或数据节之前。这个域的值被调整为文件对齐大小的整数倍。
|
DWORD
| CheckSum
| 映像的校验和。IMAGEHLP.DLL中的CheckSumMappedFile函数可以计算出这个值。校验和用于内核模式的驱动和一些系统DLL。对于其它的,这个域可以为0。当使用链接器选项/RELEASE时校验和被放入文件中。
|
WORD
| Subsystem
| 指示可执行文件期望的子系统(用户界面类型)的枚举值。这个域只用于EXE。一些重要的值包括:
IMAGE_SUBSYSTEM_NATIVE// 映像不需要子系统IMAGE_SUBSYSTEM_WINDOWS_GUI// 使用Windows GUIIMAGE_SUBSYSTEM_WINDOWS_CUI// 作为控制台程序运行。// 运行时,操作系统创建一个控制台// 窗口并提供stdin,stdout和stderr// 文件句柄。 |
WORD
| DllCharacteristics
| 标记DLL的特性。对应于IMAGE_DLLCHARACTERISTICS_xxx定义。当前的值是:
IMAGE_DLLCHARACTERISTICS_NO_BIND// 不要绑定这个映像IMAGE_DLLCHARACTERISTICS_WDM_DRIVER// WDM模式的驱动程序IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE// 当终端服务加载一个不是// Terminal- Services-aware 的应用程// 序时,它也加载一个包含兼容代码// 的DLL。 |
DWORD
| SizeOfStackReserve
| 在EXE文件中,为线程保留的堆栈大小。缺省是1MB,但并不是所有的内存一开始都被提交。
|
DWORD
| SizeOfStackCommit
| 在EXE文件中,为堆栈初始提交的内存数量。缺省情况下,这个域是4KB。
|
DWORD
| SizeOfHeapReserve
| 在EXE文件中,为默认进程堆初始保留的内存大小。缺省是1MB。然而在当前版本的Windows中,堆不经过用户干涉就能超出这里指定的大小。
|
DWORD
| SizeOfHeapCommit
| 在EXE文件中,提交到堆的内存大小。缺省情况下,这里的值是4KB。
|
DWORD
| LoaderFlags
| 不使用。
|
DWORD
| NumberOfRvaAndSizes
| 在IMAGE_NT_HEADERS结构的末尾是一个IMAGE_DATA_DIRECTORY结构数组。此域包含了这个数组的元素个数。自从最早的Windows NT发布以来这个域的值一直是16。
|
IMAGE_
| DataDirectory[16]
| 一个IMAGE_DATA_DIRECTORY结构数组。每个结构都包含了可执行文件中一些重要数据的RVA和大小(例如导入表,导出表和资源)。
|
大小
| 域
| 描述
|
BYTE
| Name[8]
| 节的ASCII名称。节名不保证一定是以NULL结尾的。如果你指定了长于8个字符的节名,链接器会把它截短为8个字符。在OBJ文件中存在一个机制允许更长的节名。节名通常以一个句点开始,但这并不是必须的。节名中有一个“$”时链接器会对之进行特殊处理。前面带有“$”的相同名字的节将会被合并。合并的顺序是按照“$”后面字符的字母顺序进行合并的。关于名字中带有“$”的节以及这些节怎样被合并有很多的主题,但这些细节已超出本文所讨论的范围了。
|
DWORD
| Misc.VirtualSize
| 指出实际被使用的节的大小。这个域的值可以大于或小于SizeOfRawData域的值。如果VirtualSize的值大,SizeOfRawData就是可执行文件中已初始化数据的大小,剩下的字节用0填充。在OBJ文件中这个域被设为0。
|
DWORD
| VirtualAddress
| 在可执行文件中,是节被加载到内存中后的RVA。在OBJ文件中应该被设为0。
|
DWORD
| SizeOfRawData
| 在可执行文件或OBJ文件中该节所占用的字节大小。对于可执行文件,这个值必须是PE头中给出的文件对齐值的倍数。如果是0,则说明这个节中的数据是未初始的。
|
DWORD
| PointerToRawData
| 节在磁盘文件中的偏移。对于可执行文件,这个值必须是PE头部给出的文件对齐值的倍数。
|
DWORD
| PointerToRelocations
| 节的重定位数据的文件偏移。只用于OBJ文件,在可执行文件中被设为0。对于OBJ文件,如果这个域的值不为0的话,它就指向一个IMAGE_RELOCATION结构数组。
|
DWORD
| PointerToLinenumbers
| 节的COFF样式行号的文件偏移。如果非0,则指向一个IMAGE_LINENUMBER结构数组。只在COFF行号被生成时使用。
|
WORD
| NumberOfRelocations
| PointerToRelocations 指向的重定位的数目。在可执行文件中应该是0。
|
WORD
| NumberOfLinenumbers
| NumberOfRelocations 域指向的行号的数目。只在COFF行号被生成时使用。
|
DWORD
| Characteristics
| 被或到一起的一些标记,用来表示节的属性。这些标记中很多都可以通过链接器选项/SECTION来设置。常用值在图7中列出。
|
值
| 描述
|
IMAGE_SCN_CNT_CODE
| 节中包含代码。
|
IMAGE_SCN_MEM_EXECUTE
| 节是可执行的。
|
IMAGE_SCN_CNT_INITIALIZED_DATA
| 节中包含已初始化数据。
|
IMAGE_SCN_CNT_UNINITIALIZED_DATA
| 节中包含未初始化数据。
|
IMAGE_SCN_MEM_DISCARDABLE
| 节可被丢弃。用于保存链接器使用的一些信息,包括.debug$节。
|
IMAGE_SCN_MEM_NOT_PAGED
| 节不可被页交换,因此它总是存在于物理内存中。经常用于内核模式的驱动程序。
|
IMAGE_SCN_MEM_SHARED
| 包含节的数据的物理内存页在所有用到这个可执行体的进程之间共享。因此,每个进程看到这个节中的数据值都是完全一样的。这对一个进程的所有实例之间共享全局变量很有用。要使一个节共享,可使用/section:name,S 链接器选项。
|
IMAGE_SCN_MEM_READ
| 节是可读的。几乎总是被设置。
|
IMAGE_SCN_MEM_WRITE
| 节是可写的。
|
IMAGE_SCN_LNK_INFO
| 节中包含链接器使用的信息。只在OBJ文件中存在。
|
IMAGE_SCN_LNK_REMOVE
| 节中的数据不会成为映像的一部分。只出现在OBJ文件中。
|
IMAGE_SCN_LNK_COMDAT
| 节中的内容是公共数据(comdat)。公共数据是指可被定义在多个OBJ文件中的数据。链接器将选择一个包含到可执行文件中。Comdat 对于支持C++模板函数和在函数级别上的链接是至关重要的。Comdat节只出现在OBJ文件中。
|
IMAGE_SCN_ALIGN_XBYTES
| 在最终的可执行文件中这个节中数据的对齐大小。它可有许多取值(_4BYTES,_8BYTES,_16BYTES等)。如果没有被指定,缺省是16字节。这些标记只在OBJ文件中被设置。
|