All pastes #470913 Raw Edit

Hide

public c v1 · immutable
·published 2007-05-04 16:24 UTC
rendered paste body
/*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>#define M_UNDEFINED 0#define M_HIDE 1#define M_UNHIDE 2void usage(){	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];	int srcsize, destsize;		// Count the bytes...!	fseek(srcfile, 0, SEEK_END);	fseek(destfile, 0, SEEK_END);	srcsize = ftell(srcfile);	destsize = ftell(destfile);		// Rewind both files then.	fseek(srcfile, 0, SEEK_SET);	fseek(destfile, 0, SEEK_SET);		// 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 function 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;	char *srcname = NULL, *destname = NULL;	int skip_options = 1; // Skip the program name by default.	int c;	int mode = M_UNDEFINED;		// Scan the arguments.	for (c = skip_options; c < argc; c++)	{		if (!strcmp(argv[c], "--help") || !strcmp(argv[c], "-h") || !strcmp(argv[c], "-?"))		{			usage();						return 0;		}				// Unparsed option! Start whinign if it is one...		if (argv[c][0] == '-')		{			// Cancel argument parsing (just tell the user about more unknown			// options).			fprintf(stderr, "hide: unrecognized option %s\n", argv[c]);			mode = M_UNDEFINED;			skip_options = argc;		}	}		if ((argc - skip_options) == 2)	{		// Assume there are two filenames specifying the source and destination		// file.		mode = M_HIDE;				// This is no mistake. There is no need to waste memory by copying		// that string.		srcname = argv[skip_options + 0];		destname = argv[skip_options + 1];	}		if ((argc - skip_options) == 1)	{		// Assume there is one filename specifying the file to be decoded.		mode = M_UNHIDE;				// This is again no mistake!		srcname = argv[skip_options + 0];	}		// For some reasons it can be useful to not force any filenames to be	// specified (just think of --help). So scan them, if any.	if (srcname != NULL)	{		srcfile = fopen(srcname, "r");		if (srcfile == NULL)		{			perror("hide: Error opening source file");			return 1;		}				if (destname != NULL)		{			destfile = fopen(destname, "r");			if (destfile == NULL)			{				perror("hide: Error opening destination file");				fclose(srcfile);				return 1;			}		}	}		switch (mode)	{		case M_UNDEFINED:			// This mostly means argument errors. Yell it out to the poor user!			fprintf(stderr, "hide: Not enough or wrong arguments\n");			fprintf(stderr, "Use the '--help' option to get a list of available options.\n");			return 1;						break;		case M_HIDE:			// Output to the output file. (It's stdout for now.)			return hide(srcfile, destfile, stdout);						break;		case M_UNHIDE:			// Dump the hidden file to the output file. (It's stdout for now.)			return unhide(srcfile, stdout);						break;	}}