默认情况下,Windows 内存映射文件内容是否始终归零?
我凭经验确定,在我的系统上,创建为特定大小的内存映射文件在默认情况下总是完全清零。例如,使用调用
HANDLE hMM =
CreateFileMapping (h,
NULL,
PAGE_READWRITE,
0,
0x01400000,//20MB
NULL);
.. 并写入该文件的映射视图始终会生成一个完全清零的 20MB 文件,除非我写入了非零数据。
我想知道文件的未初始化部分是否可以假定为零。一般来说,这种行为在 Windows 上得到保证吗?
I've determined empirically that, on my system, a memory mapped file created to be a certain size is always completely zeroed by default. For example, using the call
HANDLE hMM =
CreateFileMapping (h,
NULL,
PAGE_READWRITE,
0,
0x01400000,//20MB
NULL);
.. and writing into a mapped view of that file always results in a 20MB file that is completely zeroed, except where I have written non-zero data.
I'm wondering if uninitialized parts of the file can be assumed to be zeros. Is this behavior guaranteed on Windows in general?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CreateFileMapping 文档(备注部分)明确指出
因此,如果磁盘上的文件一开始是空的,则不能保证它会被清零(因为您正在扩展它);我不认为文件系统驱动程序会冒着以这种方式泄露潜在敏感信息的风险,但谁知道呢,也许某些文件系统驱动程序会回收已用于您的进程的页面(这不应该是安全风险)。
另一方面,我不知道根本不提供安全性的文件系统(例如FAT)是否会如此关心为您提供它们碰巧为文件的新部分分配的簇的内容。
相反,如果您创建的内存部分不是由磁盘上的文件支持,而是由分页文件支持,则可以保证您获得的内存全部清零:
这是可以保证的,因为在创建仅内存页面文件时,内存管理器可以完全控制正在发生的事情,并且它从空白页面池中获取页面。
The CreateFileMapping documentation (Remarks section) explicitly states that
so, if your file on disk starts empty, it's not guaranteed to be zeroed (since you are expanding it); I don't think that file system drivers would take the risk of leaking potentially sensitive information that way, but who knows, maybe some file system driver recycles pages already used for your process (and this shouldn't be a security risk).
On the other hand, I don't know if filesystems that do not offer security at all (e.g. FAT) would be so concerned to give you the content of the clusters that they happened to allocate for the new part of the file.
If, instead, you are creating a memory section not backed by a file on disk but by the paging file it's guaranteed that the memory you get is all zeroed:
This is guaranteed probably because when creating a memory-only paging file the memory manager has the complete control on what's going on, and it takes the pages from the blanked pages pool.
所有新分配的页面在可供用户模式访问之前都会被清零,因为否则敏感信息可能会从内核模式或其他进程中泄漏。这适用于
NtAllocateVirtualMemory
/VirtualAlloc
和NtCreateSection
/CreateFileMapping
等。我想同样的概念也适用于文件,因为任何像样的文件系统都不想以这种方式泄漏信息。
编辑:但是,请对最后一段持保留态度 - CreateFileMapping 和 SetEndOfFile 声明文件的扩展部分未定义。我会做更多调查。
编辑 2:好的,Win32 MSDN 文档肯定是错误的。 ZwSetInformationFile 的文档指出:
所以就这样吧。扩展部分保证为零。
All newly allocated pages are zeroed before they are made accessible to user-mode, because otherwise sensitive information could be leaked from kernel-mode or other processes. This applies to things like
NtAllocateVirtualMemory
/VirtualAlloc
andNtCreateSection
/CreateFileMapping
.I imagine the same concept extends to files, because any decent file system wouldn't want to leak information in this way.
EDIT: However, take that last paragraph with a grain of salt - both the documentation for CreateFileMapping and SetEndOfFile claim that the extended portion of the file is not defined. I'll do some more investigation.
EDIT 2: OK, the Win32 MSDN documentation is definitely wrong. The documentation for ZwSetInformationFile states:
So there you go. The extended portion is guaranteed to be zero.
是的,正如wj32所指出的。这与NT自诞生以来就满足的c2要求有关。但是,根据您想要执行的操作,您可能应该查看稀疏文件。
Yes, as pointed out by wj32. This is related to c2 requirements which NT has met since its birth. However depending on what you are trying to do, you should probably look into sparse files.