typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //块名。多数块名以一个“.”开始(例如.text),这个“.”不是必需的
union {
DWORD PhysicalAddress; //常用第二个字段
DWORD VirtualSize; //加载到内存实际区块的大小(对齐前),为什么会变呢?可能是有时未初始化的全局变量不放bss段而是通过扩展这里
} Misc;
DWORD VirtualAddress; //该块装载到内存中的RVA(内存对齐后,数值总是SectionAlignment的整数倍)
DWORD SizeOfRawData; //该块在文件中所占的空间(文件对齐后),VirtualSize的值可能会比SizeOfRawData大 例如bss节(SizeOfRawData为0),data节(关键看未初始化的变量放哪)
DWORD PointerToRawData; //该块在文件中的偏移(FOA)
/*调试相关,忽略*/
DWORD PointerToRelocations; //在“.obj”文件中使用,指向重定位表的指针
DWORD PointerToLinenumbers;
WORD NumberOfRelocations; //重定位表的个数(在OBJ文件中使用)。
WORD NumberOfLinenumbers;
DWORD Characteristics; //块的属性 该字段是一组指出块属性(例如代码/数据、可读/可写等)的标志
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
成员解析
DWORD VirtualSize; //加载到内存实际区块的大小(对齐前),为什么会变呢?可能是有时未初始化的全局变量不放bss段而是通过扩展这里【PE内存状态下该区块(节)的大小,这个大小是不算内存对齐的虚拟内存实际大小】
DWORD VirtualAddress; //该块装载到内存中的RVA(内存对齐后,数值总是SectionAlignment的整数倍)【PE内存状态下该区块(节)在内存中的偏移,要与imagebass一同确定实际的虚拟内存地址】
DWORD SizeOfRawData; //该块在文件中所占的空间(文件对齐后),VirtualSize的值可能会比SizeOfRawData大 例如bss节(SizeOfRawData为0),data节(关键看未初始化的变量放哪)【PE文件文件状态下该区块(节)的大小按对文件对齐后的算】
DWORD PointerToRawData; //该块在文件中的偏移(FOA)【PE文件状态下该区块(节)的偏移】
PE二种状态
PE文件状态:区块(节)的实际占用大小(文件状态 ) +文件对齐 =》SizeOfRawData
PE内存状态:区块(节)的实际占用大小(内存状态) +内存对齐 =》VirtualSize +内存对齐 【VirtualSize:就是内存状态下该区块实际占用的大小】
那么区块实际占用的大小在内存状态和文件状态下是一样的吗;其实不一定一样!一般情况是一样的但是该区段如果存在未初始化的变量就会导致不一样!
可以暂且可以理解认为:
VirtualSize: 即区块(节)的实际占用大小(内存状态) =>区块(节)的实际占用大小(文件状态 ) + 未初始化的全局变量
而 SizeOfRawData => 区块(节)的实际占用大小(文件状态 ) + 文件对齐
所以VirtualSize 可能比SizeOfRawData 大也可能比其小
对节的尺寸的处理主要分为两个方面:
第一个方面,正如刚刚我们所讲的,由于磁盘映像和内存映像中节对齐存储单位的不同而导致了长度扩展不同(填充的0数量不同嘛~);
第二个方面,是对于包含未初始化数据的节的处理问题。既然是未初始化,那么没有必要为其在磁盘中浪费空间资源,但在内存中不同,因为程序一运行,之前未初始化的数据便有可能要被赋值初始化,那么就必须为他们留下空间。