/*
* Written by Chris Thompson
*
* This code protected under the SPL, Shit Public Licence. It isn't
* worth shit, so if you try to use it for shit and it doesn't do shit,
* then don't tell me about it or else i'll tell you to eat shit.
*
*
*
*
*
*/
#include <stdio.h>
#include <sys/types.h>
void usage()
{
printf("usage: cryptimage <imagefile> [messagefile]\n");
printf("\nIf the \'messagefile\' param is provided, the message is hidden\n");
printf("in 'imagefile' and output to a file called 'out.bmp'. If \n");
printf("\'messagefile\' is not provided, the program will try to extract\n");
printf("a message from \'imagefile\' and write it to out.txt.\n\n");
exit(1);
}
/*
* Encode message into image. msb first
*
*/
void encode(char *image,int imagelen,char *message,int messagelen)
{
int i,j,shift;
int messagebits;
long dataoff;
FILE *c;
unsigned char messagemask,imagemask;
printf("Image of length %d\n",imagelen);
printf("Message of length %d\n",messagelen);
// calculate image size requirements to store
// the message. Try to use least # of bits possible
for (messagebits=1;messagebits<5;messagebits++) {
if (messagebits == 3)
continue;
if (((messagelen+4)*(8/messagebits)+2) < imagelen)
break;
}
if (messagebits == 5) {
printf("You need minimum %d bytes in your image to store your message\n",(messagelen+4)*(8/(messagebits)+2));
}
dataoff = *(long *)(image+10);
printf("Image data starting at offset %d\n",dataoff);
// first 2 bits represent number of bits per byte that are
// message bits.
//
// 00b - 1 bit
// 01b - 2 bits
// 11b - 4 bits
//
printf("Using %d bits per byte for message\n",messagebits);
i=dataoff;
image[i++] = (image[i]&0xFE) | (((messagebits-1))&0x01);
image[i++] = (image[i]&0xFE) | (((messagebits-1)>>1)&0x01);
imagemask = 0xFF << messagebits;
messagemask = imagemask ^ 0xFF;
// next 32 bits represents the message length
printf("Storing message length of %d\n",messagelen);
for (shift=(32-messagebits);shift>=0;i++) {
image[i] = (image[i]&imagemask) | ((messagelen>>shift)&messagemask);
shift -= messagebits;
}
printf("Hiding %d message bytes in %d image bytes\n",messagelen,messagelen*(8/messagebits));
printf("Using message mask of 0x%02X\n",messagemask);
printf("Using image mask of 0x%02X\n",imagemask);
for (j=0,shift=(8-messagebits);j<messagelen;i++) {
image[i] = (image[i]&imagemask) | ((message[j]>>shift)&messagemask);
if (shift == 0) {
shift = (8-messagebits);
j++;
}
else
shift-=messagebits;
}
printf("Opening file for output\n");
c = fopen("out.bmp","w");
fwrite(image,1,imagelen,c);
fclose(c);
}
void decode(char *image,int imagelen)
{
int i,j,shift;
long dataoff;
char *message;
unsigned long messagelen = 0;
int messagebits = 0;
FILE *m;
unsigned char messagemask,imagemask;
printf("Image of length %d\n",imagelen);
dataoff = *(long *)(image+10);
printf("Image data starting at offset %d\n",dataoff);
i = dataoff;
messagebits |= image[i++]&0x01;
messagebits <<=1;
messagebits |= image[i++]&0x01;
messagebits++;
printf("Using %d bits per image byte for message\n",messagebits);
imagemask = 0xFF << messagebits;
messagemask = imagemask ^ 0xFF;
printf("Using message mask of 0x%02X\n",messagemask);
printf("Using image mask of 0x%02X\n",imagemask);
for (shift=(32-messagebits);shift>=0;i++) {
messagelen |= (image[i]&messagemask)<<shift;
shift -= messagebits;
}
printf("Message length of %d\n",messagelen);
message = (char *)malloc(messagelen);
memset(message,0,messagelen);
for (j=0,shift=(8-messagebits);j<messagelen;i++) {
message[j] = message[j] | ((image[i]&messagemask)<<shift);
if (shift == 0) {
shift=(8-messagebits);
j++;
}
else
shift-=messagebits;
}
m = fopen("message.out","w");
fwrite(message,1,messagelen,m);
fclose(m);
}
int main(int argc,char **argv)
{
FILE *file;
char *image=0,*message=0;
int imagelen = 0,messagelen = 0;
int bytesread;
if ((argc != 2) && (argc != 3))
usage();
printf("Opening image file %s...",argv[1]);
file = fopen(argv[1],"r");
fseek(file,0,SEEK_END);
imagelen = ftell(file);
fseek(file,0,SEEK_SET);
image = (char *)malloc(imagelen);
bytesread = fread(image,1,imagelen,file);
printf("read %d bytes.\n",bytesread);
fclose(file);
if (argc != 3)
decode(image,imagelen);
else {
printf("Opening message file %s...",argv[2]);
file = fopen(argv[2],"r");
fseek(file,0,SEEK_END);
messagelen = ftell(file);
fseek(file,0,SEEK_SET);
message = (char *)malloc(messagelen);
bytesread = fread(message,1,messagelen,file);
printf("read %d bytes.\n",bytesread);
fclose(file);
encode(image,imagelen,message,messagelen);
}
free(image);
free(message);
return 0;
}
|