IMAGE_SECTION_HEADER 的源代码如下:
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 节表名称,如“.text” //IMAGE_SIZEOF_SHORT_NAME=8 union {
DWORD PhysicalAddress; // 在文件中的物理地址
DWORD VirtualSize; // 真实长度,这两个值是一个联合结构,可以使用其中的任何一个,一般是取后一个
} Misc; DWORD VirtualAddress; // 节区的 RVA 地址
DWORD SizeOfRawData; // 在文件中对齐后的尺寸
DWORD PointerToRawData; // 在文件中的偏移量
DWORD PointerToRelocations; // 在OBJ文件中使用,重定位的偏移
DWORD PointerToLinenumbers; // 行号表的偏移(供调试使用地)
WORD NumberOfRelocations; // 在OBJ文件中使用,重定位项数目
WORD NumberOfLinenumbers; // 行号表中行号的数目
DWORD Characteristics; // 节属性如可读,可写,可执行等 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
每个区块表长度占40个字节。
* 表示需要注意的字段,最有用的是 SizeOfRawData 、 PointerToRawData 和Characteristics 字段。
Name *
此字段时区块名。(一句话:名字而已,没什么用)
要求:
1. 占8个字节的utf8字符串,如果区块名超过 8 个字节,则没有最后的终止标志“NULL”。
2. 每个区块的名称都是唯一的,不能有同名的两个区块。
3. 另外,如果名字过长,可以那么使用斜杠(/)加上ASCII字符表示一个10进制地址,这个地址表示真正的区块名在在字符串表中的地址。
含义:但事实上节的名称不代表任何含义,仅仅是为了便查看方便(所以将包含代码的区块命名为“.Data” 或者说将包含数据的区块命名为“.Code” 都是合法的。)。当我们要从PE 文件中读取需要的区块时候,不能以区块的名称作为定位的标准和依据。正确的做法是按照 IMAGE_OPTIONAL_HEADER32 结构中的数据目录字段结合进行定位。
其他说明:多数区块名都习惯性以一个“.”作为开头(例如:.text),这个“.” 不是必须的。并且前边带有一个“$” 的区块名字会从连接器那里得到特殊的待遇,前边带有“$” 的相同名字的区块在载入时候将会被合并,在合并之后的区块中,他们是按照“$” 后边的字符的字母顺序进行合并的。
Misc *
共用体:
PhysicalAddress | 在文件中的地址。 |
Virtual Size | 此节在读取到内存中的总大小,单位是字节。如果此值大于 SizeOfRawData 成员的话,此节将被0填充。此值仅当可执行镜像且object文件必须被设置为0时有效。 |
Virtual Address *
该区块装载到内存中的RVA 地址。这个地址是按照内存页来对齐的,因此它的数值总是 SectionAlignment 的值的整数倍。
在Microsoft 工具中,第一个快的默认 RVA 总为1000h。在OBJ 中,该字段没有意义地,并被设为0。
SizeOfRawData ***
该区块在磁盘中所占的大小(单位是字节),必须是IMAGE_OPTIONAL_HEADER中FileAlignment成员的整数倍。如果此值小于Virtual Size,那么剩下的字节以0填充。如果此节仅包含未初始化的数据,那么成员为0。
PointerToRawData ***
该区块在磁盘中的偏移。这个数值是从文件头开始算起的偏移量哦。
PointerToRelocations
这哥们在EXE文件中没有意义,在OBJ 文件中,表示本区块重定位信息的偏移值。(在OBJ 文件中如果不是零,它会指向一个IMAGE_RELOCATION 结构的数组)
PointerToLinenumbers
行号表在文件中的偏移值,文件的调试信息,于我们没用,鸡肋。
NumberOfRelocations
这哥们在EXE文件中也没有意义,在OBJ 文件中,是本区块在重定位表中的重定位数目来着。
NumberOfLinenumbers
该区块在行号表中的行号数目,鸡肋。
Characteristics ***
该区块的属性。该字段是按位来指出区块的属性(如代码/数据/可读/可写等)的标志。
在 winnt.h 中定义如下:
// // Section characteristics. // // IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. // IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. // IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. // IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. // IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved. #define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. #define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. // IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved. #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. // 0x00002000 // Reserved. // IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000 #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. #define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP #define IMAGE_SCN_MEM_FARDATA 0x00008000 // IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 #define IMAGE_SCN_MEM_16BIT 0x00020000 #define IMAGE_SCN_MEM_LOCKED 0x00040000 #define IMAGE_SCN_MEM_PRELOAD 0x00080000 #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // // Unused 0x00F00000 #define IMAGE_SCN_ALIGN_MASK 0x00F00000 #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. // // TLS Characteristic Flags // #define IMAGE_SCN_SCALE_INDEX 0x00000001 // Tls index is scaled
常用的值的翻译:
数值 |
含义 |
IMAGE_SCN_CNT_CODE |
The section contains executable code. 包含代码,常与 0x10000000一起设置。 |
IMAGE_SCN_CNT_INITIALIZED_DATA |
The section contains initialized data. 该区块包含以初始化的数据。 |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |
The section contains uninitialized data. 该区块包含未初始化的数据。 |
IMAGE_SCN_MEM_DISCARDABLE |
The section can be discarded as needed. |
IMAGE_SCN_MEM_SHARED |
The section can be shared in memory. |
IMAGE_SCN_MEM_EXECUTE |
The section can be executed as code. |
IMAGE_SCN_MEM_READ |
The section can be read. |
IMAGE_SCN_MEM_WRITE |
The section can be written to. |
- 更多资料请参考官方文档:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx
例子: