我刚刚在一本关于 Windows 7 的书中读到了有关文件松弛的内容。我已经(认为)知道的是:
- Windows 将数据以簇的形式存储在磁盘上。一个簇通常包含 8 个扇区,每个扇区 512 字节,因此为 4096 字节或 4kiB。
- 大文件会被分割到多个簇上,当文件的剩余部分不能填满整个簇时,簇末端剩余的未使用空间就称为“文件松弛”。
- Windows 总是一次写入 512 字节块,因此第一个仅部分使用的扇区必须先填满,然后才能写入磁盘。
- 无论出于什么原因,Windows 决定从 RAM 中选择一个随机序列来填充该扇区。
- 部分使用的簇中剩余的未使用扇区保持不变,并保留它们之前的字节,这些字节可能是此位置中之前删除的文件的一部分。这称为驱动器松弛。
这些假设正确吗?
为什么 Windows 会将随机的内存片段(可能包含密码等)写入我的磁盘只是为了填满空间 - 而不是将这些字节清零?
这种行为是 Windows 特有的(哪个版本?)还是 NTFS 文件系统特有的?Linux 或 ext4 文件系统也会这样做吗?
答案1
“文件松弛”指的是文件最后一个字节和簇末尾之间的数据。它通常包含操作系统用来表示未分配内存的任何位模式。
“驱动松弛”指已释放但未被覆盖的簇。它也可以指不再位于分区边界内的未分配空间。
“内存松弛”-- 我以前从未听说过这个术语。在谷歌上搜索这个,我发现的所有资源似乎都引用或源自一本名为《网络取证:收集、检查和保存计算机犯罪证据的现场手册》的书,作者是 Albert J. Marcella, Jr. 和 Doug Menendez。
我读了使用该术语的章节。尽管该术语的版权在 2010 年就已获得,但它提到了 DOS 和 Windows 95/98 的运作方式。十多年来,这已经不相关了。不过,我可能断章取义了。无论如何,这本书似乎是该术语的来源。
Windows 将数据以簇的形式存储在磁盘上。一个簇通常包含 8 个扇区,每个扇区 512 字节,因此为 4096 字节或 4kiB。
对于传统驱动器和 4K“高级格式”驱动器而言,这是正确的。4K“原生”驱动器上的扇区大小确实是 4KB,因此这些驱动器的扇区和簇之间存在 1:1 的对应关系。
大文件会被分割到多个簇上,当文件的剩余部分不能填满整个簇时,簇末端剩余的未使用空间就称为“文件松弛”。
也正确。
Windows 总是一次写入 512 字节块,因此第一个仅部分使用的扇区必须先填满,然后才能写入磁盘。
这是不正确的。Windows 不会以块为单位写入数据,只会以簇为单位写入数据。它会以任意大小写入数据,但大小会是簇大小的倍数(通常为 4KB)。Windows 唯一关心扇区/块的情况是必须计算 LBA 地址时。这是低级磁盘驱动程序执行的操作,而不是文件系统驱动程序。以 512 字节块为单位进行读写实际上非常低效。它与驱动器的内部硬件缓存有关。dd
在 Linux 中使用 512 字节块大小执行操作可以证实这一点。读写速度都会慢一个数量级。
无论出于什么原因,Windows 决定从 RAM 中选择一个随机序列来填充该扇区。
也是不正确的。Windows 将写入缓冲区中的任何内容。几乎每个应用程序(包括文件系统驱动程序)在写入输出缓冲区时都会从堆中分配新内存。当应用程序分配内存时,它会以页面的形式进行,页面大小为(猜猜是什么!)4KB。未分配的内存通常由重复的位模式(不是 00 或 FF)表示,因此如果簇未满,它将被写入簇的末尾。如果应用程序的输出缓冲区是其输入缓冲区的修改副本,则松弛部分将包含输入缓冲区中的任何数据。
部分使用的簇中剩余的未使用扇区保持不变,并保留它们之前的字节,这些字节可能是此位置中之前删除的文件的一部分。这称为驱动器松弛。
也是不正确的。即使只有 1 个字节的数据发生变化,Windows 也始终会执行全集群提交。它是诚然解除分配簇中保留了之前的数据。Windows 不会费心将已释放的簇清零。但这一切都不会在扇区级别发生。
4KB 是一个神奇的数字。内存页面是 4KB。I/O 缓冲区是 4KB。扇区现在是 4KB。甚至驱动器的硬件也针对 4KB(或其倍数)的 I/O 请求进行了优化。
所有现代操作系统都以这种方式工作(Windows、Linux 和 OS X)。上述规则的唯一例外是那些打开磁盘进行原始访问的应用程序。它们完全绕过操作系统的 API 调用来执行写入。您只能在低级恢复和取证工具中看到这种情况,因为此类应用程序无法从缓冲 I/O 带来的所有优化中受益。
答案2
RAM slack 实际上是一种众所周知的数字取证工具。
确实,旧版(即 Win 95/98)Windows 确实写入了 512 字节内存块。请不要与将群集写入介质相混淆。当我写入 512 字节内存时,我的意思是 Windows 分配/抓取内存以 512 字节块的形式写入,总计存储介质群集。
例如,存储介质上有 4096 字节簇,文件长度为 2049 字节。旧版 Windows 以 512 字节为单位分配和抓取缓冲区/缓存/内存存储在记忆中对于该 2049 字节的文件。
这需要 5 x 512 字节记忆块。这样就剩下 511 个字节被抓取,它们不属于 2049 字节文件。(5 x 512 = 2560,但 2049 / 512 = 4.002)。
那么 511 字节内存(2560 - 2049 = 511)中有什么?在旧版本中,Windows 不会清除 511 字节部分,而是将其与整个 4KB 一起写入。这就是数字取证界所称的 RAM 松弛。