最近我发现,PE中的.data部分的虚拟大小可能大于原始大小(在文件中)。这真是令人惊讶。有人说这是某个地方未初始化数据的影响。
但在分析了一些PE后,我无法真正找到这些额外的数据。这是一些程序的PEDump结果的链接:
如您所见,.data部分的虚拟大小大于原始大小。为什么在这个特定的例子中它是这样的?
答案 0 :(得分:1)
任何初始化数据的值都存储在该部分中,如果二进制文件想要在内存中为任何未初始化数据保留空间,则虚拟大小将大于原始数据大小。
您不会在文件中找到此数据,因为它不需要在那里。引用数据的地址(在代码部分中)被烘焙到二进制文件中,以便它们在加载到内存时指向正确的位置。
如果加载器没有预先保留这个空间,那么在使用它们之前必须在堆上分配全局等。
来自PE spec:
[SizeOfRawData]是节的大小(对象文件)或者 磁盘上初始化数据的大小(对于图像文件)。可执行文件 图像,这必须是可选的FileAlignment的倍数 头。如果这小于VirtualSize,则为该部分的其余部分 是零填充。因为SizeOfRawData字段是圆整的但是 VirtualSize字段不是,SizeOfRawData可能是 也大于VirtualSize。当一个部分只包含 未初始化的数据,此字段应为零。
编辑:回答有关SizeOfUninitializedData的问题。
可选标题中的SizeOfUninitializedData
字段只是.bss
部分的大小(如果有多个,则为其总和)。您的二进制文件没有针对该数据的单独部分,因此它为零。由于节在特定边界上对齐,因此在现有节的末尾节省一些空间比使用单独节更节省空间可能更有效。