?? main.cpp
字號:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************************************\
* B L I N D S I D E *
* *
* Image stego/crypto tool, please *
* see http://www.blindside.co.uk *
* *
* Compile with GCC or equiv ANSI C *
* *
* John Collomosse (mapjpc@bath.ac.uk)*
* Freeware/public domain *
* *
\************************************/
#define HEAP_UNITSIZE (102400)
#define HEAP_INITUNITS (1)
#define LOOKUP_INITLEN (2048)
#define FALSE (0)
#define TRUE (-1)
#define PATH_SEP ('\\') /* OS Specific Path Seperator */
#define BANNER ("BlindSide BMP Cryptographic Tool - (c) John Collomosse 2000\nRelease v0.9. All Rights Reserved, contact: ma7jpc@bath.ac.uk\n\n")
#define THIS_PROTO_VER (1)
/* Heap Structure (memory storage class for uchars) */
typedef struct heapstruct {
unsigned int heapunits; /* Heap size to nearest 'unit' */
unsigned char *dataspace; /* Dataspace where data stored */
unsigned char *nextchar; /* Pointer to end of dataspace */
unsigned long heaplen; /* Length of data in heap */
} HEAP;
typedef struct lookupstruct {
unsigned long int* dataspace;
unsigned long int currentlen;
unsigned long int curitem;
} LOOKUP;
/* Bitmap Structure */
typedef struct bmpstruct {
char* signature; //圖像格式標識
long filesize; //圖像文件大小
long x_size; //圖像的寬度(以像素為單位)
long y_size; //圖像的高度(以像素為單位)
int bitplanes; //圖像色彩平面數,固定為1;
int bpp; //圖像的垂直分辨率
long compression;
long compresssize;
long x_pix_per_metre;
long y_pix_per_metre;
long colours;
long cols_important; //圖像中重要的色彩數目
HEAP* palette;
HEAP* raster;
} BITMAP;
typedef struct pixstruct {
unsigned char red;
unsigned char green;
unsigned char blue;
} PIXEL;
/* Function prototypes */
int initialiseHeap (HEAP*);
int expandHeap (int, HEAP*);
void removeHeap (HEAP*);
int putToHeap (unsigned char,HEAP*);
int streamFileToHeap (FILE*, HEAP*);
int readBitmapFile (FILE*, BITMAP*);
void promoteTo24 (BITMAP*, BITMAP*);
unsigned long resolveMaxEncode (BITMAP*, LOOKUP*);
void writeBitmapFile (FILE*, BITMAP*);
unsigned int biggest_of_3 (unsigned int,unsigned int,unsigned int);
void longToStream (FILE*,unsigned long int);
unsigned long streamToLong (FILE*);
void process24gotpixel (unsigned char, unsigned char*,HEAP*);
unsigned int calcEOLpad (int, long);
PIXEL getIndexedPixel (unsigned long int, BITMAP*);
void encodeData (BITMAP*, HEAP*, LOOKUP*);
void setIndexedPixel (unsigned long int, BITMAP*, PIXEL);
unsigned char getNextHeapBit (unsigned long int, int, HEAP*);
int decodeData (BITMAP*, HEAP*);
//void cryptoData (HEAP* data, unsigned char* key);
unsigned char xor (unsigned char, unsigned char);
int rotl4 (int);
int hash_func (unsigned char*);
int pow (int,int);
int stricmp (const char*, const char*);
int formatDataspace (BITMAP*, HEAP*);
void dumpFileDirectory (HEAP*);
void dumpFileStats (BITMAP*, HEAP*);
void addFileToArchive (HEAP*, FILE*, char*);
int checkExists (char*);
int extractFile (HEAP*, char*);
void flattenBitmap (BITMAP*, LOOKUP*);
int main (int argc, char** argv) {
int mode;
FILE* bitmap_handle=NULL; //指向BMP圖片
FILE* plaintext_handle=NULL; //指向普通的需要隱藏的文本文件
FILE* outfile_handle=NULL; //輸出文件
BITMAP* BMPsource=NULL; //結構體
BITMAP* BMPworking=NULL; //結構體
HEAP* filespace=NULL;
LOOKUP* hotspots;
unsigned long int i;
//int isencrypted=FALSE;
//char password[130];
//printf(BANNER);
mode=0;
if (argc >=2) {
/* deduce mode of operation */
if (stricmp(argv[1],"-A")==0)
mode=1;
if (stricmp(argv[1],"-X")==0)
mode=2;
if (stricmp(argv[1],"-C")==0)
mode=3;
if (stricmp(argv[1],"-L")==0)
mode=4;
}
if (mode==0 || (mode==1 && (argc!=5 && argc!=6)) || (mode==2 && (argc!=3 && argc!=4 && argc!=5)) || (mode==3 && argc!=3) || (mode==4 && argc!=3)) {
printf("USAGE: BSIDE < option > < filenames - see below >\n\n");
printf("Option Description\n");
printf("~~~~~~ ~~~~~~~~~~~\n");
printf(" -A Add a file into image, need to specify files as follows\n");
printf(" BSIDE -A < BMP file > < plaintext file > < result BMP file > [password]\n\n");
printf(" -X eXtract file(s) from image, need to specify files as follows\n");
printf(" BSIDE -X < BMP file > [file to extract] [password if needed]\n\n");
printf(" -C Calculate data storage statistics of a bitmap\n");
printf(" BSIDE -C < BMP file >\n\n");
printf(" -L List files stored within a bitmap\n");
printf(" BSIDE -L < BMP file >\n\n");
printf("Please note that wildcards are NOT currently supported\n\n");
printf("BlindSide is (c) John Collomosse 2000, All Rights Reserved\nComments/suggestions to ma7jpc@bath.ac.uk, updates see www.blindside.co.uk\n");
exit(1);
}
/* Read Password off of command line */
for (i=0; i< 129; i++)
password[i]='\0';
if ((argc==6 && mode==1) || (argc==5 && mode==2)) {
isencrypted=TRUE;
for (i=0; i< 129; i++) {
password[i]=argv[6-mode][i];
if (argv[6-mode][i]=='\0')
break;
}
password[129]='\0';
}
/* Open all necessary files */
bitmap_handle=fopen(argv[2],"rb"); //打開載體圖像
if (mode==1)
plaintext_handle=fopen(argv[3],"rb"); //打開密碼文件
if (bitmap_handle==NULL) {
printf("FATAL: Could not open bitmap %s!\n",argv[2]);
exit(2);
}
if (plaintext_handle==NULL && mode==1) {
printf("FATAL: Could not open plaintext %s!\n",argv[3]);
exit(3);
}
/* Read source bitmap (this must be done for every command line variation) */
printf("? Reading bitmap file....");
BMPsource=(BITMAP*)calloc(1,sizeof(BITMAP));
BMPsource->palette=(HEAP*)calloc(1,sizeof(HEAP));
BMPsource->raster=(HEAP*)calloc(1,sizeof(HEAP));
initialiseHeap(BMPsource->palette);
initialiseHeap(BMPsource->raster);
if (!readBitmapFile(bitmap_handle,BMPsource)) {
printf("ERROR\n\nFATAL: Out of memory, while reading bitmap file\n");
exit(4);
}
printf("OK\n");
/* Analyse Bitmap */
if (stricmp("BM",BMPsource->signature) || BMPsource->bitplanes!=1) {
printf("FATAL: Not a valid bitmap file\n");
exit(5);
}
if (BMPsource->compression!=0) {
printf("FATAL: BlindSide cannot work with compressed bitmaps yet\n");
exit(6);
}
if (BMPsource->bpp==1) {
printf("FATAL: BlindSide can't work with monochrome images, as it is the colours\nwithin the image itself that are used to hide files within a bitmap.\nYou can only use bitmaps of greater colour depth (16c, 256c, 16Mc)\n");
exit(8);
}
if (BMPsource->bpp!=4 && BMPsource->bpp!=8 && BMPsource->bpp!=24) {
printf("FATAL: Can't work with a bitmap with %d bits per pixel\n\nTry saving the bitmap into a different bit depth in a graphics package.\n",BMPsource->bpp);
exit(8);
}
printf("? Image is %ld bytes (%ldx%ld), %d bits/pixel\n",BMPsource->filesize,BMPsource->x_size,BMPsource->y_size,BMPsource->bpp);
/* Colour depth increase if need be */
if (BMPsource->bpp< 24) {
printf("? Increasing Colour Depth to 16M colours (24bpp)...");
BMPworking=(BITMAP*)calloc(1,sizeof(BITMAP));
if (BMPworking==NULL) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
BMPworking->palette=(HEAP*)calloc(1,sizeof(HEAP));
BMPworking->raster=(HEAP*)calloc(1,sizeof(HEAP));
if (BMPworking->palette==NULL || BMPworking->raster==NULL) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
if (!initialiseHeap(BMPworking->palette) || !initialiseHeap(BMPworking->raster)) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
/* Do the promote to 24bpp */
promoteTo24(BMPsource, BMPworking);
/* cleanup source */
removeHeap(BMPsource->palette);
removeHeap(BMPsource->raster);
free(BMPsource);
BMPsource=NULL;
printf("OK\n");
}
else {
/* Source was fine -> already 24 bpp */
BMPworking=BMPsource;
BMPsource=NULL;
}
/* Prepare BS dataspace */
printf("? Analysing Data Patterns....");
filespace=(HEAP*)calloc(1,sizeof(HEAP));
initialiseHeap(filespace);
switch (decodeData(BMPworking,filespace)) {
case 0: printf("OK\n");
break;
case 1: removeHeap(filespace);
initialiseHeap(filespace);
if (mode==2 || mode==4) {
printf("ERROR\n\nFATAL: File does not contain any BlindSide hidden data\n");
exit(4);
}
printf("OK\n");
if (mode==1) {
printf("? Creating New Archive....");
if (formatDataspace(BMPworking, filespace))
printf("OK\n");
else {
printf("ERROR\n\nFATAL: There isn't enough space in the bitmap to hold any Blindside hidden data\n");
exit(4);
}
}
break;
case 2: printf("\nFATAL: Out of memory while analysing bitmap\n");
exit(4);
break;
case 3: printf("\nFATAL: Bitmap was encoded using a higher version of BlindSide than this one\n");
exit(4);
break;
}
/* At this point 'filespace' is always a working BS archive (although it may be one with no files contained) */
/* In case of Mode 3 it MAY NOT be the case that filespace is archive - it may be empty heap */
/* Decrypt if necessary */
if (filespace->heaplen!=0) {
if (*(filespace->dataspace+1)=='E') {
/* decrypt */
if (strcmp(password,"")==0) {
/* get pword */
printf("\nData is encrypted, please enter password: ");
scanf("%s",password);
printf("\n");
}
/*printf("? Decrypting Data....");
cryptoData(filespace,password);
if (*(filespace->dataspace+7)=='O' && *(filespace->dataspace+8)=='K') {
printf("OK\n");
isencrypted=TRUE;
}
else {
printf("ERROR\n\nFATAL: Incorrect password\n");
exit(9);
}
*/
}
}
/* Do whichever of the operations was requested */
switch (mode) {
case 1: printf("\n");
for (i=strlen(argv[3]); i >0; i--) {
if (argv[3][i]==PATH_SEP)
break;
}
if (i!=0 || (argv[3][0]==PATH_SEP))
i++;
addFileToArchive(filespace,plaintext_handle,&(argv[3][i]));
printf("\n");
break;
case 2: printf("\n");
if (argc >=3)
extractFile(filespace,argv[3]);
else
extractFile(filespace,NULL);
break;
case 3: dumpFileStats(BMPworking, filespace);
break;
case 4: dumpFileDirectory(filespace);
break;
}
/* Output to disk */
/* If we were in ADD mode, write the bitmap out (Xtract, Calc, and List are READ ONLY) */
if (mode==1) {
/* close plaintext */
fclose(plaintext_handle);
if (isencrypted==TRUE) {
printf("? Encrypting Data....");
//cryptoData(filespace,password);
printf("OK\n");
}
printf("? Encoding Data....");
hotspots=(LOOKUP*)calloc(1,sizeof(LOOKUP));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit(4);
}
hotspots->dataspace=(unsigned long int*)calloc(LOOKUP_INITLEN,sizeof(unsigned long int));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit (4);
}
hotspots->currentlen=LOOKUP_INITLEN;
flattenBitmap(BMPworking,hotspots);
encodeData(BMPworking,filespace,hotspots);
printf("OK\n");
printf("? Writing result to %s....",argv[4]);
outfile_handle=fopen(argv[4],"wb");
writeBitmapFile(outfile_handle, BMPworking);
fclose(outfile_handle);
printf("OK\n");
}
/* Cleaup and exit */
printf("\nDone!\n");
removeHeap(filespace);
free(filespace);
removeHeap(BMPworking->palette);
free(BMPworking->palette);
removeHeap(BMPworking->raster);
free(BMPworking->raster);
free(BMPworking);
return(0);
}
/***************************** HEAP MANAGEMENT ***********************/
int initialiseHeap(HEAP* heap) {
heap->dataspace=NULL;
heap->heapunits=0;
heap->nextchar=NULL;
heap->heaplen=0;
heap->dataspace=(unsigned char*)calloc(HEAP_INITUNITS,HEAP_UNITSIZE*sizeof(unsigned char));
if (heap->dataspace==NULL)
return FALSE;
else {
heap->heapunits=HEAP_INITUNITS;
heap->nextchar=heap->dataspace;
return TRUE;
}
}
int expandHeap(int newunits, HEAP* heap) {
if (newunits> heap->heapunits) {
unsigned char* tmpheap;
int i;
tmpheap=heap->dataspace;
heap->dataspace=(unsigned char*)calloc(newunits,HEAP_UNITSIZE*sizeof(unsigned char));
if (heap->dataspace==NULL) {
heap->dataspace=tmpheap;
return FALSE;
}
else {
for (i=0; i< heap->heapunits*HEAP_UNITSIZE; i++)
heap->dataspace[i]=tmpheap[i];
free(tmpheap);
heap->nextchar=(heap->dataspace)+(heap->heapunits*HEAP_UNITSIZE);
heap->heapunits=newunits;
}
}
return TRUE;
}
void removeHeap(HEAP* heap) {
if (heap->dataspace!=NULL) {
free (heap->dataspace);
heap->heapunits=0;
heap->dataspace=NULL;
heap->nextchar=NULL;
heap->heaplen=0;
}
}
int streamFileToHeap(FILE* infile, HEAP* heap) {
unsigned char readchar;
while (fscanf(infile,"%c",&readchar) >0) {
if (!putToHeap(readchar,heap))
return FALSE;
}
return TRUE;
}
int putToHeap(unsigned char data, HEAP* heap) {
unsigned long hopeful_pos=heap->heaplen;
unsigned long current_pos=(heap->heapunits*HEAP_UNITSIZE);
if (hopeful_pos >= current_pos) {
int discrep=(int)hopeful_pos/HEAP_UNITSIZE;
discrep++;
if (!expandHeap(discrep, heap)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -