您的位置:首页 > 运维架构

关于PE文件格式中IMAGE_OPTIONAL_HEADER.FileAlignment的一些说明

2012-02-24 15:15 465 查看
关于PE文件格式中IMAGE_OPTIONAL_HEADER.FileAlignment的一些说明

这个字段是在文件对齐时使用的.

例如FileAlignment = 0x1000, 有一个节真正有用的数据大小为0x400, 但是因为FileAlignment是0x1000, 所以连接器生成文件时, 该节的大小就是0x1000了. 这就是文件对齐.

看下面数据:

IMAGE_DOS_HEADER (Size: 0x0040H<64B>)

               LONG e_lfanew;   // 0x00005440

IMAGE_NT_HEADERS32 (Size: 0x00F8H<248B>)

               IMAGE_FILE_HEADER (Size: 0x0014H<20B>)

                              .......

                              WORD NumberOfSections; // 0x0004
                              ........

               IMAGE_OPTIONAL_HEADER32 (Size: 0x00E0H<224B>)

                              .......  

                              DWORD SectionAlignment;     // 0x00001000

                              DWORD FileAlignment;          // 0x00001000
                               .......

IMAGE_SECTION_HEADER (Count: 4) (Size: 0x0028H<40B>)(ROF: 0x00005538)
               IMAGE_SECTION_HEADER[0]

                              BYTE Name[8];     // .text

                              DWORD Misc.PhysicalAddress/Misc.VirtualSize; // 0x000176E1

                              DWORD VirtualAddress;    // 0x00006000

                              DWORD SizeOfRawData;    // 0x00018000

                              DWORD PointerToRawData;   // 0x00006000
                              DWORD PointerToRelocations;  // 0x00000000

                              DWORD PointerToLinenumbers;  // 0x00000000

                              WORD NumberOfRelocations;  // 0x0000

                              WORD NumberOfLinenumbers;  // 0x0000

                              DWORD Characteristics;   // 0x60000020

                               ........

IMAGE_DOS_HEADER + Stub + IMAGE_NT_HEADERS + IMAGE_SECTION_HEADER * 4

= 0x00005538 + 0x0028H * 4

= 0x000055D8 != 0x00006000

IMAGE_SECTION_HEADER * 4的后面就是节了, 但第一个节在文件的中位置是0x00006000

可以看到"IMAGE_DOS_HEADER + Stub + IMAGE_NT_HEADERS + IMAGE_SECTION_HEADER * 4 "这块数据也是要文件对齐的.

所以假设FileAlignment = 0x1000, 通常第一个节在文件中的位置也就是0x1000的(IMAGE_SECTION_HEADER[0].PointerToRawData), 知道为什么吗? 也是文件对齐的缘故.

因为IMAGE_DOS_HEADER + Stub + IMAGE_NT_HEADERS + IMAGE_SECTION_HEADER * n的大小比 0x1000 还小.

 

还引出了一个问题: 就是书上说的"节表结构后面加一个空的节表结构来代表节表的结束", 但是既然有IMAGE_FILE_HEADER.NumberOfSections, 你觉得还需要用一个空的节表结构来代表结束吗? 节表结构后面的0可能不是空节表结构, 而是因为文件对齐而补的0(经过验证, 我是对的, 看下面).

IMAGE_SECTION_HEADER (Count: 4)
(Size: 0x0028H<40B>)(ROF: 0x00004F58)
             IMAGE_SECTION_HEADER[0]

                              BYTE Name[8];    // .text

                              DWORD Misc.PhysicalAddress/Misc.VirtualSize; // 0x000176E1

                              DWORD VirtualAddress;    // 0x00005000

                              DWORD SizeOfRawData;    // 0x00018000

                              DWORD PointerToRawData;   // 0x00005000
                              DWORD PointerToRelocations;  // 0x00000000

有4个IMAGE_SECTION_HEADER  第一个在0x00004F58

而第一个节在0x00005000
0x00004F58 + * 0x0028H * 4 = 0x00004FF8(差8个byte就到0x00005000, 查看文件, 这8个byte是补0的).
如果是多一个空白IMAGE_SECTION_HEADER的话

0x00004F58 + * 0x0028H * 5 = 0x00005020(都超出第一个节的起始位置了0x00005000)

所以说节表结构后面的0不是空节表结构, 而是因为文件对齐而补的0

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  image header dos byte file