首页
社区
课程
招聘
[原创]PE文件内名存实亡的对齐
发表于: 2007-6-23 15:39 10245

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

2007-6-23 15:39
10245

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,英文版的文档。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

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