Click here to Skip to main content
Click here to Skip to main content
Go to top

FileDestroyer: Annihilate Files (overwrite multiple times, then delete) With This Utility

, 22 May 2014
Rate this:
Please Sign up or sign in to vote.
The complete deletion of files leads us to understand the file system and OS even more deeply.

Introduction

Have you ever wondered how to completely destroy a file which has been written to your Windows File System? I've heard a lot about this and often wondered how I would set out to do that. The utility attached (FileDestroyer) to this article makes it extremely easy to do that.

Caveat Emptor - BEWARE: IT DELETES

Please don't try this program on files you want to keep. This thing will destroy those files (overwrite them numerous times) and finally delete them. It is extremely unlikely you will be able to recover them. Be careful and understand that I assume no responsiblity for files you delete using this utility.

This utility is intended for instructional purposes and / or deleting files you really want to destroy such as old copies of your tax returns or whatever.

Background

Recently, during a trip to the local Barnes & Noble I stumbled upon a book talking about how that when file is deleted it isn't actually completely deleted. Of course most of us know that deleted files are not actually deleted but are simply marked as free space again and then only after they are over-written are they gone. But, I've also heard that tools can be used to restore these files even after they've been over-written 3 or 4 times.

That led me to wonder if I could write a simple utility which would Destroy a chosen file. How would I do that? That is the investigation I set out to undertake and this article details what I learned and how I came to build the attached utility (FileDestroyer).

Using the code

First Requirement : Work Seemlessly With File Explorer

This utility is directly associated with the File System, of course, so one of the main requirements I had was that it would work seemlessly with File Explorer.

Some Kind of Shell Hook?

At first I thought this meant I had to do some kind of special Windows Shell Hook in my code or something. I thought I had to hook into the Windows Shell in some special way to get it to run my functionality. But then I remembered that using the Windows Registry I could do insert commands on the File Explorer context menu.

You see, I want the functionality to be called from File Explorer when a user simply right-clicks on the file. It should look like what you see in the following image:

That way the user can simply right-click the file, choose "Destroy File" and the file will be over-written and deleted and completely destroyed.

Extend File Explorer Context Menu, The Easy Way

I did a little searching on how to extend the File Explorer context menu and learned that you can add in commands by altering the following Windows Registry path:

or as a string : \\HKEY_CLASSES_ROOT\*\shell\

Under the shell key, you have to add a key with the text that you want to see display in the context menu. In our example, we want it to display the words, [Destroy File], so I have added a key named Destroy File.

Here's what the entire thing looks like in the Registry Editor

Image NOTE: Later I found that to fix a problem with spaces in the filename you need to wrap the %1 variable in double-quotes like "%1". This change is produced properly in the registry download file so you won't have that problem.

After you create the key (folder) in that path, you'll need to create another key under that one named Command.

Finally, once you create one named Command, you'll need to add a value that becomes the (default) value which will be the string of the command you want to run when the user selects the menu item.

Executable Path

This is the thing that will point to the FileDestroyer executable. In our case, I have it pointing to the directory: c:\dev\C#\FileDestroyer\FileDestroyer.exe

Obviously, you can alter this to point at any executable in any location.

I've attached a registry file which will create the entire thing for you so you can easily import it into your registry.

Double-Backslashes and %1 Argument

If you open the file you'll notice that it contains double-backslashes to escape those backslash characters in the path and it contains a argument of %1.

The %1 simply represents an argument that will be sent into the FileDestroyer application. The %1 coming from the File Explorer in this case is a file name so it works perfectly for our needs.

For Now, Only Files Only, No Directories

If this had been a Directory, then we would get a directory name. However, at this time I am going to only implement FileDestoryer for one or more files, not on the directory. A subsequent update to this article will handle that work.

Summary: Up To This Point

At this point, we have the first parts of our program ready. I can now get the file name(s) from File Explorer and call my program with the file name as an argument.

I am ready to do the work to destroy the file.

OverWriting Should Be Easy: The Challenges

Here's where I believe my attempt to create this solution becomes additionally interesting. Now I want to do the work to overwrite the file bytes numerous times.

Write A New Byte For Each One That Exists

That means i just need to get the number of bytes in the file. That is easy with the C# FileInfo class.

I just do the following:

      public static void Main(string[] args)
    {
            string targetFile = args[0];
        FileInfo fi = new FileInfo(targetFile); 

I grab the first argument out of the args[] array.

I know that first argument represents the file name (passed in from File Explorer). I save it off in a variable named targetFile.

Next, I can pass that filename (it includes the complete path) to my FileInfo constructor.

Later in my code I can use the fi object to get the size in bytes of my file. It looks like the following:

 fi.Length  

Now that I have the length (in bytes) for the file, it seems like an easy task to simply overwrite each byte with a garbage byte like a zero or something.

Unbuffered Output Is Required

However, I need to actually write to the disk. I need to force the bytes to the disk and not just get written to a memory buffer. I want to overwrite the bytes on the disk and many file writing schemes are buffered, which means the bytes are not written to the actual disk. Instead the bytes are buffered to memory which would mean the disk isn't actually altered except maybe one time at the end of the process. However, I want to insure that I write each and every byte to the disk numerous times.

A Possible Problem

One of the reasons I find this problem so interesting is because normally as software developers we only consider the layer we are working in. For example, if you are .NET developer you think about what the class library provides for you and if you can get your program to work reasonably well while handling errors you think you've solved the problem properly. However, other underlying conditions may cause your logic to be incorrect.

OS Layer of Control

For example in our case, it may be impossible to completely force bytes to be written to the disk, because the Windows Operating System itself, may decide to buffer all the bytes and not write them until some later time. If we cannot get around this limitation it would mean that I could not write this program.

This displays the real truth of computer programming which many scripters forget -- you must know exactly what the computer is actually doing. A lot of people who've written programs and consider themselves programmers have just gotten lucky a lot, because they don't really know what goes on in the various layers.

The Best Information I Could Find On Caching

So we see that we are controlled by the many layers and that is why I've decided to go straight to the Windows API calls in my program -- so I have fewer layers attempting to control me.

Here is the best snippet I could find about disk caching:

[ -- If FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING are both specified, so that system caching is not in effect, then the data is immediately flushed to disk without going through the Windows system cache. The operating system also requests a write-through of the hard disk's local hardware cache to persistent media. --]

FILE_FLAG_WRITE_THROUGH
0x80000000

Write operations will not go through any intermediate cache, they will go directly to disk.

Those two sections come from the CreateFile API documentation at http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx

That is why you will see that my call to CreateFile looks like the following:

        IntPtr hFile = CreateFile(targetFile,  
               FileAccess.Write,
           FileShare.None,
           IntPtr.Zero,
           OPEN_EXISTING,
           FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_NORMAL,
           IntPtr.Zero); 

You can see that I've bitwise OR'd the flags together so that I ignore all disk caching. Hopefully. As far as I know. Smile | :)

No Caching Really Doesn't Mean Slow

No caching means these bytes are going to be written directly to the disk. It means that this program is going to wait for other programs to give it a slice of disk time so it can write. It means that at times, the program will be waiting on other disk I/O operations handled by the OS and that waiting may mean slowness. However, I was shocked at the speed.

Is It Too Slow?

I was able to destroy a file that is 90Megabtyes in about 5 seconds for one iteration of writing. Yes, to completely destroy that file you need to overwrite it a larger number of times (5 to 10) but that is still exceptionally fast.

Configure Number of Overwrites

In the interest of creating a program that you can use without recompiling I've added some lines of code which will look for

a configuration file : FileDestroyer.config

in the Application.Execution Directory

If it finds that file in the directory it will simply attempt to load the file to obtain the number of times the program should overwrite the data (OverwriteMax) and whether or not the program should delete the file after it is done (DeleteAfterOverwrite -- bool).

This way you can test the program and determine if overwriting 7 times works efficiently on your computer and you can take a look at the file before it is deleted so you can determine that all bytes are set to 0.

 OverwriteMax = Convert.ToInt32(configLines[0].Split(new char[]{','})[0]);
DeleteAfterOverwrite = Convert.ToBoolean(configLines[0].Split(new char[]{','})[1]); 

Main Work : Overwriting The File

First : StrongMethod

Looking in the code you are going to find on function called StrongMethod()

This method takes a targetFile (path and filename sent in from FileExplorer), an integer (MaxWrites) which determines the number of times the bytes will be overwritten a FileInfo object which we use to get info about that file and then a boolean value (DeleteAfterOverwrite) which will determine if the code will run the File.Delete method on the file after it overwrites it.

Unbuffered Writing Has More Requirements

When writing directly to the disk I learned that you are forced to write to files in blocks which are the same size of the disk blocks. I have hardcoded that value to 512 which is the size of the blocks on my disk.

Silent Fail : The Worst Kind of Fail

This is very interesting, because as I attempted to overwrite the bytes and I set my byte buffer which was supposed to be written to disk I found that it would never write the bytes out.

Finally, I discovered that I was getting a error returned in GetLastError which was a bit cryptic. Searching the web uncovered very little information but a few people revealed that WriteFile would only write for them in block sizes also.

What Does This Mean? It Means Math

It just means that I had to add a bit of code so that every file is calculated to a size which is exactly divisible by 512. That means if a file is from 1 to 512 bytes in size, then I need to write 512 bytes out. If the file is from 513 to 1024 bytes, then I write out 1024 bytes. That means if you create a 1 byte file and save it out, then Destroy it with this program, then FileDestroyer will write 512 bytes to that file MaxOverwrites times and finally delete it.

public static void StrongMethod (string targetFile, int MaxWrites, FileInfo fi, bool DeleteAfterOverwrite)
{ 
    int WRITE_SIZE = 512;
    // outputFileSize is the new file size which is divisble evenly by WRITE_SIZE
long outputFileSize = (long)Math.Ceiling((double)fi.Length / WRITE_SIZE);
// open the file and write to it FILEWRITE_COUNTER times
    for (int x = 0; x < MaxWrites;x++)
    {
        IntPtr hFile = CreateFile(targetFile, 
                          FileAccess.Write,
                          FileShare.None,
                          IntPtr.Zero,
                         OPEN_EXISTING,
                 FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_NORMAL ,
                   IntPtr.Zero);
                    uint bytesWritten;
        byte [] charToWrite = new byte[WRITE_SIZE * outputFileSize];
                        // initialize array to all zeros
        for (int z= 0;z<charToWrite.Length;z++)
        {
            charToWrite[z] = 48; // write the 0 char (ASCII value 48)
        }
                        bool retVal = false;
    System.Threading.NativeOverlapped no = new System.Threading.NativeOverlapped();
                    // write the entire file out.
retVal = WriteFile(hFile,charToWrite,(uint)(charToWrite.Length),out bytesWritten,ref no);
        
       if (!retVal)
            {
                MessageBox.Show(GetLastError().ToString());

            }

           if (hFile != null)
           {
                bool success = CloseHandle(hFile);
          }
    }
    if (DeleteAfterOverwrite)
    {
        File.Delete(targetFile);
    }
} 

Second : WeakMethod

I have also added a method which I call the WeakMethod, because it uses the .Net API to overwrite the file so we have less control over whether or not the bytes are truly written to the disk or not. I think they are, but I cannot prove* it.

That method is far simpler and looks like the following:

public static void WeakMethod(string targetFile, int MaxWrites)
{
    byte [] allBytes = File.ReadAllBytes(targetFile);
        // initialize array of bytes to value of 0
    for (long byteCounter = 0;byteCounter < allBytes.LongLength;byteCounter++)
    {
        allBytes[byteCounter] = 48;
    }
        for (int x = 0;x < MaxWrites;x++)
    {
        File.WriteAllBytes(targetFile,allBytes);
    }
} 

That's all of the interesting points about this application.

Final Note About Truly Destroying Data

Please keep in mind, I do not have a way to prove that I am actually writing bytes to the disk. I wish I did. To determine that I need to write a C or Assembler program which allows me to read bytes directly from the disk. So, even though I'm doing all this overwriting, it may be that I'm not actually writing bytes to the disk at all. Maybe the OS just ignores me and doesn't do it anyway.

However, I think this program and idea is valuable because it makes you think about what you can and can't control as a programmer. I'm hoping this starts a dialogue about programming and thinking about solutions in general and specifically related to this application. Try the program and leave notes.

Quick Summary To Setting Up & Using the Program

Here are the steps to get the program working for you on your computer.

  1. Download DestroyFileShell_Registry file
  2. Unzip and Double-click registry file to add the entry to the registry*.
  3. Download the source and build or get the Exe and place it in the path where the FileDestroyer.exe will run.
  4. Optional : Edit your config file so to delete the file after overwriting. The provided config file has the DeleteAfterOverwrite set to false. If you do not provide a config file at all, the program will automatically delete the file after overwriting it. The config file is looked for and loaded from the application startup path, so place it in the same directory where the DestroyFile.exe is located.

*Note: Step 2 sets up the default path to your DestroyFile.exe. In the provided registry file the path is: C:\Dev\C#\FileDestroyer. Obviously, if that path is invalid, the program will not work for you. Make sure you either, edit the file to point to the location where you are going to keep the DestroyFile.exe or edit Registry key after you've added it.

FileDestroyer.config & Breaking Conventions

Please note: It is very important that you notice that the config file where the MaxOverwrites and the DeleteAfterOverwriting is actually named FileDestroyer.config. It is NOT named FileDestroyer.exe.config. I understand this breaks convention. I was doing this very quickly and just wanted to provide a way to reload those values without having to recompile the program. I did not want to implement all the config file reading stuff so I did it this way.

Gratuitous Self Promotion

If you've enjoyed this article, please check out my books on Amazon.com. Thanks.

Points of Interest

Console Application / No Window Please

I originally built this as a Console Application using SharpDevelop. Each time I ran the application though I got a blinky console window. I wasn't sure how to get rid of that, since I really don't want any User Interface for this application so it will behave as a "plugin" to File Explorer.

I learned that all you have to do is change the Project Property option from Console Application to Windows Application and rebuild. Now, you have no window since you haven't added on to the project. Very easy.

Important Research Links

Here are some links with important information related to this article

File Buffering

http://msdn.microsoft.com/en-us/library/windows/desktop/cc644950(v=vs.85).aspx

Write File Function (Windows API)

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx

History

Initial release : 05/22/2014

Attempting to add more notes to see if this article will publish.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

newton.saber
Architect
United States United States
My newest book is Learn Python, Think Python (amazon link opens in new window/tab)
 
My previous book is Object-Oriented JavaScript (See it at Amazon.com)
 
My book, Learn JavaScript - amazon.com link is available at Amazon.
 
My upcoming book, Learn AngularJS - Think AngularJS, will be releasing later in 2014.
 
You can learn more about me and my other books, at, Follow on   Twitter

Comments and Discussions

 
QuestionMy vote of 5 PinmemberMember 105253171-Jun-14 19:46 
AnswerRe: My vote of 5 Pinmembernewton.saber2-Jun-14 1:48 
Questionproblem with SSD PinmemberSergV-SNV25-May-14 19:58 
AnswerRe: problem with SSD Pinmembernewton.saber26-May-14 4:46 
AnswerRe: problem with SSD Pinmembernewton.saber2-Jun-14 4:48 
GeneralRe: problem with SSD [modified] PinmemberSergV-SNV2-Jun-14 18:35 
GeneralRe: problem with SSD Pinmembernewton.saber3-Jun-14 2:01 
GeneralGreat Work... PinprofessionalMayurDighe22-May-14 9:34 
GeneralRe: Great Work... Pinmembernewton.saber22-May-14 10:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140922.1 | Last Updated 22 May 2014
Article Copyright 2014 by newton.saber
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid