Windows运行机理——线程的机制(4)-程序员宅基地

技术标签: 操作系统  runtime  嵌入式  

PE结构分析

 

因为PE结构是一个很复杂的结构,所以下面我们在讨论PE时把它分为PE头标、表节、文件导入/导出、资源分别介绍。如果你只对某部分内容感兴趣,可以直接跳到此节阅读。


P E头标

 

PE 的意思就是 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格式。它的一些特性继承自 Unix Coff (common object file format)文件格式。Portable Executable(可移植的执行体)意味着此文件格式是跨Win32平台的:即使Windows运行在非IntelCPU上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPU上的PE执行体必然得有一些改变。所有Win32执行体(除了VxD16位的DLL)都使用PE文件格式,包括NT的内核模式驱动程序(Kernel Mode Drivers)。

我们在PE结构中最先看见的PE格式中的是PE结构的头标。像所有其他微软可执行文件格式一样,PE文件在一个已知(或容易找到的)位置上,有一系列域来定义该文件其余部分看起来像什么。PE头标包含了至关重要的一些信息,诸如代码和数据区的位置和大小、该文件要用什么操作系统以及初始的堆栈大小。我们在学习PE结构时最好用PEDUMPDUMP一个EXEDLL文件比较好学习点(PEDUMP可以在X:Msvc\COMMON\TOOLS找到,XVC的安装目录)。

 

1. DOS
 

与其他微软的可执行格式相似的是,在PE头标前面还有一个百多个字节的DOS头。这个DOS区域是一小段DOS程序。这一段程序只有几行简单的汇编程序,在Windows 3.1中可以自己定义。把一个很大的DOS程序当成PE结构的头也是可以的,例如说做一个从DOS下启动的游戏,就可以把DOS启动的内容放在前面。到了Windows 9x中的PE结构,在VC 4.0以后,DOS头就不可定义了。

现在,它的作用是如果此程序在DOS平台运行时,它将打印出“该程序不能在DOS模式下运行”之类的信息。这样就能提示程序的用户到Windows平台去运行此程序。下图PE结构图。


71-32-9.gif

PE文件的所有结构都能在WINNT.H文件中找到,其结构如下:

ExpandedBlockStart.gif ContractedBlock.gif typedef  struct  _IMAGE_DOS_HEADER  dot.gif // DOS .EXE header
InBlock.gif

InBlock.gif    WORD   e_magic;             
// Magic number
InBlock.gif

InBlock.gif    WORD   e_cblp;              
// Bytes on last page of file
InBlock.gif

InBlock.gif    WORD   e_cp;                 
// Pages in file
InBlock.gif

InBlock.gif    WORD   e_crlc;              
// Relocations
InBlock.gif

InBlock.gif    WORD   e_cparhdr;          
// Size of header in paragraphs
InBlock.gif

InBlock.gif    WORD   e_minalloc;         
// Minimum extra 
InBlock.gif
InBlock.gif
//paragraphs needed
InBlock.gif

InBlock.gif    WORD   e_maxalloc;       
// Maximum extra 
InBlock.gif
InBlock.gif
//paragraphs needed
InBlock.gif

InBlock.gif    WORD   e_ss;                 
// Initial (relative) SS value
InBlock.gif

InBlock.gif    WORD   e_sp;            
// Initial SP value
InBlock.gif

InBlock.gif    WORD   e_csum;         
// Checksum
InBlock.gif

InBlock.gif    WORD   e_ip;             
// Initial IP value
InBlock.gif

InBlock.gif    WORD   e_cs;             
// Initial (relative) CS value
InBlock.gif

InBlock.gif    WORD   e_lfarlc;           
// File address of relocation table
InBlock.gif

InBlock.gif    WORD   e_ovno;          
// Overlay number
InBlock.gif

InBlock.gif    WORD   e_res[
4];           // Reserved words
InBlock.gif

InBlock.gif    WORD   e_oemid;       
// OEM identifier (for e_oeminfo)
InBlock.gif

InBlock.gif    WORD   e_oeminfo;     
// OEM information; 
InBlock.gif
InBlock.gif
//e_oemid specific
InBlock.gif

InBlock.gif    WORD   e_res2[
10];        // Reserved words
InBlock.gif

InBlock.gif    LONG   e_lfanew;           
// File address of new exe header
InBlock.gif

ExpandedBlockEnd.gif  }
 IMAGE_DOS_HEADER,  * PIMAGE_DOS_HEADER;
None.gif
None.gif

e_lfanew是相对实际PE头标的相对偏移量(或RVA)。要得到内存中一个指向PE头标的指针,只需将该域的值与映像的基相加:


None.gif      // Ignoring typecasts and pointer conversion issues for clarity…
None.gif

None.gif    pNTHeader
=  dosHeader  +  dosHeader -> e_lfanew;
None.gif
None.gif

其他字段的意义是和DOS头有关的字节,这里没有什么大的作用,就不做介绍了。

 

2. IMAGE_NT_HEADERS
 

PE头标是一个IMAGE_NT_HEADERS类型的结构,该类型在WINNT.H中定义。

在内存中,Windows中把IMAGE_NT_HEADERS结构作为它内存中的模块数据库。在Windows中,每个被装入的EXEDLL都用一个IMAGE_NT_HEADERS结构来说明。其结构如下:


ExpandedBlockStart.gif ContractedBlock.gif typedef  struct  _IMAGE_NT_HEADERS  dot.gif {
InBlock.gif
InBlock.gif    DWORD Signature;
InBlock.gif
InBlock.gif    IMAGE_FILE_HEADER FileHeader;
InBlock.gif
InBlock.gif    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
InBlock.gif
ExpandedBlockEnd.gif}
 IMAGE_NT_HEADERS32,  * PIMAGE_NT_HEADERS32;
None.gif
None.gif

Signature表示此文件所表示的类型,其意义定义如下:


None.gif #define  IMAGE_DOS_SIGNATURE     0x4D5A         //  MZ
None.gif
None.gif
#define  IMAGE_OS2_SIGNATURE     0x4E45         //  NE
None.gif
None.gif
#define  IMAGE_OS2_SIGNATURE_LE  0x4C45         //  LE
None.gif
None.gif
#define  IMAGE_NT_SIGNATURE        0x50450000   //  PE00
None.gif
None.gif

如果是PE格式,则SignaturePE\0\0PE后跟两个0)。

 

3. IMAGE_FILE_HEADER
 

PE头标中紧随PEWORD记号的是一个IMAGE_FILE_HEADER类型的结构,如下所示:


ExpandedBlockStart.gif ContractedBlock.gif typedef  struct  _IMAGE_FILE_HEADER  dot.gif {
InBlock.gif
InBlock.gif    WORD    Machine;
InBlock.gif
InBlock.gif    WORD    NumberOfSections;
InBlock.gif
InBlock.gif    DWORD   TimeDateStamp;
InBlock.gif
InBlock.gif    DWORD   PointerToSymbolTable;
InBlock.gif
InBlock.gif    DWORD   NumberOfSymbols;
InBlock.gif
InBlock.gif    WORD    SizeOfOptionalHeader;
InBlock.gif
InBlock.gif    WORD    Characteristics;
InBlock.gif
ExpandedBlockEnd.gif}
 IMAGE_FILE_HEADER,  * PIMAGE_FILE_HEADER;
None.gif
None.gif

这个结构的域只包含了关于文件的最基本的信息。

Machine表示该文件运行所要求的CPU,有如下的CPU ID定义:


None.gif #define  IMAGE_FILE_MACHINE_UNKNOWN            0
None.gif
None.gif
#define  IMAGE_FILE_MACHINE_I386                 0x014c  
None.gif
None.gif
//  Intel 386.
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_R3000              0x0162  
None.gif
None.gif
//  MIPS little-endian, 0x160 big-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_R4000            0x0166  
None.gif
None.gif
//  MIPS little-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_R10000        0x0168  
None.gif
None.gif
//  MIPS little-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_WCEMIPSV2    0x0169  
None.gif
None.gif
//  MIPS little-endian WCE v2
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_ALPHA          0x0184  
None.gif
None.gif
//  Alpha_AXP
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_POWERPC       0x01F0  
None.gif
None.gif
//  IBM PowerPC Little-Endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_SH3             0x01a2  
None.gif
None.gif
//  SH3 little-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_SH3E           0x01a4  
None.gif
None.gif
//  SH3E little-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_SH4             0x01a6  
None.gif
None.gif
//  SH4 little-endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_ARM            0x01c0  
None.gif
None.gif
//  ARM Little-Endian
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_THUMB          0x01c2
None.gif
None.gif
#define  IMAGE_FILE_MACHINE_IA64            0x0200  
None.gif
None.gif
//  Intel 64
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_MIPS16         0x0266  
None.gif
None.gif
//  MIPS
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_MIPSFPU       0x0366  
None.gif
None.gif
//  MIPS
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_MIPSFPU16     0x0466  
None.gif
None.gif
//  MIPS
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_ALPHA64       0x0284  
None.gif
None.gif
//  ALPHA64
None.gif

None.gif
#define  IMAGE_FILE_MACHINE_AXP64         
None.gif
None.gif
// IMAGE_FILE_MACHINE_ALPHA64
None.gif

None.gif

NumberOfSection表示在EXEOBJ中的节数。这个很重要,因为它直接表示节表数组的大小。

TimeDateStamp表示连接器生成该文件的时间。该值是指从<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />19691231下午4点整开始至文件生成时之间的秒数。

PointerToSymbolTable表示文件的COFF符号表的偏移量。该域只用在OBJ文件和带有COFF调试信息的PE文件中,此信息只在调试文件中有用。

NumberOfSymbols表示在COFF符号表中的符号数目,参见前一个域,此信息只在调试文件中有用。

SizeOfOptionalHeader表示紧跟该结构之后的一个可选头标的大小。在可执行文件中,它是紧随该结构的image_file_header结构的大小。这个值必须有效。

Characteristics表示文件的信息化标记。一些重要的域描述如下:

None.gif //  Relocation info stripped from file.
None.gif

None.gif
#define  IMAGE_FILE_RELOCS_STRIPPED             0x0001
None.gif
None.gif
//  File is executable  (i.e. no unresolved external references).
None.gif

None.gif
#define  IMAGE_FILE_EXECUTABLE_IMAGE           0x0002
None.gif
None.gif
//  Line nunbers stripped from file.
None.gif

None.gif
#define  IMAGE_FILE_LINE_NUMS_STRIPPED         0x0004
None.gif
None.gif
//  Local symbols stripped from file.
None.gif

None.gif
#define  IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008
None.gif
None.gif
//  Agressively trim working set
None.gif

None.gif
#define  IMAGE_FILE_AGGRESIVE_WS_TRIM          0x0010
None.gif
None.gif
//  App can handle >2gb addresses
None.gif

None.gif
#define  IMAGE_FILE_LARGE_ADDRESS_AWARE           0x0020
None.gif
None.gif
//  Bytes of machine word are reversed.
None.gif

None.gif
#define  IMAGE_FILE_BYTES_REVERSED_LO          0x0080
None.gif
None.gif
//  32 bit word machine.
None.gif

None.gif
#define  IMAGE_FILE_32BIT_MACHINE                0x0100
None.gif
None.gif
//  Debugging info stripped from file in .DBG file
None.gif

None.gif
#define  IMAGE_FILE_DEBUG_STRIPPED              0x0200
None.gif
None.gif
//  If Image is on removable media, copy and run from the swap file.
None.gif

None.gif
#define  IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400
None.gif
None.gif
//  If Image is on Net, copy and run from the swap file.
None.gif

None.gif
#define  IMAGE_FILE_NET_RUN_FROM_SWAP          0x0800
None.gif
None.gif
//  System File.
None.gif

None.gif
#define  IMAGE_FILE_SYSTEM                        0x1000
None.gif
None.gif
//  File is a DLL.
None.gif

None.gif
#define  IMAGE_FILE_DLL                            0x2000
None.gif
None.gif
//  File should only be run on a UP machine
None.gif

None.gif
#define  IMAGE_FILE_UP_SYSTEM_ONLY              0x4000
None.gif
None.gif
//  Bytes of machine word are reversed.
None.gif

None.gif
#define  IMAGE_FILE_BYTES_REVERSED_HI          0x8000
None.gif
None.gif

我们常见的意义如下。

Ø         0x0001:该文件中没有重定位。

Ø         0x0002:文件是一个可执行的映像(即不是一个OBJLIB)。

Ø         0x2000:文件是一个动态连接库,不是一个程序。


4. IMAGE_OPTIONAL_HEADER
 

PE头标的第三部分是一个IMAGE_OPTIONAL_HEADER类型结构。对于PE文件,这部分是必要的。除了标准的IMAGE_FILE_HEADER外,COFF格式还允许单独定义一个附加信息结构。

IMAGE_OPTIONAL_HEADER分为两种,一种是32位的,一种是64位的,我们可以在WINNT.H中找到对应的结构,其名分别为:

IMAGE_OPTIONAL_HEADER32IMAGE_OPTIONAL_HEADER64我们在这里只对32位进行介绍,其结构如下:


ExpandedBlockStart.gif ContractedBlock.gif typedef  struct  _IMAGE_OPTIONAL_HEADER  dot.gif {
InBlock.gif
InBlock.gif    
//
InBlock.gif
InBlock.gif    
// Standard fields.
InBlock.gif
InBlock.gif    
//
InBlock.gif

InBlock.gif 
InBlock.gif
InBlock.gif    WORD     Magic;
InBlock.gif
InBlock.gif    BYTE      MajorLinkerVersion;
InBlock.gif
InBlock.gif    BYTE      MinorLinkerVersion;
InBlock.gif
InBlock.gif    DWORD     SizeOfCode;
InBlock.gif
InBlock.gif    DWORD     SizeOfInitializedData;
InBlock.gif
InBlock.gif    DWORD     SizeOfUninitializedData;
InBlock.gif
InBlock.gif    DWORD     AddressOfEntryPoint;
InBlock.gif
InBlock.gif    DWORD     BaseOfCode;
InBlock.gif
InBlock.gif    DWORD     BaseOfData;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif    
//
InBlock.gif
InBlock.gif    
// NT additional fields.
InBlock.gif
InBlock.gif    
//
InBlock.gif

InBlock.gif 
InBlock.gif
InBlock.gif    DWORD     ImageBase;
InBlock.gif
InBlock.gif    DWORD     SectionAlignment;
InBlock.gif
InBlock.gif    DWORD     FileAlignment;
InBlock.gif
InBlock.gif    WORD      MajorOperatingSystemVersion;
InBlock.gif
InBlock.gif    WORD      MinorOperatingSystemVersion;
InBlock.gif
InBlock.gif    WORD      MajorImageVersion;
InBlock.gif
InBlock.gif    WORD      MinorImageVersion;
InBlock.gif
InBlock.gif    WORD      MajorSubsystemVersion;
InBlock.gif
InBlock.gif    WORD      MinorSubsystemVersion;
InBlock.gif
InBlock.gif    DWORD     Win32VersionValue;
InBlock.gif
InBlock.gif    DWORD     SizeOfImage;
InBlock.gif
InBlock.gif    DWORD     SizeOfHeaders;
InBlock.gif
InBlock.gif    DWORD     CheckSum;
InBlock.gif
InBlock.gif    WORD      Subsystem;
InBlock.gif
InBlock.gif    WORD      DllCharacteristics;
InBlock.gif
InBlock.gif    DWORD     SizeOfStackReserve;
InBlock.gif
InBlock.gif    DWORD     SizeOfStackCommit;
InBlock.gif
InBlock.gif    DWORD     SizeOfHeapReserve;
InBlock.gif
InBlock.gif    DWORD     SizeOfHeapCommit;
InBlock.gif
InBlock.gif    DWORD     LoaderFlags;
InBlock.gif
InBlock.gif    DWORD     NumberOfRvaAndSizes;
InBlock.gif
InBlock.gif    IMAGE_DATA_DIRECTORY 
InBlock.gif
InBlock.gifDataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
InBlock.gif
ExpandedBlockEnd.gif}
 IMAGE_OPTIONAL_HEADER32,  * PIMAGE_OPTIONAL_HEADER32;
None.gif

Magic表示标志映像文件状态的一个WORD记号。值定义如下:

None.gif #define  IMAGE_NT_OPTIONAL_HDR32_MAGIC        0x10b
None.gif
None.gif
#define  IMAGE_NT_OPTIONAL_HDR64_MAGIC        0x20b
None.gif
None.gif
#define  IMAGE_ROM_OPTIONAL_HDR_MAGIC          0x107
None.gif
None.gif

Ø         0x0107:一个ROM映像。

Ø         0x010B:一个普通的可执行映像(大多数文件含此值)。

MajorLinkerVersionMinorLinkerVersion表示生成该文件的连接器版本号。该数字以十进制形式显示,而不是十六进制,一个典型的连接器版本号是2.23

SizeOfCode表示所有代码段组合聚集在一起的尺寸大小,内存中整个PE映像体的尺寸。它是所有头和节经过节对齐处理后的大小。

SizeOfInitializedData表示由初始化的数据(不包括代码段)组成的所有节的总尺寸。

SizeOfUninitializedData表示初始化的数据的大小。未初始化的数据通常被归入称为.bss的一节中。

AddressOfEntryPoint表示映像开始执行位置的地址。PE装载器准备运行的PE文件的第一个指令的RVA。若您要改变整个执行的流程,可以将该值指定到新的RVA,这样,新RVA处的指令首先被执行。

BaseOfCode表示文件代码节开始处的RVA。典型情况下,代码节在PE头标之后,并在数据节之前进入内存。在微软生成的EXE文件中,该RVA通常是0x1000

BaseOfData表示文件的数据节开始处的RVA。典型情况下,数据节最后进入内存,排在PE头标和代码节后面。

ImageBase表示当连接器创建一个可执行文件时,它假设该文件将被内存映射到内存中的一个指定位置上。也就是PE文件的优先装载程序的地址。因为在Windows操作系统中,总是把可执行程序安装到虚拟空间中去,每个虚拟空间在逻辑上都是相对独立的,不相干的。此值就是表示程序装在虚拟空间的什么地方开始。

SectionAlignment表示内存中节对齐的粒度。例如,如果该值是4096 (1000h),那么每节的起始地址必须是4096的倍数。若第一节从401000h开始且大小是10个字节,则下一节必定从402000h开始,即使401000h402000h之间还有很多空间没被使用。

FileAlignment表示文件中节对齐的粒度。例如,如果该值是(200h),,那么每节的起始地址必须是512的倍数。若第一节从文件偏移量200h开始且大小是10个字节,则下一节必定位于偏移量400h: 即使偏移量5121024之间还有很多空间没被使用/定义。

MajorOperatingSystemVersionMinorOperatingSystemVersion表示使用该可执行文件所要求的操作系统最小版本。该域含义有点模棱两可,因为subsystem域(后面的一些域)页体现类似的目的。在大多数Win32文件中,该域为版本1.0

MajorImageVersionMinorImageVersion表示一个用户自定义域。该域允许你具有一个EXE或一个DLL的不同版本。可用连接器的/VERSION开关来置该域的值,如LINK/VERSION2.0 myobj.obj

MajorSuvsystemVersionMinorSubsystemVersion表示运行该可执行文件所要求的最小子系统版本。该域的一个典型值是4.0(意为Windows 4.0,即Windows 95)。

Reserved1一般总为0

SizeOfImage一般是装载器不得不关心的映像部分的总尺寸。它是从映像基地址开始直到最后一节的尾端这个范围的长度。最后一节的尾端是被调整为最接近节对齐值的倍数的。

SizeOfHeaders表示PE头标和节(对象)表的尺寸。这些节的生数据直接跟在所有头标部分之后。

SizeOfHeaders =所有头+节表的大小

也就等于文件尺寸减去文件中所有节的尺寸。

CheckSum总是值0

Subsystem表示该可执行文件为它用户接口而使用的子系统类型。WINNT.H定义了如下值:

None.gif //  Unknown subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_UNKNOWN                0 
None.gif
None.gif
//  Image doesn't require a subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_NATIVE                      1 
None.gif
None.gif
//  Image runs in the Windows GUI subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_WINDOWS_GUI            2 
None.gif
None.gif
//  Image runs in the Windows character subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_WINDOWS_CUI            3 
None.gif
None.gif
//  image runs in the OS/2 character subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_OS2_CUI                  5 
None.gif
None.gif
//  image runs in the Posix character subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_POSIX_CUI                   7 
None.gif
None.gif
//  image is a native Win9x driver.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_NATIVE_WINDOWS        8 
None.gif
None.gif
//  Image runs in the Windows CE subsystem.
None.gif

None.gif
#define  IMAGE_SUBSYSTEM_WINDOWS_CE_GUI       9
None.gif
None.gif

表示的意义如下。

Ø         native=1:不需要子系统(例如,一个设备驱动器)

Ø         WINDOWS_GUI=2:在Windows GUI子系统中运行

Ø         WINDOWS_GUI=3:在Windows字符子系统中运行(一个控制台应用程序)

Ø         OS2_GUI=5:在OS/2字符子系统中运行(只对OS/2 1.x的应用程序)

Ø         POSIX_CUI=7:在Posix字符子系统中运行

DllCharacteristics (在NT 3.5中标为obsolete)指示什么情况下一个DLL的初始化函数,例如DllMain()要被调用的标志集合。该值看起来总被置为0,然而操作系统仍为4个事件调用了DLL初始化函数。

被定义的值如下。

Ø         1:当DLL第一次被装入一个进程的地址空间时调用;

Ø         2:当一个线程中止时调用;

Ø         4:当一个线程启动时调用;

Ø         8:当DLL退出时调用。

SizeOfStakeReserve表示为初始线程栈保留的虚拟内存量。然而,这些内存不是都要交付的(见后一个域)。该域默认为0x1000001MB)。如果你对CreateThread()指定一个0作为栈的大小,结果线程仍是得到一个域默认值相同的栈。

SizeOfStackCommit表示为初始线程栈首先交付的内存量。在微软连接器中,该域默认值是0x1000字节(1页),而TLINK默认为0x2000字节(2页)。

SizeOfHeapReserve表示为初始进程堆保留的虚拟内存量。该堆句柄可通过调用GetProcessHeap()来获得。这些内存也不是都要交付的(见下一个域)。

SizeOfHeapCommit表示在进程堆中初始交付的内存量。连接器在该域的默认值是0x1000字节。

Loaderflags(在NT 3.5中标记为obsolete)它们一般是与调试支持有关的域。

NumberOfRvaAndSizes表示在DataDiretory数组中项的数目。目前的工具总把该域的值置为16

DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]是一个IMAGE_DATA_DIRECTORY结构数组。数组中前面的元素包含了该可执行文件重要部分的起始RVA和尺寸。数组尾端的元素目前还未用到。数组的第一个元素总是引出函数表(如果有的话)的地址和尺寸。第二个数组项是引入函数表的地址和尺寸,如此等等。对于一个完整的数组项的定义列表,在WINNT.H中的IMAGE_DIRECTORY_ENTRY_xxx #defins中有如下的几项:


None.gif //  Export Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_EXPORT               0
None.gif
None.gif
//  Import Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_IMPORT               1
None.gif
None.gif
//  Resource Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_RESOURCE             2
None.gif
None.gif
//  Exception Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_EXCEPTION           3
None.gif
None.gif
//  Security Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_SECURITY            4
None.gif
None.gif
//  Base Relocation Table
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_BASERELOC           5
None.gif
None.gif
//  Debug Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_DEBUG                 6 
None.gif
None.gif
//  Architecture Specific Data
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_ARCHITECTURE       7 
None.gif
None.gif
//  RVA of GP
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_GLOBALPTR           8 
None.gif
None.gif
//  TLS Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_TLS                   9 
None.gif
None.gif
//  Load Configuration Directory
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG        10 
None.gif
None.gif
//  Bound Import Directory in headers
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT     11 
None.gif
None.gif
//  Import Address Table
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_IAT                   12 
None.gif
None.gif
//  Delay Load Import Descriptors
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT       13 
None.gif
None.gif
//  COM Runtime descriptor
None.gif

None.gif
#define  IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR    14
None.gif
None.gif

该数组的目的是允许装载器可迅速地找到一个映像的特定节(例如引入函数表),而不必遍历映像的每一个节并逐一比较它们的名字。数组的大多数项描述了一个完整的节的数据。然而,IMAGE_DIRECTORY_ENTRY_ DEBUG元素只含了.rdata节中一小部分字节。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34272308/article/details/85355960

智能推荐

python opencv resize函数_python opencv 等比例调整(缩放)图片分辨率大小代码 cv2.resize()...-程序员宅基地

文章浏览阅读1.3k次。# -*- coding: utf-8 -*-"""@File : 200113_等比例调整图像分辨率大小.py@Time : 2020/1/13 13:38@Author : Dontla@Email : [email protected]@Software: PyCharm"""import cv2def img_resize(image):height, width = image...._opencv小图等比例缩放

【OFDM、OOK、PPM、QAM的BER仿真】绘制不同调制方案的误码率曲线研究(Matlab代码实现)-程序员宅基地

文章浏览阅读42次。对于这些调制技术的误码率(BER)研究是非常重要的,因为它们可以帮助我们了解在不同信道条件下系统的性能表现。通过以上步骤,您可以进行OFDM、OOK、PPM和QAM的误码率仿真研究,并绘制它们的误码率曲线,以便更好地了解它们在不同信道条件下的性能特点。针对这些调制技术的BER研究是非常重要的,可以帮助我们更好地了解这些技术在不同信道条件下的性能表现,从而指导系统设计和优化。6. 分析结果:根据误码率曲线的比较,分析每种调制方案在不同信噪比条件下的性能,包括其容忍的信道条件和适用的应用场景。_ber仿真

【已解决】Vue的Element框架,日期组件(el-date-picker)的@change事件,不会触发。_el-date-picker @change不触发-程序员宅基地

文章浏览阅读2.5w次,点赞3次,收藏3次。1、场景照抄官方的实例,绑定了 myData.Age 这个值。实际选择某个日期后,从 vuetool(开发工具)看,值已经更新了,但视图未更新。2、尝试绑定另一个值: myData,可以正常的触发 @change 方法。可能是:值绑定到子对象时,组件没有侦测到。3、解决使用 @blur 代替 @change 方法。再判断下 “值有没有更新” 即可。如有更好的方法,欢迎评论!..._el-date-picker @change不触发

PCL学习:滤波—Projectlnliers投影滤波_projectinliers-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏8次。Projectlnliersclass pcl: : Projectlnliers< PointT >类 Projectlnliers 使用一个模型和一组的内点的索引,将内点投影到模型形成新的一个独立点云。关键成员函数 void setModelType(int model) 通过用户给定的参数设置使用的模型类型 ,参数 Model 为模型类型(见 mo..._projectinliers

未处理System.BadImageFormatException”类型的未经处理的异常在 xxxxxxx.exe 中发生_“system.badimageformatexception”类型的未经处理的异常在 未知模块。 -程序员宅基地

文章浏览阅读2.4k次。“System.BadImageFormatException”类型的未经处理的异常在 xxxx.exe 中发生其他信息: 未能加载文件或程序集“xxxxxxx, Version=xxxxxx,xxxxxxx”或它的某一个依赖项。试图加载格式不正确的程序。此原因是由于 ” 目标程序的目标平台与 依赖项的目标编译平台不一致导致,把所有的项目都修改到同一目标平台下(X86、X64或AnyCPU)进行编译,一般即可解决问题“。若果以上方式不能解决,可采用如下方式:右键选择配置管理器,在这里修改平台。_“system.badimageformatexception”类型的未经处理的异常在 未知模块。 中发生

PC移植安卓---2018/04/26_电脑软件移植安卓-程序员宅基地

文章浏览阅读2.4k次。记录一下碰到的问题:1.Assetbundle加载问题: 原PC打包后的AssetBundle导入安卓工程后,加载会出问题。同时工程打包APK时,StreamingAssets中不能有中文。解决方案: (1).加入PinYinConvert类,用于将中文转换为拼音(多音字可能会出错,例如空调转换为KongDiao||阿拉伯数字不支持,如Ⅰ、Ⅱ、Ⅲ、Ⅳ(IIII)、Ⅴ、Ⅵ、Ⅶ、Ⅷ、Ⅸ、Ⅹ..._电脑软件移植安卓

随便推点

聊聊线程之run方法_start 是同步还是异步-程序员宅基地

文章浏览阅读2.4k次。话不多说参考书籍 汪文君补充知识:start是异步,run是同步,start的执行会经过JNI方法然后被任务执行调度器告知给系统内核分配时间片进行创建线程并执行,而直接调用run不经过本地方法就是普通对象执行实例方法。什么是线程?1.现在几乎百分之百的操作系统都支持多任务的执行,对计算机来说每一个人物就是一个进程(Process),在每一个进程内部至少要有一个线程实在运行中,有时线..._start 是同步还是异步

制作非缘勿扰页面特效----JQuery_单击标题“非缘勿扰”,<dd>元素中有id属性的<span>的文本(主演、导演、标签、剧情-程序员宅基地

文章浏览阅读5.3k次,点赞9次,收藏34次。我主要用了层次选择器和属性选择器可以随意选择,方便简单为主大体CSS格式 大家自行构造网页主体<body> <div class='main' > <div class='left'> <img src="images/pic.gif" /> <br/><br/> <img src="images/col.gif" alt="收藏本片"/&_单击标题“非缘勿扰”,元素中有id属性的的文本(主演、导演、标签、剧情

有了这6款浏览器插件,浏览器居然“活了”?!媳妇儿直呼“大开眼界”_浏览器插件助手-程序员宅基地

文章浏览阅读901次,点赞20次,收藏23次。浏览器是每台电脑的必装软件,去浏览器搜索资源和信息已经成为我们的日常,我媳妇儿原本也以为浏览器就是上网冲浪而已,哪有那么强大,但经过我的演示之后她惊呆了,直接给我竖起大拇指道:“原来浏览器还能这么用?大开眼界!今天来给大家介绍几款实用的浏览器插件,学会之后让你的浏览器“活过来”!_浏览器插件助手

NumPy科学数学库_数学中常用的环境有numpy-程序员宅基地

文章浏览阅读101次。NumPy是Python中最常用的科学数学计算库之一,它提供了高效的多维数组对象以及对这些数组进行操作的函数NumPy的核心是ndarray(N-dimensional array)对象,它是一个用于存储同类型数据的多维数组Numpy通常与SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用,用于替代MatLabSciPy是一个开源的Python算法库和数学工具包;Matplotlib是Python语言及其Numpy的可视化操作界面'''_数学中常用的环境有numpy

dind(docker in docker)学习-程序员宅基地

文章浏览阅读1.1w次。docker in docker说白了,就是在docker容器内启动一个docker daemon,对外提供服务。优点在于:镜像和容器都在一个隔离的环境,保持操作者的干净环境。想到了再补充 :)一:低版本启动及访问启动1.12.6-dinddocker run --privileged -d --name mydocker docker:1.12.6-dind在其他容器访问d..._dind

推荐文章

热门文章

相关标签