感谢各位看帖,回帖的朋友。在看雪各位朋友的帮助下,我想找到了我想要的答案,在此分享下^_^(如有谬误,欢迎指正)
求助贴参见:http://bbs.pediy.com/showthread.php?t=132101
首先根据两个事实:
1.一些PE文件节区的VirtualSize比SizeOfRawData大,一些PE文件节区的VirtualSize比SizeOfRawData小。
2.一些PE文件节区的VirtualSize并不是SectionAlignment的整数倍,很多VirtualSize甚至为奇数。
3.我将PE文件的CODE节区的SizeOfRawData增加了一个字节(变为奇数),不影响PE文件执行。
得出推论:
1.VirtualSize不是数据装入内存后按内存对齐粒度对齐后占用空间大小,也不一定要按照SectionAlignment对齐(依据事实2)
2.VirtualSize也不是节区内数据的实际大小(依据事实1)
3.SizeOfRawData也并不一定要按照FileAlignment对齐。
根据QEver朋友推荐kenmark大牛的帖子:PE文件内名存实亡的对齐(地址:http://bbs.pediy.com/showthread.php?t=46849)结合上述推论得出以下猜测:
PE文件中的对齐“名存实亡”。
1.kenmark根据实验得出:SizeOfRawData不一定要按照FileAlignment对齐,但是FileAlignment必须是2的整数次幂。
2.根据上述推论,VirtualSize也不一定要按照SectionAlignment对齐。
据此,得出个人观点:
VirtualSize和SizeOfRawData分别应该按照SectionAlignment和FileAlignment对齐仅仅是PE装在器的推荐做法,当PE文件并没有这样对齐时PE装载器仍然会“智能”的进行装载操作,以便运行程序。
那么,PE装载器在将节区载入内存时是如何操作的呢?以下仅为我根据以上推论又进行了一些实验(实验环境:Windows 7,工具:C32ASM+PEID):
1.我将PE文件的CODE节区表中的SizeOfRawData的字段值逐渐增加,直到增加到0x0FFFFF,PE文件仍然可以正常执行,且内存占用无变化。
2.我将PE文件的CODE节区表中的SizeOfRawData的字段组建减少,当减少到某个字节后就无法执行。
3.我将PE文件的CODE节区表中的VirtualSize进行大小调整发行规律:只要VirtualSize按SectionAlignment对齐后+RVA=下一个节区RVA,就能正常执行否则无法执行。
根据实验和上述一些推论做如下猜测:
PE装载器首先申请一片内存空间,内存大小为节区VirtualSize按SectionAlignment对齐后的大小,然后判断SizeOfRawData是否大于已经申请的内存空间,如果SizeOfRawData大于申请的内存空间,则从PE文件节区的PointToRawData开始读取数据,当申请的内存空间存满即止。如果SizeOfRawData小于申请的内存空间则从PE文件节区的PointToRawData开始读取长度为SizeOfRawData的数据填入申请的内存空间,并将剩余空间用0填充。
以上观点如有谬误欢迎指正。
再次感谢QEver,zapline等朋友的帮助……
- 标 题:PE装载器如何装载节区猜想
- 作 者:刀锋舞者
- 时 间:2011-04-11 16:28:19
- 链 接:http://bbs.pediy.com/showthread.php?t=132195