views:

897

answers:

6

I have been tasked to overwrite all the free space on a few laptops 3 times. I know there are some alternatives but I like to know how things work and if I can to do it myself with C#.

1) yes, I know there are plenty of freeware applications that will do this

2) no, we don't need to conform to any specific government standard

Where do I look for ideas on how to start this?

Thanks if you can point me in the right direction.

Can it be achieved using C#? If so, how?

+2  A: 

Simple algorithm:

  • Create a large text file full of arbitrary text (best to use a pre-created file instead of regenerating random for performance reasons. Test it out.)
  • Create a clever folder and file naming scheme so as to be able to track the files. You should also track the files with your app but if it crashes, especially near the end of a first few test runs, you'll want to be able to easily find and clean up your handy work.
  • Write it to the HDD until it's full
  • Delete the files you created
  • Repeat above steps two more times

Update: More advanced consideration on wiping per subsequent discussion:

  • On first pass write files of 0x0000 values (all bits off)
  • On second pass write all bits as 0xFFFF (all bits on)
  • On last pass repeat with 0x0000

The above ignores a few ideas such as what is the best size of the file, depends on your file system anyway. You might also get different behaviors from the OS as you near a filled HDD...

Paul Sasik
This may be a much better way than mine to handle the simple implementation he's looking for. As I said, I'm no expert in the field ;)
statichippo
I will just add, that writing zeros to the file is even better (no need to add text to it).
gbianchi
@gbianchi: Perhaps... That's where it gets a little more theoretical. Would random text be better at foiling would-be data thiefs? Perhaps, perhaps not. Might also be better actually to switch between 0s and 1s to force a bit flip to truly "wiggle" out the previous data.
Paul Sasik
Thanks for the info. I would probably wouldn't use a pre computed text file It seems like that would be easy to back out if you needed to retrieve teh data. Same thing with writing to individual bits. you should probably just do random, random , random or at the very least on off random. just so you can't back out the data.My reasoning is that if you can't reverse engineer random they can't tell if what they are looking at is a file or white noise.
Crash893
Might not work too well on SSDs, because their wear levelling algorithms will spread these writes.
MSalters
A: 

You're going to have to do some low level manipulations, so you'll certainly have to talk to the Win32 API. I haven't done this sort of thing, so I can't give you specifics, but a good place to start looking might be the Win32 API reference:http://msdn.microsoft.com/en-us/library/aa383749%28VS.85%29.aspx

I'm really not an expert in this field at all, but it seems to my naive understanding that you'll need to: 1) get info on where the filesystem starts & stops 2) using the non-deleted files as a reference, get a list of physical locations of what should be free space 3) write 0's to those locations

Maybe this isn't a great answer since I'm not an expert in the field, but it was a bit too long for a comment ;) I hope that helps a little.

statichippo
A: 

Check the SDelete documentation, maybe you can get a clue there.

jmservera
is this available in english?
statichippo
oops, sorry, changed to en-us
jmservera
A: 

This code is from The Code Project I think. I'm unsure where the orignal article is, but it does what you asked for:

Based on comments I clearly need to spoonfeed a bit more..

You can do this very simply, based on your requirements.

  1. Make 1 large file that fills the remaining free size on your drive. Then simply wipe this file.

  2. Make several files until your drive is full. (This might be better if you want to use the machine while its going on ). Then you can start wiping each file, so in effect the total time the system has a full hard disj drive is smaller than using method 1. But it will likely be a bit slower and use a bit more code.

The advantage of using are a few, easy code for you to use. You don't have to play with low level APIs that will screw you over.

using System;
using System.IO;
using System.Security.Cryptography;

namespace QuickStarterShared
{
    public class Wipe
    {
        /// <summary>
        /// Deletes a file in a secure way by overwriting it with
        /// random garbage data n times.
        /// </summary>
        /// <param name="filename">Full path of the file to be deleted</param>
        /// <param name="timesToWrite">Specifies the number of times the file should be overwritten</param>
        public void WipeFile(string filename, int timesToWrite)
        {
#if !DEBUG
            try
            {
#endif
                if (File.Exists(filename))
                {
                    // Set the files attributes to normal in case it's read-only.
                    File.SetAttributes(filename, FileAttributes.Normal);

                    // Calculate the total number of sectors in the file.
                    double sectors = Math.Ceiling(new FileInfo(filename).Length/512.0);

                    // Create a dummy-buffer the size of a sector.
                    byte[] dummyBuffer = new byte[512];

                    // Create a cryptographic Random Number Generator.
                    // This is what I use to create the garbage data.
                    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

                    // Open a FileStream to the file.
                    FileStream inputStream = new FileStream(filename, FileMode.Open);
                    for (int currentPass = 0; currentPass < timesToWrite; currentPass++)
                    {
                        // Go to the beginning of the stream
                        inputStream.Position = 0;

                        // Loop all sectors
                        for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++)
                        {
                            // Fill the dummy-buffer with random data
                            rng.GetBytes(dummyBuffer);
                            // Write it to the stream
                            inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                        }
                    }
                    // Truncate the file to 0 bytes.
                    // This will hide the original file-length if you try to recover the file.
                    inputStream.SetLength(0);
                    // Close the stream.
                    inputStream.Close();

                    // As an extra precaution I change the dates of the file so the
                    // original dates are hidden if you try to recover the file.
                    DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
                    File.SetCreationTime(filename, dt);
                    File.SetLastAccessTime(filename, dt);
                    File.SetLastWriteTime(filename, dt);

                    File.SetCreationTimeUtc(filename, dt);
                    File.SetLastAccessTimeUtc(filename, dt);
                    File.SetLastWriteTimeUtc(filename, dt);

                    // Finally, delete the file
                    File.Delete(filename);
                }
#if !DEBUG
            }
            catch(Exception e)
            {

            }
#endif
        }
    }

    # region Events
    # region PassInfo
    public delegate void PassInfoEventHandler(PassInfoEventArgs e); 
    public class PassInfoEventArgs : EventArgs
    {
        private readonly int cPass;
        private readonly int tPass;

        public PassInfoEventArgs(int currentPass, int totalPasses)
        {
            cPass = currentPass;
            tPass = totalPasses;
        }

        /// <summary> Get the current pass </summary>
        public int CurrentPass { get { return cPass; } }
        /// <summary> Get the total number of passes to be run </summary> 
        public int TotalPasses { get { return tPass; } }
    }
    # endregion

    # region SectorInfo        
    public delegate void SectorInfoEventHandler(SectorInfoEventArgs e);
    public class SectorInfoEventArgs : EventArgs
    {
        private readonly int cSector;
        private readonly int tSectors;

        public SectorInfoEventArgs(int currentSector, int totalSectors)
        {
            cSector = currentSector;
            tSectors = totalSectors;
        }

        /// <summary> Get the current sector </summary> 
        public int CurrentSector { get { return cSector; } }
        /// <summary> Get the total number of sectors to be run </summary> 
        public int TotalSectors { get { return tSectors; } }
    }
    # endregion

    # region WipeDone        
    public delegate void WipeDoneEventHandler(WipeDoneEventArgs e);
    public class WipeDoneEventArgs : EventArgs
    {
    }
    # endregion

    # region WipeError
    public delegate void WipeErrorEventHandler(WipeErrorEventArgs e);
    public class WipeErrorEventArgs : EventArgs
    {
        private readonly Exception e;

        public WipeErrorEventArgs(Exception error)
        {
            e = error;
        }

        public Exception WipeError{get{ return e;}}
    }
    # endregion
    # endregion
}
EKS
This wipes an individual file. The question was about wiping all the free space on the hard drive... which contains dellocated/deleted files that could be recovered by some 3rd party.
Paul Sasik
This is for securely overwriting an existing file. He's looking to securely wipe the free space on his drive.
statichippo
This is not what I asked for in the OP but its still very interesting thanks
Crash893
Create a file the size of free space. Or use several files ( If for some reason you cannot fill the entire drive at once).
EKS
A: 
System.Diagonstics.Process.Start("chipher.exe /WC:\");

This is asynchronous by default, you get the idea.

teest1
+2  A: 

This is really dangerous but..

You can use the Defrag APIs (here's a C# wrapper) to get hold of the drive 'map' and specifically target the freespace and write junk to those parts of the disk.

JBRWilkinson
If you fill up all the free space at the same time with files, you might cause problems if anything else tries to write to disk, or virtual memory tries to expand. If you use the Defrag APIs, you can at least clear the free space without causing problems, assuming you do it right.
Dean J