PE文件中所有节的属性都被定义在节表中,节表由一些列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序一至。节表总是被存放在紧接在PE文件头的地方,也就是从PE文件头(不是文件本身的头部)开始的偏移为00f8h的地方。

 

节表中IMAGE_SECTION_HEADER结构的总数由PE文件头IMAGE_NT_HEADERS结构中的FileHeader.NumberOfSections字段指定。

 

IMAGE_SECTION_HEADER      STRUCT

Name1 db IMAGE_SIZEOF_SHORT_NAME dup (?)8字节的节区名称

union Misc

       physicalAddress        dd          ?

       VirtualSize                 dd          ?;节区的尺寸,没有对齐前的实际大小

ends

VirtualAddress           dd          ?;节区的RVA地址,被装载到内存后的偏移地址,这是一个RVA地址,这个地址是按照内存页对齐的,它的值总是SectionAlignment的指数倍

SizeOfRawData         dd          ?;在文件中对齐后的尺寸,指出磁盘文件中所占空间大小,这个数值等于VirtualSize字段的值按照FileAlignment的值对齐后的大小。

PointerToRawData    dd          ?;在文件中的偏移,指在磁盘文件中所处的位置。这个数值是从文件开头算起的偏移量。

PointerToRelocations       dd          ?;在OBJ文件中使用

PointerToLinenumbers     dd          ?;行号表的位置

NumberOfRelocations     dw         ?;在OBJ文件中使用

NumberOfLinenumbers   dw         ?;在行号表中行号数量

Characteristics           dd          ?;节的属性

IMAGE_SECTION_HEADER      ENDS

 

PE文件中的节的名称是一个由ANSI字符组成的字符串,但并没有规定以0结束,如果节的名称字符串长度小于8个字节的话,后面以0补齐,但是字符串长度达到8个字节的话,后面就没有0字符了,所以在处理的时候需要注意字符串的结束方式。

 

每个节的名称是唯一的,不能有同名的两个节,但是节的名称不代表任何含义,它仅仅是为了查看方便而设置的一个标记而已。

 

当从PE文件中读取需要的节时,不能以节的名称作为定位标准,正确的方法是按照IMAGE_OPTIONAL_HEADER32结构中的数据目录字段定位,也就是IMAGE_DIRECTORY_ENTRY_RESOURCE项才能正确的指向资源数据。

 

依靠以上的信息,装载器就可以从PE文件中找出某个节(从PointerToRawData偏移开始的SizeOfRawData字节)的数据,并将它映射到内存中去(映射到从模块基地址开始偏移VirtualAddress的地方,并占用VirtualSize的值按照页的尺寸对齐后的空间大小)。

 

RVA就是当PE文件被装载到内存中后,某个数据的位置相对于文件头偏移量。