Hosting by Solid Eight Studios,PhotoTangler Collage Maker

This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.


  Hiding A Message In An Image
  Submitted by

This is a small program I whipped up one day when I got curious about steganography. This program will hide a message inside a 24-bit bitmap file and extract it. It's kinda cool because it will use 1-4 of the least significant bits depending on size of the message to hide. Chris

Download Associated File: cryptimage.c (4,928 bytes)

 * 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; }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.


Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.