PE结构学习笔记(五)
Chinese:
区块结构体IMAGE_SECTION_HEADER如下:
typedef struct IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //节表名称,如".text", IMAGE_SIZEOF_SHORT_NAME=4 union { DWORD PhysicalAddress; //物理地址 DWORD VirtualSize; //真实长度 } Misc; DWORD VirtualAddress; //节区的RVA地址 DWORD SizeOfRawData; //在文件中对齐后的尺寸 DWORD PointerToRawData; //在文件中的偏移量 DWORD PointerToRelocations; //在obj文件中使用,重定位的偏移 DWORD PointerToLinenumbers; //行号表的偏移(供调试使用地) WORD NumberOfRelocations; //在ojb文件中使用,重定位项数目 WORD NumberOfLinenumbers; //行号表中行号的属木 DWORD Characteristics; //节属性 如可读、可写、可执行等 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
记录一下每个成员的含义和作用。
1、Name
区块名。这是一个8位的ASCII码名,用来定义区块的名称。多数区块名都习惯以一个"."作为开头。如果区块名超过8个字节,则没有最后的终止标志"NULL"字节。前边带有一个"$"的区块名会从Linker那边得到特殊的待遇,前面带有$的相同名字的区块在载入时候将会被合并,在合并后的区块中,它们是按照$后边的字符的字母顺序进行合并。
每个区块的名称都是唯一的,不能有同名的两个区块。节的名称不代表任何含义,它的存在仅仅是为了正规统一编程的时候方便程序猿查看方便而设置的一个标记而已。
当我们要从PE文件中读取需要的区块时候,不能以区块的名称作为定位的标准和依据,正确的方法是按照IMAGE_OPTIONAL_HEADER32结构中的数据目录字段结合进行定位。
2、Virtual Size:
对表对应的区块的大小,这是区块的数据在没有进行对齐处理前的实际大小。
3、Virtual Address:
该区块装载到内存中的RVA地址。这个地址是按照内存页来对齐的,因此它的数值总是SectionAlignment的值的整数倍。在Microsoft工具中,第一个块的默认RVA总为1000h。在obj中,该字段没有意义地,并被设为0。
4、SizeOfRawData:
该区块在磁盘中所占的大小。在可执行文件中,该字段是已经被FileAlignment潜规则处理过的长度。
5、PointerToRawData:
该区块在磁盘中的偏移。(从文件头开始计算)
6、PointerToRelocations:
该成员在exe文件中没有意义。在obj文件中,表示本区块重定位信息的偏移值。
7、PointerToLinenumbers:
行号表在文件中的偏移值,文件的调试信息(鸡肋)。
8、NumberOfRelocations:
在exe文件中无意义,在obj文件中,是本区块在重定位表中的重定位数目。
9、NumberOfLinenumbers:
该区块在行号表中得行号数目,鸡肋。
10、Characteristics:
该区块的属性。该字段是按位来指出区块的属性(如代码/数据/可读/可写等)的标志。
详细的内容请参考msdn: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx
下面描述几个常用的:
IMAGE_SCN_CNT_CODE 包含代码,常与0x10000000一起设置
IMAGE_SCN_CNT_INITIALIZED_DATA 包含已初始化的数据
IMAGE_SCN_CNT_UNINITIALIZED_DATA 包含未初始化的数据
IMAGE_SCN_MEM_DISCARDABLE 该区块可被丢弃,因为当它一旦被装入后,进程就不再需要它了,典型的如重定位区块。
IMAGE_SCN_MEM_SHARED 为共享区块
IMAGE_SCN_MEM_EXECUTE 可执行。通常当0x00000020被设置的时候,该标志也被设置
IMAGE_SCN_MEM_READ 可读,可执行文件中的区块总是设置该标志。
IMAGE_SCN_MEM_WRITE 可写。