/*Hide - A little tool to hide data in image files from noobsCopyright (C) 2007 Lars Stoltenow <penma@penma.de>This program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 51 FranklinSt, Fifth Floor, Boston, MA 02110, USA*/#include <stdio.h>void usage(){ // FIXME: Replace with some getopts calls, same with argument parser. fprintf(stderr, "Usage:\n" "\thide [ <options> ] <srcfile> <destfile>\n" "\thide [ <options> ] <srcfile>\n" "\n" "<srcfile> specifies the file that's to be embedded in <destfile>, or\n" "the file where embedded data should be extracted from.\n" "\n" "Available options:\n" "\t--help or -h or -? Show this help message.\n" );}int hide(FILE *srcfile, FILE *destfile, FILE *outfile){ unsigned char srcbyte, destbytes[4]; // Read bytes from destination file until the end is reached. do { // Check if the source file has still bytes to offer, if not, include // null bytes (I think they always fit). :) if (feof(srcfile)) { srcbyte = 0x00; } else { fread(&srcbyte, 1, 1, srcfile); } // Read 4 bytes from the destination file to include the data there. fread(destbytes, 1, 4, destfile); // Empty the lower 2 bits. destbytes[0] &= 0xfc; destbytes[1] &= 0xfc; destbytes[2] &= 0xfc; destbytes[3] &= 0xfc; // Include the bits from the source file. destbytes[0] += (srcbyte >> 0) & 0x03; destbytes[1] += (srcbyte >> 2) & 0x03; destbytes[2] += (srcbyte >> 4) & 0x03; destbytes[3] += (srcbyte >> 6) & 0x03; // Write out the new data. fprintf(outfile, "%c%c%c%c", destbytes[0], destbytes[1], destbytes[2], destbytes[3]); } while (!feof(destfile)); // Make sure the files are closed! The calling unction won't do this. fclose(srcfile); fclose(destfile); return 0;}int unhide(FILE *srcfile, FILE *outfile){ unsigned char srcbytes[4]; // Go through the file and push bits to the output. do { // Get new bytes! fread(srcbytes, 1, 4, srcfile); // And write them to the output! fprintf(outfile, "%c", (srcbytes[0] & 0x03) | ((srcbytes[1] & 0x03) << 2) | ((srcbytes[2] & 0x03) << 4) | ((srcbytes[3] & 0x03) << 6)); } while (!feof(srcfile)); // Make sure the file gets closed! The calling routine won't do this for us. fclose(srcfile); return 0;}int main(int argc, char *argv[]){ FILE *srcfile, *destfile; if ((argc == 2) && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") || !strcmp(argv[1], "-?"))) { usage(); return 0; } if (argc == 3) { // Assume there are two filenames specifying the source and destination // file. srcfile = fopen(argv[1], "r"); if (srcfile == NULL) { perror("hide: Error opening source file"); return 1; } destfile = fopen(argv[2], "r"); if (destfile == NULL) { perror("hide: Error opening destination file"); fclose(srcfile); return 1; } // Output to the output file. (It's stdout for now.) return hide(srcfile, destfile, stdout); } if (argc == 2) { // Assume there is one filename specifying tzhe file to be decoded. srcfile = fopen(argv[1], "r"); if (srcfile == NULL) { perror("hide: Error opening source file"); return 1; } // Dump the hidden file to the output file. (It's stdout for now.) return unhide(srcfile, stdout); } // Reaching here mostly means argument errors. Yell it out to the poor user! fprintf(stderr, "hide: Not enough arguments\n"); fprintf(stderr, "Use the '--help' option to get a list of available options.\n"); return 1;}