Chapter – 15
Programming for Data Wipers
Introduction
We have already that discussed when we delete any file from the disk, the information is not erased completely from the drive but it is marked as available for new data to be written over it.
When we format a drive, all the information of files and directories of the drive such as FATs and Root Directory Entries are wiped out but data area remains unchanged and nothing from data area of the disk is erased. The data which is deleted or formatted using the operating system remains on the data area as it is and can be recovered with some data recovery efforts and data recovery software.
Therefore the need to fully eliminate data from a drive leads the requirement for such a program that wipes out the data from the disk completely. For doing this it is not sufficient to just delete the files or just to format the drive but the data on the disk must be overwritten by some other data.
The programs which are used to wipe out the data completely from the disk are known as the data wiping programs. These programs write random characters on the data area to overwrite data and to wipe out all the information previously saved on the disk.
When the data becomes completely unrecoverable
To wipe out the data, the data area of the disk should be overwritten by some other data on it but the problem does not end here. To further complicate things, the tendency of magnetic drives to remember data that has been overwritten requires that data also be over-written several times by random sequences of data so that it may not be recovered even with sophisticated data recovery tools
It is so because the technologies which can recover data even after the use of some simple data wipers are available today.
Some data erasure products perform binary zeros and binary ones overwriting on data. Writing a series of binary zeros and binary ones achieves the deepest overwrite effect as these values are the minimum and maximum magnetic values respectively.
Although this is the theory of an ideal data wiping program, but generally, the data over writing by random ASCII character is sufficient. The reason to say so is that the recovery by sophisticated recovery tools and technology can not be used to recover the data of any organization for a routine data recovery because these technologies are very much expensive and cost in millions even for single recovery. Not only this but also these technologies are available only in few countries around the world.
We shall discuss only the simple data overwriting to wipe the data from the disk. However you can further modify the same programs to write the random characters only with some little efforts. Data wiped out by this idea can also not be recovered by any data recovery software.
Why data wiping is so important
When we discuss about the data recovery techniques we assure the user that the data can be recovered with some general or some specific data recovery efforts. But data recovery is not always a desired and expected feature for everyone.
There may be a lot of people or organizations that are always willing to erase the data of their disk in such a way that it should not be recovered by any how. In such cases very sensitive data might previously stored on the disk, which if goes in wrong hands may harm the organization or user by misusing the information.
As we know that the requirement of more and more space in hard disks is increasing day by day. As the result of this, the older small capacity drives are replaced by new large capacity disks on a large scale every year in almost every organization. If these older disks are got by some wrong hands, it may create a very serious problem for that organization.
According to news published by CNET News.com, on January 16, 2003, Massachusetts Institute of Technology students Simon Garfinkel and Abbi Shelat have been purchasing old hard drives, in the name of research, from the Web and other second-hand sales to uncover the huge amounts of personal information people do not bother to erase.
After buying 158 drives for around US$1000, they managed to collect over 5000 credit card number, medical records, detailed personal and corporate financial information and several gigabytes of e-mails, source codes and other information.
The pair of these students has compiled their findings into a report entitled "Remembrance of Data Passed: A Study of Disk Sanitation" published in the February edition of IEEE Security and Privacy.
The main points that have come out of the research are that the second-hand market for hard drives is filled with personal information making it very easy for a malicious buyer to assume the identity of someone else.
Writing program for Non–Destructive data wiper
The non-destructive data wiper is a kind of data wiping program by using which we can wipe out the entire “unallocated space” of the disk volume, without harming the data which is stored in disk, in any way.
The scope of such data wiper is in the cases, where you want to wipe out all the unallocated space of the disk volume while the allocated data stored in the volume should remain untouched. This type of data wiping program also wipes out the data area of deleted files.
The program coding for a type of non – destructive data wiping program has been given next:
///// Program for a Non Destructive Data Wiper \\\\\
#include <stdio.h>
unsigned int file_num=0; /* Provides File Number
During the Auto Creation
of Temporary Data files */
float status=0; /* How Much Disk space is
still Written */
static char dbuf[40000]; /* Data Buffer to write
Temporary Files with */
char file_extension[5]=".ptt";/* Unique Extensions for
Temporary Files */
char temp[5]; /* File Number converted to
String */
char filename[40]; /* Temporary File name */
void main()
{
unsigned int i=0;
clrscr();
while(i<40000)
{
dbuf[i] = ' ';
i++;
}
gotoxy(10,14);cprintf(" MB Still Written...");
while(1)
{
/* Logic to create temporary files automatically with unique name */
strcpy(filename,"TTPT");
itoa(file_num,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
file_num++;
write_to_temp(filename);
}
} //// End of Main \\\\
///// Function to write the data to temporary file \\\\\
write_to_temp(char *filename)
{
unsigned int i, count=1;
float buf_status=0;
FILE *tt;
if((tt=fopen(filename,"wb"))==NULL)
{
fclose(tt);
printf("\n Error occurred while creating temporary
file, ");
printf("\n Removing temporery Files After KEY BOARD
HIT");
getch();
remove_temp_file();/* Remove All temporary files */
}
while(1)
{
for(i=0;i<50;i++)
{
fprintf(tt,"%s",dbuf);
}
buf_status = (float)((40000*50*count)/512);
status= status+(40000*50);
count++;
gotoxy(10,14);
cprintf("%.0f",(float)(status/1000000));
if(kbhit())
{
fclose(tt);
printf("\n Removing Temporery Files, Please
Wait...");
remove_temp_file();
}
if(buf_status>=10000)
{
fclose(tt);
return;
}
}
}
/* Function to Delete the Temporary files automatically */
remove_temp_file()
{
int i=0;
for(i=0;i<=file_num;i++)
{
strcpy(filename,"TTPT");
itoa(i,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
remove(filename);
}
exit(1);
return 0;
}
Comments on logic and the coding of the program:
In this program basically we follow the following two steps to wipe the unallocated space of the disk:
- Create temporary data files automatically: First we create temporary files with unique names and having some data in them until the disk volume is full with these temporary data files. By doing this, all the unallocated data area of the logical drive is occupied by the data of the temporary files and all unallocated data is overwritten.
For doing this, I chose the names of temporary files in the TTPTxxxx.PTT format, which means, the first four characters of the temporary files are TTPT and the extension of the files is .PTT. It is done so to provide the temporary files the unique filenames.
I have set the maximum size of the single temporary file, equivalent to approximately 11,718 sectors data however you can define it according to you. I chose space character “ ” (ASCII character 32) to fill the data in temporary files. However random characters may also be used instead of space.
- Remove all temporary files: When the logical drive is full with temporary files, it indicates that all the unallocated data area is now overwritten. Now all the temporary files created by the program are removed automatically. And thus wiped out unallocated space is achieved.
In the coding of the program, the character array filename stores the file name to generate temporary files automatically, with different names.
The function write_to_temp(filename); fills the temporary file up to 11,718 sectors (because there is no occurrence of 10,000 sectors in specified group writing of buffer) equivalent data with help of data buffer dbuf of 40,000 bytes. 50 times data buffer is written at a time to speed up the writing.
The temporary files are created until the disk volume is full and file creation error occurs. The function remove_temp_file() removes all temporary file, created by the program.
In this way all the unallocated space is wiped out without harming the data of the disk volume.
Writing program for Destructive Data Wiper:
Destructive data wiping programs are those which write directly on the surface of the disk. This type of data wiping programs work on lower level than file system and operating system, which means that all the data and other logical information including OS, File systems, Directory entry and everything written on the disk is wiped out.
These data wiping programs directly wipe the sectors of the surface of the disk, and wipe out everything written on it. As all the data of the disk including operating system is lost, these programs as called destructive data wiping programs.
These types of wiping programs are preferred in such cases, where user is willing to overwrite everything on the disk, including Operating system and all the data on the disk.
However there are some more benefits of this type of data wiping programs. As these destructive data wiping programs work completely free from OS and File system and write directly on the surface of the disk, they are reasonably faster than the non-destructive data wipers.
Also, if any how logical bad sectors on the disk are created due to illegal storage of some random data, these logical bad sectors are also wiped out completely with the data of the disk.
The coding for a destructive data wiping program has been given next. The program has been written to support large size disks too. The program wipes the data of second physical hard disk connected to the computer.
///// Coding for a destructive data wiping program \\\\\
#include<stdio.h>
#include<dos.h>
/* Structure to be used by getdrivegeometry function using INT 13H Extension, Function Number 0x48. */
struct geometry
{
unsigned int size ; /* (call) size of Buffer */
unsigned int flags ; /* Information Flags */
unsigned long cyl ; /* Number of Physical Cylinders on
Drive */
unsigned long heads ;/* Number of Physical Heads on
Drive */
unsigned long spt ; /* Number of Physical Sectors Per
Track */
unsigned long sectors[2] ; /* Total Number of
Sectors on Drive */
unsigned int bps ; /* Bytes Per Sector */
} ;
/* Structure of Disk Address packet format, To be used by the writeabsolutesectors Function */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet,
generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to
Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
///// Function to get Drive Parameters \\\\\
unsigned long getdrivegeometry (int drive)
{
union REGS i, o ;
struct SREGS s ;
struct geometry g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
i.h.ah = 0x48 ; /* Function Number 0x48 of INT 13H
Extensions */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Invoke the specified function number of INT 13H extension with Segment Register Values */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder =
%lu\n",
g.heads,g.spt,g.cyl);
/* If get drive Geometry function Fails, Display Error Message and Exit */
if(g.spt==0)
{
printf("\n Get Drive Geometry Function Fails....");
printf("\n Extensions Not Supported, Press any Key to
Exit...");
getch();
exit(1);
}
return *g.sectors; /* Return The Number of
Sectors on Drive */
}
void main()
{
unsigned long loop=0, Sectors_in_ HDD2=0;
unsigned char buffer[61440]; /* Data buffer of 61440
bytes Equivalent to
120 Sectors */
unsigned long i=0;
char choice;
clrscr();
/* If total no. of hard disks attached is less then two Display Error Message and Exit. */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n You Must Have At least Two Hard Disks
Attached to your Computer To Run This");
printf("\n Program. This Program has been developed
to Wipe the Data of Second Hard Disk.");
printf("\n Press any Key to Exit... ");
getch();
exit(1);
}
Sectors_in_HDD2 = getdrivegeometry (0x81);
printf(" Total Sectors in Second Hard Disk =
%lu\n\n",
Sectors_in_HDD2);
///// First Confirm, then Proceed \\\\\
printf("\n It is A Data Wiping Program, and Writes on
the Surface of the Disk,");
printf("\n After running this program, Data can not
be recovered by any Software,");
printf("\n All The Data in Second Hard Disk will be
lost !!!");
printf("\n Press \'Y\' to Continue, Else any key to
Exit... ");
choice = getche();
switch(choice)
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
gotoxy(10,15);cprintf(" Initializing, Please Wait...");
for(i=0;i<61440;i++)
{
buffer[i]='\0';
}
gotoxy(10,15);cprintf(" ");
gotoxy(10,15);
printf("Currently Wiping Absolute Sector: ");
for(loop=0;loop<= Sectors_in_HDD2;loop=loop+120)
{
writeabsolutesectors (0x81, loop, 120, buffer);
gotoxy(44,15); printf("%ld",loop);
if(kbhit())
{
exit(0);
}
///// Display Message when completed \\\\\
printf("\n\n Data wiping is Now Completed, All the Data in
Second Hard Disk is now");
printf("\n Completely Erased, Press any Key to Exit...");
getch();
}
//// Function to Write Absolute Sector(s) \\\\
int writeabsolutesectors ( int drive, unsigned long sectornumber, int numofsectors, void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* Packet Size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ;/* Number of Sectors to
be written */
/* for Data buffer */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to be written*/
pp.blocknumber[1] = 0 ; /* Block number = 0 */
i.h.ah = 0x43 ; /* Function Number */
i.h.al = 0x00 ; /* Write Flags */
i.h.dl = drive ; /* Physical Drive
number */
i.x.si = FP_OFF ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
/* Invoke the specified Function of INT 13H with segment register values */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; //failure
else
return 1 ; // success
}
Comments on coding:
The structure geometry is used by getdrivegeometry function using INT 13H Extension, Function Number 0x48 to get the various parameters of the disk.
The structure diskaddrpacket is for Disk Address packet format, to be used by the writeabsolutesectors Function.
The Function getdrivegeometry (int drive) is to get Drive Parameters of the disk specified physical drive number drive. buffer [61440] is the data buffer of 61440 bytes, Equivalent to 120 Sectors.
(char) peekb(0x0040, 0x0075) is used to find the number of hard disks connected to the computer, stored at memory location represented by segment 0040H:offset 0075H. If total number of hard disks attached is less then two Display Error Message and Exit.
writeabsolutesectors ( 0x81, loop, 120, buffer ) function is used to write the data of data buffer on 120 sectors at a time starting from the absolute sector number specified by loop.
I chose ‘\0’ (NULL character, ASCII code 0) to write on the sectors to overwrite the data. However you can use random characters to overwrite the data.
For detailed description on Functions writeabsolutesectors and getdrivegeometry refer the chapters given earlier in this book.
Wiping Data Area of specific file
We discussed about the data wiping programs which wipe the data of unallocated space of the disk or wipe the entire disk. But if user is willing to wipe the data every time when he deletes the data, it may be a time taking process to wipe the entire unallocated space of the disk.
We need this type of data wiping programs to wipe the data area only occupied by that particular file. For doing this, we get the help from FAT and Root directory entries, to find the data area occupied by that particular files
Even in case of floppy, if the data is not fragmented, we can do so only with the help of Root directory information. The Following table shows the information stored by a root directory entry with 32 bytes, for any file:
As we see in the table of contents of root directory entry, we are capable to find the starting and ending cluster of the files. The first Byte of the filename may also contain some important information about file. The information given by this byte may be one of the given below:
Let us try this information to wipe the data of any file stored in 1.44Mb, 3 ½ inch floppy disk, with the help of root directory information. Assuming that the data in the floppy disk is not fragmented, the program given next wipes the data of specified file from its data area:
/* Program to wipe the data area of specified file in floppy disk */
#include<stdio.h>
#include<dos.h>
///// Structure to read 32 bytes of File Entry in Root Directory \\\\\
struct root
{
unsigned char filename[8]; /* File name Entry of
8 Bytes */
unsigned char extension[3]; /* Extension of File of
3 Bytes */
unsigned char attribute; /* File Attribute Byte */
unsigned char reserved[10]; /* Reserved Bytes 10 */
unsigned int time; /* Time, 2 Bytes */
unsigned int date; /* Date, 2 Bytes */
unsigned int starting_cluster;/* Starting Cluster of File,
2 Bytes */
unsigned long file_size; /* File Size in Bytes,
4 Bytes */
};
/* Should be taken this to read all Root Directory Entries */
//struct root entry[224];
/* Structure to read all 16 File entries in one Sector of Root Directory */
struct one_root_sector
{
struct root entry[16];
};
struct one_root_sector one;
void main()
{
int result, i, num_sectors,j;
char wipe_buf[512]; /* Data Buffer to be used to wipe
out the data Area of file */
clrscr();
result= absread(0x00, 1, 19, &one); /* Read Absolute Sector
19 (First Sector of Root Directory) */
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
/* Display Files' Information after Reading from Root Directory */
printf(" FILE NO. FILENAME EXTENSION STARTING CLUSTER
FILESIZE \n\n");
for(i=1;i<16;i++)
{
printf("\n %5d %8.8s %3.3s %5u %10lu ",
i, one.entry[i].filename, one.entry[i].extension,
one.entry[i].starting_cluster, one.entry[i].file_size);
}
//// Get User Input To Delete The File \\\\
printf("\n\n Enter The File Number, you Want to Delete and
Wipe out Completely ");
scanf("%d", &i);
if(i<1 || i>15)
{
printf(" \"%d\" is an Invalid Choice..., Press any
Key to Exit...", i);
getch();
exit(1);
}
///// First Confirm, Then Continue \\\\\\
printf("\n You are About to wipe-out,
The File \"%.8s.%s\"",
one.entry[i].filename,
one.entry[i].extension);
printf("\n Do you Want to Continue...(Y/N) ");
switch(getche())
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
///// Calculate The Size of File in Sectors \\\\\
num_sectors = one.entry[i].file_size/512;
if((one.entry[i].file_size%512)>0)
{
num_sectors = num_sectors+1;
}
/* Data buffer of 512 bytes with 512 NULL characters */
for(j=0;j<512;j++)
{
wipe_buf[j] = '\0';
}
///// Starting Sector of the File \\\\\
j= one.entry[i].starting_cluster+31;
/* Wipe out the data Area Until the Sectors of file End */
while(j!=(one.entry[i].starting_cluster +
num_sectors+31) )
{
if((abswrite(0x00, 1, j, &wipe_buf))!=0)
{
printf("\n Error Writing on Disk Sectors");
getch();
exit(0);
}
j++;
}
printf("\n\n File \"%.8s.%.3s\" Deleted !!!" ,
one.entry[i].filename,
one.entry[i].extension);
one.entry[i].attribute = 0; /* Set the File Attribute
to 0 */
one.entry[i].time = 0; /* Wipe The Time information
of File */
one.entry[i].date = 0; /* Wipe The Date information
of File */
one.entry[i].starting_cluster = 0; /* Set the Starting cluster to 0
*/
one.entry[i].file_size = 0; /* Set the file Size to 0 */
one.entry[i].filename[0]=0xE5; /* Give the Deleted
file Status to the File */
///// Write above information in the root Directory \\\\\\
result= abswrite(0x00, 1, 19, &one);
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
}
Comments on logic and coding of program:
The structure root is used to read 32 bytes of File Entry in Root Directory and Structure one_root_sector reads all 16 File entries in one Sector of Root Directory
If you want to read all the sectors of root directory information you should take it as struct root entry[224]; however I have written the program to analyze the 16 entries of only one sector of root directory.
The Starting Sector of the File has been calculated as follows:
j= one.entry[i].starting_cluster+31;
It is done so because the data area of the 1.44 MB, 3 ½ inch floppy disk starts after the first 32 sectors of the floppy disk. And in the specified capacity floppy disk, one cluster is of one sector.
The following table shows the logical map of 1.44MB, 3½ inch floppy disk:
The out put of the program is displayed as follows:
Here we deleted and wiped the data of file PARTBOOT.C. When we see the contents of the floppy with DIR command, the file PARTBOOT.C is not displayed there. When we further execute the program the entry of the deleted file is showed as follows:
Here, the character “” (0xE5), represents that the file has been deleted. (see the table for First Character of File Name).
If you want to write the same program for hard disk drive, you must also use the FAT with root directory to get the information of the data area of any file.
It is so because, the rate of fragmented data in the hard disk drives, increases with time as the older files are deleted and new file are created. Then it is not necessary for all the data clusters of any file in the drive to stay one after one continuously in the data area. By accessing FAT, you can access all of those clusters.
Page Modified on: 18/01/2022