4

I want to make a file shedder to completely delete a file, by writing zeros to its physical areas.

Files may be stored on hard drive in pieces, not always in a whole block.

When I say physical areas. I mean the physical sections that the file is stored, or any reference to those sections that I can perform "writing zeros".

Better in C#.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Frank
  • 7,235
  • 9
  • 46
  • 56
  • 1
    I'm pretty sure you can't do this with .NET alone, you'll have to use some low-level calls to do this. – Kolky Jan 10 '12 at 08:11
  • 1
    Any reason why you want to write this yourself? There are many utilities that do just that on the market already. And BTW, just writing zeros over existing sectors does not completely erase the files - some software is still capable of retrieving (part of) the data. – Roy Dictus Jan 10 '12 at 08:14
  • writing to physical sectors not possible from user mode, need a kernel mode driver – David Heffernan Jan 10 '12 at 08:14
  • Hi Roy, I checked out some software in market and found they were not good. Could you please tell us why writting zeros doesn't work well? What's your suggestions? Thanks – Frank Jan 10 '12 at 08:18
  • The file system is intended to be an abstraction. The reason you can't do this in user mode is because it's *never necessary*. The only time you need to do this is if you're writing a driver, which you wouldn't be doing in C# in the first place. – Cody Gray - on strike Jan 10 '12 at 08:19
  • Hi Cody, I know what you mean. The hard drive structure need to be hidden from OS. Howver, if I couldn't do it, then how those data recovery software collect data from the hard drive? They also need some way to accessing data areas that do not have an abstraction in upper level, right? – Frank Jan 10 '12 at 08:23
  • Can't you just rewrite the file data by seeking to pos 0 and then overwrite upto the original size? If NTFS is any good it shouldn't reallocate new blocks. If that's untrue then perhaps that's why it's super slow compared to other filesystems? – hookenz Jan 10 '12 at 08:32

3 Answers3

6

Unfortunately, that is not entirely possible in C# and neither in C/C++ for that matter even if you are writing a kernel mode driver.

Quote from the Bleachbit documentation:

Shredding an individual file properly assumes its location can be completely known, but basically it can only be known in one ideal case.The ideal case has three characteristics:

  1. The file size has never shrunk because of editing. Imagine starting with a 3MB spreadsheet, editing it down to 1MB (using the spreadsheet application), and asking the cleaner application to delete the 1MB version: the cleaner has no way of knowing where the missing 2MB was allocated on the physical hard drive. (Remember: file systems often don't store files continuously, so you can't assume the missing part was directly after the known part.)
  2. The file never moved. Imagine the spreadsheet software saves the document by writing a new copy to a temporary file, deleting the old copy, and renaming the temporary file to the original name. In this case, the cleaner application has no way of knowing where any of the old spreadsheet was located.
  3. The file system overwrites files to the same place. This is a good assumption. On Windows NTFS and on Linux the most common ext3 configuration (which is the default on Ubuntu 9.10 and other Linux distributions) overwrite files in the same place, but transparent disk compression, encryption, and sparse files may not overwrite files in place.

Further: When an area of a modern hard drive is damaged, it automatically remaps the bad sector to a spare. These operations are at the discretion of the drive's firmware and neither the operating system nor applications are aware of the move, so wiping the drive ignores the damaged area.

Having said that, it is possible (albeit not easy) to figure out which sectors of the drive a file currently occupies. This requires however that your application (at least partially) understands the filesystem used and how that filesystem stores files on the underlying medium.

Finally, the question remains what additional security you would gain by identifying all the sectors your file occupies and filling them with 0s vs. just doing

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);       
}
afrischke
  • 3,836
  • 17
  • 30
1

Generally, there is no .NET API for this. Most likely you're looking at manually reading FS structures from the disk and parsing the file allocation structures and using interop to go to low-level block IO.

You might want to try to write zeroes into the file without changing its length and observing what happens. Chances are the file will not be re-allocated. I really don't know if that's the case and I suspect it depends on the OS, OS version, FS and perhaps even differs between SSDs and HDDs.

Also, consider the case when the file you're trying to shred has been reallocated by the OS recently. Some of the areas which were used by the file are now marked as "empty", but the data is still there. There is (almost) no way to figure out what these areas are/were without actually "shredding" the whole disk.

Also, for paranoids among us: writing zeroes (or ones, or garbage) into the file areas does NOT guarantee that the old data becomes unrecoverable. Physically destroying the drive might do the trick, but there is no API for that ;)

Rom
  • 4,129
  • 23
  • 18
  • Thanks for replying. I am wondering why is it not guaranteed? Can a space hold two piece of data? – Frank Jan 10 '12 at 08:36
  • 1
    @Feng HDDs are basically electrically charged pieces of metal. you *can* read residual charge from a disassembled hard drive and rebuild data from that (expensive machinery and skills needed, ofc) even if it's been repeatedly overwritten. – Alex Jan 10 '12 at 10:24
0

I'm not sure you can do this. According to This, you can only use unmanaged code to do this.

Community
  • 1
  • 1
Orentet
  • 2,353
  • 1
  • 17
  • 28