4

我想通过将零写入文件的物理区域来制作文件脱落器以完全删除文件。

文件可以分段存储在硬盘驱动器上,而不是始终存储在整个块中。

当我说物理区域时。我的意思是文件存储的物理部分,或者对我可以执行“写入零”的那些部分的任何引用。

在 C# 中更好。

4

3 回答 3

6

不幸的是,即使您正在编写内核模式驱动程序,这在 C# 和 C/C++ 中也不完全可能。

引用 Bleachbit 文档:

正确粉碎单个文件假设它的位置可以完全知道,但基本上只能在一种理想情况下知道。理想情况具有三个特征:

  1. 文件大小从未因编辑而缩小。想象一下,从 3MB 的电子表格开始,将其编辑为 1MB(使用电子表格应用程序),并要求清理程序删除 1MB 版本:清理程序无法知道丢失的 2MB 在物理硬盘驱动器上的分配位置。(请记住:文件系统通常不会连续存储文件,因此您不能假设丢失的部分直接位于已知部分之后。)
  2. 该文件从未移动。想象一下,电子表格软件通过将新副本写入临时文件、删除旧副本并将临时文件重命名为原始名称来保存文档。在这种情况下,清理应用程序无法知道任何旧电子表格的位置。
  3. 文件系统将文件覆盖到同一位置。这是一个很好的假设。在 Windows NTFS 和 Linux 上,最常见的 ext3 配置(这是 Ubuntu 9.10 和其他 Linux 发行版上的默认配置)会在同一位置覆盖文件,但透明磁盘压缩、加密和稀疏文件可能不会在原地覆盖文件。

进一步:当现代硬盘驱动器的某个区域损坏时,它会自动将坏扇区重新映射到备用扇区。这些操作由驱动器的固件决定,操作系统和应用程序都不知道移动,因此擦除驱动器会忽略损坏的区域。

话虽如此,有可能(尽管不容易)找出文件当前占用的驱动器的哪些扇区。但是,这要求您的应用程序(至少部分地)了解所使用的文件系统以及该文件系统如何在底层介质上存储文件。

最后,问题仍然是通过识别文件占用的所有扇区并用 0 填充它们而不是仅仅做,您可以获得什么额外的安全性

using(var fs = new System.IO.FileStream(@"m:\delme.zip", 
                                        FileMode.Open,
                                        FileAccess.Write,
                                        FileShare.None))
{
    var zeros = new byte[fs.Length];

    fs.Write(zeros, 0, zeros.Length);       
}
于 2012-01-10T08:24:31.877 回答
1

通常,没有用于此的 .NET API。很可能您正在考虑从磁盘手动读取 FS 结构并解析文件分配结构并使用互操作转到低级块 IO。

您可能想尝试在文件中写入零而不更改其长度并观察发生的情况。文件可能不会被重新分配。我真的不知道是不是这样,我怀疑这取决于操作系统、操作系统版本、FS,甚至可能在 SSD 和 HDD 之间有所不同。

此外,请考虑您尝试粉碎的文件最近已被操作系统重新分配的情况。该文件使用的一些区域现在被标记为“空”,但数据仍然存在。如果不实际“切碎”整个磁盘,则(几乎)无法弄清楚这些区域是/曾经是什么。

此外,对于我们当中的偏执狂:将零(或一,或垃圾)写入文件区域并不能保证旧数据变得不可恢复。物理地破坏驱动器可能会奏效,但没有 API ;)

于 2012-01-10T08:27:46.537 回答
0

我不确定你能做到这一点。根据This,您只能使用非托管代码来执行此操作。

于 2012-01-10T08:20:25.803 回答