Steganography

//Steg.h
Designed and Implementation: Renjith G


/********************** header file*************************/
#define BUFSIZE 1024 //512
#define DATASIZE 64
#define STARTBYTE 64

/************type definition***********************/
/* typedefs */
typedef unsigned char UBYTE;

/***********struture definition********************/
struct steg_header
{
unsigned long datalen;
char key[10];
};

struct BMPFILEHEADER
{
unsigned char bfType; //2 Bitmap identifier. Must be 'BM'.
unsigned int bfSize; //4 Can be set to 0 for for uncompressed bitmaps, which is the kind we have.
short int bfReserved1;//2 Set to 0.
short int bfReserved2;//2 Set to 0.
unsigned int bfOffbits; //4 Specifies the location (in bytes) in the file of the image data.
// For our 8-bit bitmaps, this will be sizeof(BITMAPFILEHEADER) +
//sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numPaletteEntries.
};


struct BMPINFOHEADER
{
unsigned int biSize; //4 This is the size of the BMPINFOHEADER structure. Thus, it is
//sizeof(BITMAPINFOHEADER).
unsigned int biWidth; //4 The width of the bitmap, in pixels.
unsigned int biHeight; //4 The height of the bitmap, in pixels.
short int biPlanes; //2 Set to 1.
short int biBitCount; //2 The bit depth of the bitmap. For 8-bit bitmaps, this is 8.
unsigned int biCompression; //4 Our bitmaps are uncompressed, so this field is set to 0.
unsigned int biSizeImage; //4 The size of the padded image, in bytes.
unsigned int biXPelsPerMeter; //4 Horizontal resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set to 0.
unsigned int biYPelsPerMeter; //4 Vertical resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set to 0.
unsigned int biClrUsed; //4 This indicates how many colors are in the palette.
unsigned int biClrImportant; //4 This indicates how many colors are needed to display the bitmap. We will set it to 0, indicating all colors should be used.

};
/********************************************************/



//Steg.cpp
Designed and Implementation: Renjith G

/*My Special Thanks to -----Peter Kieltyka----For the Main Idea of hiding Data
on LSB of Bitmap File. New program Modified and designed by renjith.
Creation Date ->Saturday, January 31, 2004, 10:48:42 PM
Last Modification ->Tuesday , March 02 , 2004, 10:44:54 PM
*/
#include "steg.h"
#include
#include
#include
//#include

/**************Function Prototypes*************************/

void MediaInfo(char *);
CheckMediaFile (FILE *);
void Eof(void);
void usage(char *);
int MaxCapacity(unsigned long);
int FileSize(FILE *);
int SteganoHide(char *, char *, char *, char *);
int SteganoExtract(char *, char *, char *);
/*************************Usage()*************************/
void usage(char *argv)
{
fprintf(stderr,
"\n\n"
"usage: \t\t To Hide\n"

"%s \n "
"\n\n"
"usage:\t\t To Extract\n"
"%s \n\n"
"\n\n"
"usage:\t\t To get Information about MediaFile File\n"
"%s <-i> "
"\n\n",argv,argv,argv);
exit(-1);
}
/******************EOF()*********************************/

void Eof(void)
{
puts("Error: End of file encountered - So aborting...\n");
}
/********************************************************/



/*********************************************************/
CheckMediaFile (FILE *fpin)
{
int b;

if ((b = getc (fpin)) == EOF)
Eof();
//printf("b=%d\n",b); /* ren check*/
return (UBYTE) b;
}
/****************Checking MaxCapacity()********************/
int MaxCapacity(unsigned long fsize)
{
return((fsize-STARTBYTE)/8);

}
/***************FileSize()***********************************/
int FileSize(FILE *fp)
{
unsigned long fsize;

(void)fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
(void)fseek(fp, 0, SEEK_SET);
return(fsize);
}
/**********************************************************/
void MediaInfo(char *fin)
{

struct BMPINFOHEADER bmih;
FILE *fpin;
long int hresol,vresol;
unsigned long int value;

if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}

switch (CheckMediaFile (fpin))
{
case 'M':
break;
case 'A':
puts ("File is probably an OS/2 bitmap ARRAY.\n");
fclose(fpin);
break;

case 'B':
{
puts("\n\n");
puts("File is Probably a Bitmap!\n");
puts("Media File Information\n");
rewind(fpin); /*set file pointer to beginning
please refer linux man pages */
fseek(fpin,14,SEEK_SET);
fread(&value,4,1,fpin);
printf("Bitmap Type -->");
switch(value)
{
case 12:
puts(" Bitmap of OS/2 (1)");
break;
case 40:
puts(" Windows Bitmap");
break;
case 64:
puts(" Bitmap of OS/2 (2)");
break;
default:
puts(" Unknown Type");
break;
}
////////////////////////////////printf("VALUE =%ld\n",value);
rewind(fpin);
fseek(fpin,14,SEEK_SET);

fread(&bmih,sizeof(bmih),1,fpin);

printf("Size of %s = %dKB\n",fin,bmih.biSizeImage/1024);
printf("Width of Bitmap File = %d\n", bmih.biWidth );
printf("Height of Bitmap File = %d\n", bmih.biHeight);
hresol = bmih.biXPelsPerMeter/39.3700787401;
vresol = bmih.biYPelsPerMeter/39.3700787401;
printf("Horizontal Resolution = %ld dpi\n",hresol);
printf("Vertical Resolution = %ld dpi\n",vresol);
switch(bmih.biBitCount)
{
case 1:
puts ("Monochrome Image 1bit (2 color)\n");
break;
case 4:
puts ("VGA Image ->4bit (16 color)\n");
break;
case 8:
puts ("SVGA or greyscale ->8bit (256 color)\n");
break;
case 16:
puts ("High Color ->16bit (65536 colour)\n");
break;
case 24:
puts ("True Color ->24bit (16.7 Mio colour)\n");
break;
default:
printf ( "Unknown color depth = %i\n",bmih.biBitCount );
} /*End o 2nd switch*/
if(bmih.biCompression != 0) /*Refer 6th field of BMPinfoHeader structure */
printf("BitMap File <%s> is Compressed\n",fin);
else
printf("Bitmap File <%s> is UnCompressed\n",fin);

}
fclose(fpin);
// printf("file closed");

} /*End of 1st switch*/

}

/***********************SteganoHide()***********************/
/* notes:- when hiding:
a = (a & ~1) | (((b >> (7-k)) & 1) & 1);

this takes the bit of byte 'b' at location 'k' (k goes from 0-7, 0 being the LSB)
and stores it in the LSB of byte 'a'

*/

int SteganoHide(char *fin, char *fout, char *fdata, char *key)
{
FILE *fpin, *fpout, *fpdata;
unsigned long media,fhide;
struct steg_header steg = {0};
char data[DATASIZE];
char buf[BUFSIZE];
int c,n,i,k,x,j,h;
int mediatype;
int count;/*Media file Type */
if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}
if((fpout = fopen(fout, "wb")) == NULL)
{
fprintf(stderr, "Error! Cannot open output file!\n");
exit(-1);
}
if((fpdata = fopen(fdata, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open %s!\n", fdata);
exit(-1);
}

mediatype = CheckMediaFile (fpin);
if(!(mediatype == 'B'))
{
printf("GETSREGABYTE = %d\n",mediatype);
fprintf(stderr, "Error! %s ->s Not a BITMAP File!\n", fin);
exit(-1);
}
media = FileSize(fpin);
fhide = FileSize(fpdata);

//if(MaxCapacity(FileSize(fpin)) < FileSize(fpdata))
if(MaxCapacity(media) < fhide)
{
printf("\nMedia size = %ld\n",media);
printf("File-to-Hide = %ld\n",fhide);
fprintf(stderr, "Error!! Hiding File %s will not fit in %s, %d Bytes Capacity!\n",
fdata,fin, MaxCapacity(media));
return(-1);
}

steg.datalen = FileSize(fpdata);
memcpy(steg.key, key, sizeof(steg.key));
puts("Please wait while Hiding............");
x = 0;
k = 0;
j = 0;
i = STARTBYTE;
h = sizeof(steg);
count=0;

while(n = fread(buf, 1, sizeof(buf), fpin)) /* total no of bytes read = size(buf) * 1 */
{
if(x != 0)
i = 0;

while(i < n)
{
if(j <= 0)
{
c = 0;
memset(data, 0, sizeof(data)); /* returns data */
j = fread(data+h, 1, sizeof(data)-h, fpdata);
// j = fread(data, 1, sizeof(data), fpdata);
// printf("j==================%d\n",j);

if(h != 0)
{
j += h;
memcpy(data, &steg, sizeof(steg));
h = 0;
}
}

if(j > 0)
{
printf("count=%d\n",count);
printf("the val buf[%d] =%d\n",i,buf[i]);
printf("The data[%d] =%d\n",c,(((data[c] >> (7-k)) & 1) & 1));


// printf("i=%d \t c=%d\n",i,c);

buf[i] = (buf[i] & ~1) | (((data[c] >> (7-k)) & 1) & 1);
printf("the val buf[%d] =%d\n\n\n",i,buf[i]);
count=count+1;

// getch();

k++;
//printf("buff %c\n",buf[i] );
if(k > 7)
{
k = 0;
c++;
j--;
}
}

i++;
} /* End Of While */

fwrite(buf, 1, n, fpout);
x += n;
}

fclose(fpin);
fclose(fpout);
fclose(fpdata);

return(0);
}

/****************Stegano Extraction()********************/
/* note to follow:- when extracting:
a = (a & ~(1 << (7-k))) | ((b & 1) << (7-k));

this assigns 'a' the LSB of 'b' to location 'k' (k goes from 0-7, 0 being the LSB)
*/
int SteganoExtract(char *fin, char *fout, char *key)
{
FILE *fpin, *fpout;
struct steg_header steg = {0};
char buf[BUFSIZE], data[DATASIZE], c;
int done,n,x,i,k,j;

if((fpin = fopen(fin, "rb")) == NULL)
{
fprintf(stderr, "Error! Cannot open input file!\n");
exit(-1);
}
if((fpout = fopen(fout, "wb")) == NULL)
{
fprintf(stderr, "Error! Cannot open output file!\n");
exit(-1);
}


// Get header
x = 0;
j = 0;
k = 0;
done = 0;
puts("Please wait while Extracting............");
memset(data, 0, sizeof(data));
while((n = fread(buf, 1, sizeof(buf), fpin)) && done == 0)
{
if(x == 0)
i = STARTBYTE;
else
i = 0;

while(i < n)
{
if(j < sizeof(steg))
{
data[j] = (data[j] & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;

if(k > 7)
{
k = 0;
j++;
}
}
else
{
done = 1;
break;
}

i++;
} /*end of While */

x += n;
}
memcpy(&steg, data, sizeof(steg));
(void)fseek(fpin, 0, SEEK_SET);

// Check key's
if(strcmp(steg.key, key))
{
printf("Incorrect Key! No data for you!\n");
fclose(fpin);
fclose(fpout);
return(-1);
}

// Get data
x = 0;
k = 0;
j = steg.datalen;
i = STARTBYTE+(sizeof(steg)*8);
while(n = fread(buf, 1, sizeof(buf), fpin))
{
if(x != 0)
i = 0;

while(i < n)
{
c = (c & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;

if(k > 7)
{
k = 0;
j--;
if(j >= 0)
fputc(c, fpout);
}

i++;
}

x += n;
}

fclose(fpin);
fclose(fpout);

return(0);
}

/********************Main()******************************/

int main(int argc, char **argv)
{
///int c; /////////////////////////
if(argc <> 5)

usage(argv[0]);
if(argc == 3)
{
if(strcmp (argv[1],"-i") == 0)
{
//puts("in hai");
MediaInfo(argv[2]);
exit(-1);
}
else
puts("out hai");
usage(argv[0]);
exit(-1);
///////////////////////////srecmp(argv[2],"-i")==0?usage(argv[0]):exit(-1));
}
if(argc == 4)
{
if(strlen(argv[3]) > 10)
{
printf("Sorry, the key cannot be greater then 10 characters long!\n");
exit(-1);
}

SteganoExtract(argv[1], argv[2], argv[3]);
}
else
{
if(strlen(argv[4]) > 10)
{
printf("Sorry, the key cannot be greater then 10 characters long!\n");
exit(-1);
}

SteganoHide(argv[1], argv[2], argv[3], argv[4]);
}
exit(0);
}
/**********************end of main()************************/






2 comments:

geofrey said...

Hey This does not work ..can you please send me the one which work I am learning stegonagraphy just begginer , jellyforjully088@yahoo.com my email ,

geofrey said...

Hey This does not work ..can you please send me the one which work I am learning stegonagraphy just begginer , jellyforjully088@yahoo.com my email ,