Windows内存映射文件内容是否始终归零?

Ada*_*erg 3 c++ windows kernel memory-mapped-files

我已经根据经验确定,在我的系统上,默认情况下,创建为特定大小的内存映射文件始终完全归零.例如,使用呼叫

HANDLE hMM = 
    CreateFileMapping (h,
                        NULL,
                        PAGE_READWRITE,
                        0,
                        0x01400000,//20MB
                        NULL);
Run Code Online (Sandbox Code Playgroud)

..并且写入该文件的映射视图总是会导致20MB的文件完全归零,除非我写了非零数据.

我想知道文件的未初始化部分是否可以假定为零.这种行为一般在Windows上得到保证吗?

Mat*_*lia 7

的CreateFileMapping文档(备注部分)明确规定,

如果文件被扩展,则文件旧端与文件新端之间的文件内容不保证为零; 行为由文件系统定义.

所以,如果磁盘上的文件为空,则不能保证归零(因为你正在扩展它); 我不认为文件系统驱动程序会冒这种方式泄漏潜在敏感信息的风险,但是谁知道,也许某些文件系统驱动程序会回收已经用于您的进程的页面(这不应该是安全风险).

另一方面,我不知道根本不提供安全性的文件系统(例如FAT)是否会如此关注为您提供他们碰巧为文件的新部分分配的集群的内容.

相反,如果您创建的内存部分不是由磁盘上的文件支持,而是由分页文件创建,则可以保证您获得的内存全部归零:

由操作系统页面文件支持的文件映射对象中的页面的初始内容是0(零).

这可以保证,因为在创建仅内存页面文件时,内存管理器可以完全控制正在进行的操作,并从空白页面池中获取页面.


wj3*_*j32 6

所有新分配的页面在用户模式可访问之前都归零,因为否则敏感信息可能会从内核模式或其他进程泄漏.这适用于像NtAllocateVirtualMemory/ VirtualAllocNtCreateSection/ 这样的东西CreateFileMapping.

我想同样的概念扩展到文件,因为任何体面的文件系统都不希望以这种方式泄露信息.

编辑:但是,最后一段用一粒盐 - CreateFileMapping和SetEndOfFile的文档声称文件的扩展部分没有定义.我会做更多的调查.

编辑2:好的,Win32 MSDN文档肯定是错误的.ZwSetInformationFile的文档说明:

如果将FileInformationClass设置为FileEndOfFileInformation,并且FILE_END_OF_FILE_INFORMATION的EndOfFile成员指定超出当前文件结束标记的偏移量,则ZwSetInformationFile会扩展文件并使用零填充扩展名.

你去吧 延伸部分保证是零.

  • @ wj32:实际上Win32被设计为"充满谎言",以使应用程序无缝地在NT,9x,(部分)在Win32s上运行,以及微软将来考虑的任何内核,而不依赖于特定于平台的实现细节.任何表现良好的Win32应用程序应该只依赖于Win32合同,以确保在未来的Windows版本中继续工作.你有没有读过Raymond Chen的博客?`:)` (2认同)