64位Windows操作系统中,PE文件的最大大小是多少?

14

在我看来,它似乎总是会保持4GB的大小,因为它使用相同大小的数据类型(DWORD)?对于SizeOfImage,DWORD始终会是32位吗?或者我对这个限制有误解吗?

答案

实际上,所有可移植可执行文件(32位和64位PE+)都有4GB的硬性限制。

3个回答

14
根据规范,对于PE32+镜像来说,它是与PE32镜像一样的32位无符号值。然而,在Windows 7 SP1 Home Premium x64上测试32位和64位应用程序(PE32/PE32+文件)时,两者的最大文件大小在1.8-1.85GB之间。
我通过使用Visual Studio创建一个非常基本的C可执行文件(32位约8K,64位约9K),并向PE头添加了一个空代码段,直到Windows无法再加载它,并进行二进制搜索以查找限制。使用vmmap查看该进程可以看出,几乎全部的前2GB地址空间都是该镜像(包括任何随后加载的DLL,如kernel32.dll)。对于我来说,32位和64位进程的限制相同。64位进程确实在其NT Header的File Header部分中设置了标志,表明它可以处理大于2GB的地址。它还可以为超过2GB限制的非镜像部分分配内存。
似乎该镜像需要完全适合进程的较低2GB VA空间中,这意味着加载器将SizeOfImage视为带符号32位整数来处理。

[COFF/PE规范][1]中的pe规范在3.4.2节中有一个表格,其中SizeOfImage字段的大小为4个字节,这应该意味着PE文件理论上最大可以达到2^32字节(4 GiB)的大小。这与您获得的2GiB限制相冲突。[1]:https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v83.docx - Sahil Singh
你能否告诉我你在回答中提到的64位标志的名称,该标志表示可以处理大于2GiB的文件? - Sahil Singh
1
规范书的第10页有这样一句话:“PE32+映像允许64位地址空间,同时将映像大小限制为2GB”。这解释了为什么限制是2GiB,但为什么会有这个限制并没有提到。 - Sahil Singh
@SahilSingh 首先,这并不是一个冲突。字段的类型只允许您指定那些大小,它对操作系统实际加载这样的图像能力没有任何影响。 - harold
@harold - 那么操作系统为什么不能使用4 GiB的PE文件呢?如果不是PE头,那是什么呢? - Sahil Singh
当您超过限制时,您遇到了什么错误? - Ayman Salah

8
根据COFF/PE32规范,有效的PE32+(64位/(PE+)文件)的图像大小为4字节无符号值。

完全正确,那意味着限制为2^(4*8)B - 1B = 4GiB - 1B。我在Windows 10 64位上通过使用WinRAR创建自解压缩归档文件形式的.EXE文件来验证了这一点。一个大小为4GiB的可执行文件无法启动,但是4GiB - 1B可以正常工作。 - Robin Hartmann

1
PE头中的ImageSize字段与PE文件磁盘上的文件大小没有太大关系。ImageSize是加载的映像在内存中的大小,即所有节的大小(每个节都舍入到SectionAlignment边界)+ PE头的大小(在下一个头字段SizeOfHeaders中给出)。由于规范要求,并且规范中存在31位RVA(例如在导入查找表中),因此对于PE32或PE32 +,此值不能> 2GB。 RVA是作为相对于内存基址的偏移量给出的内存引用。
虽然这是在内存中,但磁盘上的文件可能包含未加载到内存中的数据(例如调试数据、证书数据)。 PE规范中的文件指针字段是32位无符号值。因此,根据规范,PE文件的理论最大尺寸为4GB。
这是根据规范。除了PE规范外,可能存在文件系统、装载程序、操作系统限制,进一步降低了最大值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接