默认情况下,Windows 内存映射文件内容是否始终归零?

发布于 2024-10-14 20:01:38 字数 403 浏览 7 评论 0原文

我凭经验确定,在我的系统上,创建为特定大小的内存映射文件在默认情况下总是完全清零。例如,使用调用

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心的憧憬 2024-10-21 20:01:38

CreateFileMapping 文档(备注部分)明确指出

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

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

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

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

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

这是可以保证的,因为在创建仅内存页面文件时,内存管理器可以完全控制正在发生的事情,并且它从空白页面池中获取页面。

The CreateFileMapping documentation (Remarks section) explicitly states that

If the file is extended, the contents of the file between the old end of the file and the new end of the file are not guaranteed to be zero; the behavior is defined by the file system.

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:

The initial contents of the pages in a file mapping object backed by the operating system paging file are 0 (zero).

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.

无人问我粥可暖 2024-10-21 20:01:38

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

我想同样的概念也适用于文件,因为任何像样的文件系统都不想以这种方式泄漏信息。

编辑:但是,请对最后一段持保留态度 - CreateFileMapping 和 SetEndOfFile 声明文件的扩展部分未定义。我会做更多调查。

编辑 2:好的,Win32 MSDN 文档肯定是错误的ZwSetInformationFile 的文档指出:

如果将 FileInformationClass 设置为
FileEndOfFileInformation,以及
文件结尾成员
FILE_END_OF_FILE_INFORMATION 指定
超出当前值的偏移量
文件结束标记,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 and NtCreateSection/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:

If you set FileInformationClass to
FileEndOfFileInformation, and the
EndOfFile member of
FILE_END_OF_FILE_INFORMATION specifies
an offset beyond the current
end-of-file mark, ZwSetInformationFile
extends the file and pads the
extension with zeros.

So there you go. The extended portion is guaranteed to be zero.

二智少女 2024-10-21 20:01:38

是的,正如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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文