64 位 Windows 上 PE 文件的最大大小是多少?
在我看来它总是 4GB,因为它使用相同大小的数据类型 (A DWORD)?SizeOfImage
的 DWORD 不是总是 32 位吗?还是我对这个限制有误解?
It seems to me it's always going to be 4GB, because it uses the same size datatype (A DWORD)? Isn't a DWORD for the SizeOfImage
always going to be 32-bits? Or am I mistaken about this limitation?
4GB 确实似乎是所有便携式可执行文件(32 位和 64 位 PE+)的硬限制.
4GB does indeed to seem to be the hard limit of ALL Portable Executable's (32-bit and 64-bit PE+).
根据 规范它是 32 位无符号值,用于 PE32+ 图像,就像 PE32 图像一样.
According to the spec it is 32-bit unsigned value for a PE32+ image just like a PE32 image.
但是,在我对 Windows 7 SP1 Home Premium x64 上的 32 位和 64 位应用程序(PE32/PE32+ 文件)进行的测试中,两者的最大文件大小介于 1.8-1.85GB之间>.
However, in my testing with both 32-bit and 64-bit applications (PE32/PE32+ files) on Windows 7 SP1 Home Premium x64, the maximum file size for either is between 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 限制的非图像部分分配内存.
I tested by creating a very basic C executable with Visual Studio (~8K for 32-bit and 9K for 64-bit) and the added an empty code section to the PE header until Windows would no longer load it, and then binary searched for the limit. Looking at the process with vmmap showed that almost all of the entire first 2GB of address space were the image (including any subsequently loaded DLLs such as kernel32.dll). The limit was the same for me with both 32 and 64-bit processes. The 64-bit process did have the flag set in it's NT Header's File Header's section stating that it could handle addresses >2GB. It also could allocate memory for non-image sections above the 2GB limit.
似乎需要图像完整地容纳在较低的 2GB VA 空间中,这意味着加载器有效地将 SizeOfImage 视为有符号的 32 位整数.
It seems like the image is required to fit in it's entirety in the lower 2GB of VA space for the process, which means the SizeOfImage is being treated a signed 32-bit integer by the loader effectively.