首页
论坛
课程
招聘
[原创]PE文件内名存实亡的对齐
2007-6-23 15:39 8708

[原创]PE文件内名存实亡的对齐

2007-6-23 15:39
8708
PE文件内名存实亡的对齐

大家知道PE文件中IMAGE_NT_HEADERS的IMAGE_OPTIONAL_HEADER32里有两个对其因子SectionAlignment和FileAlignment分别表示内存中块的对齐和文件中块的对齐。我同时翻阅了Visual Studio, Microsoft Portable Executable and Common Object File Format Specification Revision 8.0 - May 16, 2006英文原版以及各种中文版的PE文件格式解析(其中包括《加密与解密》),发现描述Section时特别指出块的PointerToRawData和SizeOfRawData必须遵循FileAlignment(即必须是对齐因子的整数倍),而VirtualAddress必须遵循SectionAlignment,同时两个对齐因子必须都是2的整数次幂,且FileAlignment必须小于等于SectionAlignment。
对于此点,各色文档参差不齐,例如英文文档中没有强调VirtualAddress的对齐,而《加密与解密》中没有强调PointerToRawData的对齐。众说风云,姑且先放一下,我用LordPE+Win2k(SP4)作了一系列的试验来验证对齐问题。

首先必须研究一下section(有人译成节,本人将其译成块,在下文中不再解释)。
可执行文件中,块有4个主要参数和2个参考参数,分别为:
4个主要参数:
PointerToRawData(在LordPE中为ROffset)表示块在文件中开始的偏移
SizeOfRawData(在LordPE中为RSize)表示块在文件中对齐后的大小
VirtualAddress(在LordPE中为VOffset)表示块在内存中的RVA(相对虚拟地址)
VirtualSize(在LordPE中为VSize)表示块从文件映射到内存时实际需要映射的大小(也就是对齐前实际使用了的大小)
特别的,英文文档指出当VirtualSize > SizeOfRawData时表示块内数据全部是0,通常下VirtualSize <= SizeOfRawData。
由此看来英文文档中的对齐要求不无理由,除VirtualSize和块实际存储信息有关(可能是代码多少,数据多少),其它三项都要求对齐。
2个参考参数:
分别是BYTE name[8];块名字,详细参见英文文档和Characteristics表示块的属性(可执行?保存已初始化数据?等等)
还有一些和调试相关的参数详细参见英文文档。

既然对齐如此必要,那么理应严格遵循,但是试验结果令人大吃一惊。
FileAlignment使用了win2k\system32\notepad.exe作为试验对象。
Notepad.exe的块表:
name        VOffset                VSize                ROffset                RSize                Flags
.text        00001000        0000654A        00000600        00006600        60000020
.data        00008000        00001944        00006C00        00000600        C0000040
.rsrc        0000A000        00005238        00007200        00005400        40000040

FileAlignment : 200h        SectionAlignment : 1000h                运行结果:ok
FileAlignment : 400h        SectionAlignment : 1000h                运行结果:ok
FileAlignment : 600h        SectionAlignment : 1000h                运行结果:错误,原因:600h不是2的整数次幂
FileAlignment : 800h        SectionAlignment : 1000h                运行结果:ok
FileAlignment : 1000h        SectionAlignment : 1000h                运行结果:ok
FileAlignment : 2000h        SectionAlignment : 1000h                运行结果:错误,原因:FileAlignment > SectionAlignment

可见FileAlignment并没有严格遵循对齐原则。
而SectionAlignment是严格遵循的,因为它关系到SizeOfImage,EntryPoint等与RVA和VA相关的所有内容。

最后的结果大出所料但又在情理之中,文件中FileAlignment没有严格遵循对齐原则,因为在映射到内存时地址会重新改写,只要内容上没有问题,映射后与映像文件对齐没有关系。但是SectionAlignment却要严格遵循,因为映射到内存后诸多寻址与其息息相关。
PELoader和我们玩了一个游戏,只要EXE能够执行,不必细究那些次要因素带来的影响。
当然这些推断只是基于本环境(win2k+sp4),其它系统上不敢妄言,由于看不到系统PELoader的代码实现,所以这些只是表象的推测而已,更待高手指点迷津。

附件中带有win2k下的notepad,英文版的文档。

2022 KCTF春季赛【最佳人气奖】火热评选中!快来投票吧~

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (9)
雪    币: 1654
活跃值: 活跃值 (200)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
linxer 活跃值 11 2007-6-24 00:03
2
0
ROffset可以不对齐,这个时候会在load的时按FileAlignment向下对齐
VSize的大小只是效验下是否跨越下一个节了,或者是否超出了SizeOfImage,如果出现越界问题,提示非法32位应用程序,否则的话,它的值没有意义,节的大小不是由它决定的......对非最后一个节,按节间VOffset之差,最后一节用SizeOfImage-VOffset
雪    币: 246
活跃值: 活跃值 (11)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 活跃值 10 2007-6-26 17:38
3
0
学习~
凑字凑字
雪    币: 1962
活跃值: 活跃值 (753)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
wofan[OCN] 活跃值 21 2007-6-26 20:27
4
0
看看,翻翻,学习
雪    币: 256
活跃值: 活跃值 (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
yutu 活跃值 1 2007-6-27 13:03
5
0
好!!!!!
雪    币: 246
活跃值: 活跃值 (11)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 活跃值 10 2007-6-27 14:38
6
0
貌似VirtualSize > SizeOfRawData的时候对应的节的数据也不是0
雪    币: 100
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
galihoo 活跃值 2007-6-27 14:52
7
0
努力学习种~~~
雪    币: 1654
活跃值: 活跃值 (200)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
linxer 活跃值 11 2007-6-27 21:31
8
0
不管VirtualSize和SizeOfRawData的关系怎么样,貌似都是从磁盘上读取SizeOfRawData大小数据填充该节的头部,剩下的空间全填充0
雪    币: 3491
活跃值: 活跃值 (2236)
能力值: ( LV15,RANK:490 )
在线值:
发帖
回帖
粉丝
曾半仙 活跃值 12 2007-7-11 11:09
9
0
这里9x和2K的PE Loader有一个不一致的情况, 对于最后一节的段大小.
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
独孤剑 活跃值 1 2007-7-12 21:28
10
0
FileAlignment的限制不是很严格的.不过程序的稳定性来说还是用0x200
游客
登录 | 注册 方可回帖
返回