This commit is contained in:
BlackLight 2009-07-13 18:55:12 +02:00
commit 0318bbbf33
13 changed files with 697 additions and 0 deletions

4
AUTHORS Normal file
View file

@ -0,0 +1,4 @@
Author: BlackLight
Mail: blacklight@autistici.org
Web: http://0x00.ath.cx | http://blacklight.gotdns.org

5
BUGS Normal file
View file

@ -0,0 +1,5 @@
Sometimes the last two bytes or the last byte of the text is truncated
in decode operations. I don't know if it's my fault, as this bug seems
to happen almost in random strings of random length, or zLib's fault.
I'll try to fix anyway.

18
INSTALL Normal file
View file

@ -0,0 +1,18 @@
* PREREQUISITES
> You must have CImg libraries <http://cimg.sourceforge.net/> installed on your
system in order to compile and use Jastegal. These libraries are used for a
high-level wrapping of image managing.
> You also must have zlib installed on your system. zlib is installed almost
anywhere, and it's use by Jastemal for compression/uncompression operations.
* INSTALLATION
> To install Jastegal on your system you need, of course, g++ and gmake already
installed. Then, just type:
$ make
% make install

30
LICENCE Normal file
View file

@ -0,0 +1,30 @@
The files in this directory and elsewhere which refer to this LICENCE
file are part of Jastegal (Just Another Steganography algorithm)
Copyright (C) 2009 BlackLight
Jastegal is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 or (at your option) any later
version.
Jastegal is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Jastegal; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from these files, or you compile these
files and link them with other works to produce a work based on these
files, these files do not by themselves cause the resulting work to be
covered by the GNU General Public License. However the source code for
these files must still be made available in accordance with section (3)
of the GNU General Public License.
This exception does not invalidate any other reasons why a work based on
this file might be covered by the GNU General Public License.

30
Makefile Normal file
View file

@ -0,0 +1,30 @@
CXX=g++
CFLAGS=-Wall -pedantic
LDFLAGS=-lX11 -lpthread -lm -lz
INSTALLDIR=/usr/local
NAME=jastegal
FILES=utils.o jastegal.o encode.o decode.o compress.o
ifeq (${DEBUG},1)
CFLAGS += -g3
endif
all: $(FILES)
${CXX} ${LDFLAGS} -o ${NAME} ${FILES}
$(FILES): $(FILES:.o=.cpp)
${CXX} ${CFLAGS} -c $*.cpp
install:
mkdir -p ${INSTALLDIR}/bin
install -m 0755 ${NAME} ${INSTALLDIR}/bin
clean:
rm ${FILES}
rm ${NAME}
uninstall:
rm -f ${INSTALLDIR}/bin/${NAME}

21
README Normal file
View file

@ -0,0 +1,21 @@
Jastegal (Just Another Steganography Algorithm) v.0.1b
c0ded by BlackLight <blacklight@autistici.org>
Usage: ./jastegal [-d|-e] <-i image file> [-o output image file] [-f file to be steganographied]
-d: Perform a decoding from an image
-e: Perform an encoding to an image
-i: Specify the input image to be processed. In case of decoding, the content of this file will be de-steganographied,
while in case of encoding this is the image to steganography from
-o: Specify the output image. This parameter is mandatory in encoding phase, as it specifies the file name containing
the image with the steganographied data
-f: Specify, in encoding phase, the file containing data to be steganographied. If this option is not specified, the
data will be gathered via stdin
Examples:
jastegal -e -i input_image.png -o output_image.png -f file.txt
This will encode the data in file.txt using input_image.png as image, and putting the output in output_image.png
jastegal -d -i input_image.png
This will decode the data in input_image.png to stdout

2
TODO Normal file
View file

@ -0,0 +1,2 @@
Support for base64 output and text cryptography (coming, I hope, *VERY* soon).

78
compress.cpp Normal file
View file

@ -0,0 +1,78 @@
/*
* jastegal.h
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#include <iostream>
#include <string>
#include <zlib.h>
using namespace std;
char* zCompress (char* uncompressed, unsigned int uLen, unsigned int &cLen) {
char *compressed = new char[uLen+10];
if (!compressed)
return NULL;
if (compress((Bytef*) compressed, (uLongf*) &cLen, (Bytef*) uncompressed, uLen) < 0)
return NULL;
return compressed;
}
char* zUncompress (char* compressed, unsigned int cLen, unsigned int &uLen) {
uLen = cLen;
int ret = 4;
char *uncompressed = NULL;
while ((uLen < 4000000) && (ret != Z_OK)) {
if (uncompressed)
delete [] uncompressed;
uncompressed = new char[uLen+10];
if (!uncompressed)
return NULL;
ret = uncompress((Bytef*) uncompressed, (uLongf*) &uLen, (Bytef*) compressed, cLen);
if (ret == Z_MEM_ERROR || ret == Z_BUF_ERROR)
return NULL;
if (ret != Z_OK)
uLen *= 2;
}
return uncompressed;
}

86
decode.cpp Normal file
View file

@ -0,0 +1,86 @@
/*
* decode.cpp
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#include <CImg.h>
#include <string>
#include "jastegal.h"
using namespace std;
using namespace cimg_library;
string steganoDecode (string inImg) {
CImg<u8> img(inImg.c_str());
rgb header[8];
string content;
unsigned int uLen, size = 0;
for (unsigned int i=0; i < 8; i++) {
header[i].r = img[3*i];
header[i].g = img[3*i + 1];
header[i].b = img[3*i + 2];
}
for (unsigned int i=0; i < 8; i++) {
size |= ((header[i].r & 0x3) << (i*4));
size |= ((header[i].b & 0x3) << ((i*4)+2));
}
for (unsigned int i=6*sizeof(unsigned int); i < 6*(size + sizeof(unsigned int)); i+=6) {
rgb couple[2];
u8 buf = 0;
for (unsigned int j=0; j<2; j++) {
couple[j].r = img[i + 3*j];
couple[j].g = img[i + 3*j + 1];
couple[j].b = img[i + 3*j + 2];
}
buf =
( ((couple[0].r & 0x3) << 6) |
((couple[0].b & 0x3) << 4) |
((couple[1].r & 0x3) << 2) |
((couple[1].b & 0x3)) );
content += buf;
}
char *uncompressed = zUncompress((char*) content.c_str(), size, uLen);
if (!uncompressed)
return string("");
return string(uncompressed);
}

120
encode.cpp Normal file
View file

@ -0,0 +1,120 @@
/*
* encode.cpp
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#include <CImg.h>
#include <iostream>
#include <string>
#include <vector>
#include "jastegal.h"
using namespace std;
using namespace cimg_library;
int steganoEncode (string inImg, string outImg, string fname) {
CImg<u8> img(inImg.c_str());
string::iterator ch;
string content = fileContent(fname);
unsigned int i, j, k, cLen, size = (fname.empty()) ? content.size() : fileSize(fname);
char *compressed = zCompress((char*) content.c_str(), size, cLen);
cout << "Working...\n";
if (!compressed)
return 1;
if ((unsigned int) (6*img.dimx()*img.dimy()) <= cLen) {
cerr << "Error: file " << fname << " is too long to be steganographied inside image " << inImg << endl;
return 1;
}
u8 *buf = new u8[sizeof(unsigned int)];
memcpy (buf, &size, sizeof(unsigned int));
for (i=0; i < 6*sizeof(unsigned int); i+=6) {
unsigned int k = ((int) i/6);
buf[k] = (
((buf[k] & 0x03) << 6) |
((buf[k] & 0x0c) << 2) |
((buf[k] & 0x30) >> 2) |
((buf[k] & 0xc0) >> 6));
vector<u8> sizebits = bitsplit(buf[k]);
for (j=0; j < sizebits.size(); j+=2) {
unsigned int index;
u8 operand = (sizebits[j] << 1) | sizebits[j+1];
switch (j) {
case 0: index = i ; break;
case 2: index = i+2; break;
case 4: index = i+3; break;
case 6: index = i+5; break;
}
img[index] = ((img[index] & 0xfc) | operand);
}
}
//for (i=6*sizeof(unsigned int), ch = content.begin(); ch < content.end(); i+=6, ch++) {
for (i=6*sizeof(unsigned int), k=0; k < cLen; i+=6, k++) {
vector<u8> bits = bitsplit(compressed[k]);
for (j=0; j < bits.size(); j+=2) {
unsigned int index;
u8 operand = (bits[j] << 1) | bits[j+1];
switch (j) {
case 0: index=i ; break;
case 2: index=i+2; break;
case 4: index=i+3; break;
case 6: index=i+5; break;
}
img[index] = (img[index] & 0xfc) | operand;
}
}
img.save(outImg.c_str());
img.clear();
if (compressed)
delete [] compressed;
return 0;
}

119
jastegal.cpp Normal file
View file

@ -0,0 +1,119 @@
/*
* jastegal.cpp
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#include <CImg.h>
#include <iostream>
#include <unistd.h>
#include "jastegal.h"
using namespace std;
using namespace cimg_library;
int main (int argc, char **argv) {
int ch;
string inImg, outImg, fname;
action act = undef;
while ((ch=getopt(argc,argv,"edi:o:f:"))>0) {
switch (ch) {
case 'i':
inImg = string(optarg);
break;
case 'o':
outImg = string(optarg);
break;
case 'd':
if (act != undef) {
cerr << "Error: you can use a flag between -d (decode) and -e (encode) a time\n\n";
printHelp(argv[0]);
return 1;
}
act = decode;
break;
case 'e':
if (act == decode) {
cerr << "Error: you can use a flag between -d (decode) and -e (encode) a time\n\n";
printHelp(argv[0]);
return 1;
}
act = encode;
break;
case 'f':
fname = string(optarg);
break;
}
}
if (act == undef) {
cerr << "Error: you must specify an action between decoding (-d) and encoding (-e)\n\n";
printHelp(argv[0]);
return 1;
}
if (inImg.empty()) {
printHelp(argv[0]);
return 1;
}
if (act == encode) {
if (outImg.empty()) {
cerr << "Error: you must specify a file name for the output image using -o option when encoding\n\n";
printHelp(argv[0]);
return 1;
}
if (fname.empty())
cout << "Enter the input message to be steganographied [CTRL+D to end]:\n";
if (steganoEncode (inImg, outImg, fname)) {
cerr << "There was an unrecoverable error while processing the image. Exiting...\n";
return 1;
}
cout << "The steganographied output was successfully written to " << outImg << endl;
} else {
cout << steganoDecode(inImg) << endl;
}
return 0;
}

73
jastegal.h Normal file
View file

@ -0,0 +1,73 @@
/*
* jastegal.h
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#ifndef __JASTEGAL_H
#define __JASTEGAL_H
#ifndef __cplusplus
#error "You need a C++ compiler to compile Jastegal"
#endif
#include <string>
#include <vector>
#define JASTEGAL_VERSION "0.1b"
typedef unsigned char u8;
typedef enum { undef, encode, decode } action;
typedef struct {
u8 r;
u8 g;
u8 b;
} rgb;
int steganoEncode (std::string inImg, std::string outImg, std::string fname = "");
std::string steganoDecode (std::string inImg);
std::vector<u8> bitsplit (u8 data);
unsigned int fileSize (std::string fname);
std::string fileContent (std::string fname);
void printHelp (std::string arg);
char* zCompress (char* uncompressed, unsigned int uLen, unsigned int &cLen);
char* zUncompress (char* compressed, unsigned int cLen, unsigned int &uLen);
#endif

111
utils.cpp Normal file
View file

@ -0,0 +1,111 @@
/*
* utils.cpp
*
* The files in this directory and elsewhere which refer to this LICENCE
* file are part of Jastegal (Just Another Steganography algorithm)
*
* Copyright (C) 2009 BlackLight
*
* Jastegal is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 or (at your option) any later
* version.
*
* Jastegal is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Jastegal; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these
* files, these files do not by themselves cause the resulting work to be
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
* This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License.
*/
#include <iostream>
#include <fstream>
#include "jastegal.h"
using namespace std;
vector<u8> bitsplit (u8 data) {
unsigned int size = sizeof(data)*8;
u8* bits = new u8[size+1];
for (int i=size-1; i>=0; i--)
bits[size-i-1] = (data & (1 << i)) >> i;
vector<u8> v;
v.assign(bits, bits+size);
delete [] bits;
return v;
}
unsigned int fileSize (string fname) {
ifstream in(fname.c_str());
if (!in)
return -1;
in.seekg(0, ios::end);
unsigned int size = in.tellg();
in.close();
return size;
}
string fileContent (string fname) {
if (!fname.empty()) {
char *buf = NULL;
ifstream in(fname.c_str());
if (!in)
return string("");
unsigned int size = fileSize(fname);
buf = new char[size];
if (!buf)
return string("");
in.read(buf,size);
in.close();
return string(buf);
} else {
string content, line;
while (getline(cin,line))
content.append(line);
return content;
}
}
void printHelp (string arg) {
cerr << "Jastegal (Just Another Steganography Algorithm) v." << JASTEGAL_VERSION << endl
<< "c0ded by BlackLight <blacklight@autistici.org>" << endl << endl
<< "Usage: " << arg << " [-d|-e] <-i image file> [-o output image file] [-f file to be steganographied]" << endl << endl
<< "-d:\t\tPerform a decoding from an image" << endl
<< "-e:\t\tPerform an encoding to an image" << endl
<< "-i:\t\tSpecify the input image to be processed. In case of decoding, the content of this file will be de-steganographied," << endl
<< "\t\twhile in case of encoding this is the image to steganography from" << endl
<< "-o:\t\tSpecify the output image. This parameter is mandatory in encoding phase, as it specifies the file name containing" << endl
<< "\t\tthe image with the steganographied data" << endl
<< "-f:\t\tSpecify, in encoding phase, the file containing data to be steganographied. If this option is not specified, the" << endl
<< "\t\tdata will be gathered via stdin" << endl << endl
<< "Examples:" << endl
<< "\tjastegal -e -i input_image.png -o output_image.png -f file.txt" << endl
<< "\tThis will encode the data in file.txt using input_image.png as image, and putting the output in output_image.png" << endl << endl
<< "\tjastegal -d -i input_image.png" << endl
<< "\tThis will decode the data in input_image.png to stdout" << endl;
}