您的位置:首页 > 其它

在24位真彩色位图中插入文件并隐藏文件

2009-07-29 10:12 357 查看
程序中限制了文件大小,大小是 (data_size = bih.biHeight*bih.biWidth*3) / 4 ;

///////////////////////////////////////////////
// File Inside Bitmap (inserttobitmap.exe)
// 'Melts' a file into a bitmap file
// That way, files can be hidden inside bitmaps
// The algorithm uses a modulation technique
// Written by WolfCoder (2007)
///////////////////////////////////////////////

/////////////////////////////////////////////
// ******  Sample Command Line Usages  ******
/////////////////////////////////////////////
// Puts a file INTO a bitmap image
// -m file.xyz image.bmp
/////////////////////////////////////////////
// Removes a file from the image
// NOTE: extracts garbage if the image
// did not have any coded files to begin with
// -e image.bmp outfile.xyz
/////////////////////////////////////////////

/////////////////////////////////////////////
// BATCH FILE HELP
// Copy the following lines into the batch file:
// -m file.xyz image.bmp
// -e image.bmp outfile.xyz
// Use notepad and save the lines as .bat
// Simply copy the -m line in order to melt something
// and the -e line to extract something
// Then double click on the .bat file to execute
/////////////////////////////////////////////

// Program Headers
#include <iostream> // On my compiler, the .h is not allowed here, but it might in yours
using namespace std; // Keep in mind you might not need this namespace line
#include <windows.h> // Uses windows methods of file handling, bitmap reading, ect...

// Global Variables
BITMAPFILEHEADER bfh; // Contains file size information (and format tag)
BITMAPINFOHEADER bih; // Contains dimensions, color depth, ect...
unsigned char *data; // Pointer to bitmap image data in memory
unsigned char *source; // Pointer to source data in memory
HANDLE hfile; // Handle to file on disk
DWORD written,read; // Byte written/read result
DWORD data_size;
DWORD file_size;

// Insert a file into a bitmap
void insert_into_bitmap(char *bitmap,char *filename)
{
// Gather information on the bitmap image specified

// Open a channel to the file
hfile = CreateFile(bitmap,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
// Read file information
ReadFile(hfile,&bfh,sizeof(bfh),&read,NULL);
// Read file image format
ReadFile(hfile,&bih,sizeof(bih),&read,NULL);
// Allocate necessary data for image
data = new unsigned char[bih.biHeight*bih.biWidth*3];
// Read image data
ReadFile(hfile,data,bih.biHeight*bih.biWidth*3,&read,NULL);
// Close the channel, image has been completly read
CloseHandle(hfile);

// Is this a valid bitmap file?
if(bih.biBitCount != 24)
{
cout<<"Only 24-bit RGB true-color bitmap images are allowed./n";
return;
}

// Measure the size of the file and it's dimensions
cout<<"Image data is "<<(bih.biHeight*bih.biWidth*3)<<" bytes long./n";
cout<<"It has a height of "<<bih.biHeight<<" and a width of "<<bih.biWidth<<"./n";
data_size = bih.biHeight*bih.biWidth*3;

// Measure the capacity of the bitmap file
cout<<"A file of up to "<<(data_size/4)<<" bytes can be hidden inside./n";

// Prepare the image for insertion
for(DWORD i = 0;i < data_size;i++)
{
data[i] /= 4; // Reduce precision for extra data
data[i] *= 4;
}

// Read the source data
// Open a channel to data
hfile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
// Get file size
file_size = GetFileSize(hfile,NULL);
// Report that size
cout<<"Input file has a size of "<<file_size<<" bytes./n";
// Allocate and read data
source = new unsigned char[file_size];
ReadFile(hfile,source,file_size,&read,NULL);
// Close the channel since the data was retrived from disk
CloseHandle(hfile);

// Now check for size errors
if(file_size > data_size/4)
{
cout<<"File to be inserted doesn't fit in this bitmap!./n";
return;
}

// Apply the data to the image
for(DWORD i = 0;i < file_size;i++)
{
// Get the base index
DWORD index = i*4;
// Start adding data
data[index] += source[i]&3; // 1+2 = 3 00000011
data[index+1] += (source[i]&12)>>2; // 4+8 = 12 00001100
data[index+2] += (source[i]&48)>>4; // 16+32 = 48 00110000
data[index+3] += (source[i]&192)>>6; // 64+128 = 192 11000000
}

// Write the file size into Xpelspermeter
bih.biXPelsPerMeter = file_size;

// Output final result
// Open a channel to output image
hfile = CreateFile("output.bmp",GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
// Write back information and image format data
WriteFile(hfile,&bfh,sizeof(bfh),&written,NULL);
WriteFile(hfile,&bih,sizeof(bih),&written,NULL);
// Write back the edited image data
WriteFile(hfile,data,data_size,&written,NULL);
// Close the channel, operation complete
CloseHandle(hfile);
}

// Extracts a file from a bitmap image
void extract_from_image(char *bitmap,char *filename)
{
// Gather information about the file inside the bitmap

// Open a channel to the file
hfile = CreateFile(bitmap,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
// Read file information
ReadFile(hfile,&bfh,sizeof(bfh),&read,NULL);
// Read file image format
ReadFile(hfile,&bih,sizeof(bih),&read,NULL);
// Allocate necessary data for image
data = new unsigned char[bih.biHeight*bih.biWidth*3];
// Read image data
ReadFile(hfile,data,bih.biHeight*bih.biWidth*3,&read,NULL);
// Close the channel, image has been completly read
CloseHandle(hfile);

// Check to see if the bitmap could possibly hold data
if(bih.biBitCount != 24)
{
cout<<"This image is not a 24-bit true color RGB image. This program doesn't work with them./n";
return;
}

// Measure the size of the file and it's dimensions
cout<<"Image host data is "<<(bih.biHeight*bih.biWidth*3)<<" bytes long./n";
cout<<"It has a height of "<<bih.biHeight<<" and a width of "<<bih.biWidth<<"./n";
data_size = bih.biHeight*bih.biWidth*3;

// Find out how big the file inside is
cout<<"The file inside is "<<bih.biXPelsPerMeter<<" bytes long./n";
file_size = bih.biXPelsPerMeter;

// Allocate data for inside file
source = new unsigned char[file_size];

// Begin re-constructing data
for(DWORD i = 0;i < file_size;i++)
{
// Get base index
DWORD index = i*4;
// Begin data reconstruction
source[i] = data[index]%4;
source[i] += (data[index+1]%4)<<2;
source[i] += (data[index+2]%4)<<4;
source[i] += (data[index+3]%4)<<6;
}

// Write out extracted data
// Open a channel
hfile = CreateFile(filename,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
// Write the data
WriteFile(hfile,source,file_size,&written,NULL);
// Close channel
CloseHandle(hfile);
}

// Program Entry
void main(int argn,char *argv[])
{
// Determine the number of arguments
if(argn <= 1)
{
// No command given, assume the user wants help
cout<<"Usage:/n-m file.xyz image.bmp (Inserts file inside a bitmap)./n-e image.bmp outfile.xyz (Extracts file from inside a bitmap)./n";
return;
}
if(argn == 2)
{
// A command was given, but there was no parameters issued
cout<<"Error: no input or output files defined./n";
return;
}
if(argn == 3)
{
// Only some parameters were given, but not enough
cout<<"Error: not enough input/output files given./n";
return;
}
// All the parameters are here, start the action
// Check what action needs to be taken
if(argv[1][1] == 'm' || argv[1][1] == 'M')
insert_into_bitmap(&argv[3][0],&argv[2][0]); // User wants to inset a file into a bitmap
else
extract_from_image(&argv[2][0],&argv[3][0]); // User wants to take a file out of the bitmap

// Clean up after operation
delete data;
delete source;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: