文件偷渡---文件写入图片

图片是一个有趣的东西,一次偶然的机会发现可以用图片来达到文件的隐藏。

往图片文件的末尾添加数据,并不会影响图片的正常显示。于是做了一下的程序,将一个文件追加到图片中,然后在取出来;

大体思路是:

写入过程:

1、 选取一个载体图片文件A。

2、 获取A文件的原始大小sizeA。

3、 将这个大小记录到A文件的某个特定的位置PositionA,方便回头取数据用;

4、 将目标文件B已二进制形式写入到BufferB中。

5、 将此BufferB追加到A载体文件的末尾;

6、 关闭A载体文件,此时A文件末尾已添加上了目标文件;

 

取回过程:

1、 打开已追加内容的A文件。写入到Buffer中;

2、 从特定的位置取回A文件的原始大小sizeA;

3、 获取A文件当前大小sizeAA, 从Buffer中的SizeAA-sizeA位置开始到文件末尾的buffer1,

4、 将这个buffer1写到一个新的空文件中,这个文件就是原来的目标文件;

程序如下:// readData.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"
//#include<stdio.h>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
using namespace std;

//打开一个文件将内容已二进制形式写入buffer
char * openFileToBuffer(char * filepath);

//得到文件的大小
int getFileSize(char *filepath);

//将指定的buffer写入到指定位置的buffer中
//主要是将载体文件原始大小写入到文件的某一个指定的位置
void writeInfoToSpecialPos(char *filePath,char *destinationBuff,char *buffer,int buffersize,int FileBufferSize,int position);

//将资源文件以追加的形式写入到载体文件的末尾
void appendFuntion(char * filePath,char *buffer,int buffersize);




int _tmain(int argc, _TCHAR* argv[])
{
	//载体文件要偷渡的资源文件将会写入到此文件的末尾,文件写入的图片文件的末尾,但是不会影响文件的阅读显示!
	char *pathDest ="c:/destination.jpg";
	//资源文件
	char *pathSrc = "c:/source.rar";
	
	//资源文件buffer
	char *Buffer = NULL;

	//载体文件buffer
	char *DestionBuffer = NULL;

	//用来存载体文件变动之前大小;
	char originsizeBuff[4] = {0};

	//假设写到文件的位置为处
	int orgposition = 4567;

	//取出资源文件到buffer中
	Buffer = openFileToBuffer(pathSrc);

	//取出载体文件到buffer中
	DestionBuffer = openFileToBuffer(pathDest);

	//得到载体文件变动之前大小
	int sizeOrign = getFileSize(pathDest);

	//定义一个int指针,指向这个存储了载体文件大小的地址空间,这个地址空间是一个连续的,占用个字节(各个OS对int分配不同)
	int *p =&sizeOrign;

	//将载体原大小复制到定义好的个字节的buffer中,这样做就以二级制方式存好,要知道计算机就是这样,数据最终形式是
	memcpy(originsizeBuff,p,4);

	//将载体文件原始大小(二级制方式存好)写入到载体文件指定位置,
	//这样做会损坏载体文件个字节的数据,相对图片而言,个字节,几乎没影响!
	writeInfoToSpecialPos(DestionBuffer,originsizeBuff,4,orgposition);
	
	//取资源文件大小
	int BufferSize = getFileSize(pathSrc);

	//将资源文件写入到载体文件末尾;
	appendFuntion(pathA,Buffer,BufferSize);
	
	//扫尾
	delete pathDest;
	delete pathSrc;
	

	return 0;
}

//写入到指定的位置是要用到的函数
void writeInfoToSpecialPos(char *destinationBuff,char *buffer,int buffersize,int position)
{
	//其他边界检测代码
	//其他边界检测代码
	ofstream file;	
	int i =0;
	while(i<buffersize)
	{
		destinationBuff[position+i]=buffer[i];//替换原来的四个字节
		i++;
	}	
	file.close();
}
//写入到指定的位置是要用到的函数
void appendFuntion(char * filePath,char *buffer,int buffersize)
{
	ofstream file;
	file.open(filePath,ios::binary|ios::app);
	if(file.good())
	{
		file.write(buffer,buffersize);//追加到文件的末尾
		file.close();
	}else{
		file.close();
	}
}



char * openFileToBuffer(char * filepath)
{
	ifstream fileA;
	char * buffer =NULL;
	int fileSize = getFileSize(filepath);
	buffer = new char[fileSize+1];
	fileA.open(filepath,ios::binary);
	if(fileA.good())
	{
		fileA.read(buffer,fileSize);
		fileA.close();
	}
	fileA.close();
	return buffer;
}

int getFileSize(char *filepath)
{
	FILE * file = fopen(filepath,"rb");
	if(file)
	{
		int size=filelength(fileno(file));
		fclose(file);
		return size;//返回文件大小
	}
	fclose(file);
	return 0;
}



取回程序:

// readData.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//#include<stdio.h>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
using namespace std;

char * openFileToBuffer(char * filepath);
int getFileSize(char *filepath);
char * getFileSpcialPosBuffer(char *filepath,int position);
void saveBufferToFile(char * filepath,char *buffer,int buffersize);
int getSizeFromSpecialPos(char *filepah,int position);




int _tmain(int argc, _TCHAR* argv[])
{
	//经过追加后,载体文件已包含了追加的资源文件,已经在某一指定位置存好了此载体文件的原始大小
	char *pathA ="c:/destination.jpg";

	//输出文件
	char *pathC = "c:/data.rar";
	char *buffer=NULL;
	char *bufferC=NULL;
	int sizeA =0;
	int sizeB =0;
	int position =0;
	int times=0;
	sizeA = getFileSize(pathA);

	int orgposition = 4567;
	//从指定位置取出载体文件的原始大小
	int orgsize = getSizeFromSpecialPos(pathA,orgposition);

	//从原始大小开始后的文件一定是追加上去的,所以取出此部分buffer,这部分的buffer就是追加的资源文件
	bufferC = getFileSpcialPosBuffer(pathA,orgsize);

	//把bufferC存到新的文件中
	saveBufferToFile(pathC,bufferC,sizeA-orgsize);

	delete bufferC;

	return 0;
}


char * openFileToBuffer(char * filepath)
{
	ifstream fileA;
	char * buffer =NULL;
	int fileSize = getFileSize(filepath);
	buffer = new char[fileSize+1];
	fileA.open(filepath,ios::binary);
	if(fileA.good())
	{
		fileA.read(buffer,fileSize);
		fileA.close();
	}
	fileA.close();
	return buffer;
}

int getFileSize(char *filepath)
{
	FILE * file = fopen(filepath,"rb");
	if(file)
	{
		int size=filelength(fileno(file));
		fclose(file);
		return size;
	}
	fclose(file);
	return 0;
}

char * getFileSpcialPosBuffer(char *filepath,int position)
{
	ifstream file;
	char *buffer =NULL;
	int size = getFileSize(filepath);//载体文件的新的大小

	buffer= new char[size-position];//新大小减去原始大小就是追加的文件大小。先申请这么大小的空间;

	file.open(filepath,ios::binary);
	if(file.good())
	{
		file.seekg(position,ios::beg);//将文件游标指定原始文件大小位置,
		file.read(buffer,size-position);//取出追加的数据;
		file.close();
		return buffer;
	}
	file.close();
	return buffer;
}

void saveBufferToFile(char * filepath,char *buffer,int buffersize)
{
	ofstream file;
	file.open(filepath,ios::binary);
	if(file.good())
	{
		file.write(buffer,buffersize);

	}file.close();
}
int getSizeFromSpecialPos(char *filepath,int position)
{
	int size=0;
	int *p =&size;
	int size1 = getFileSize(filepath);
	char * buffer1 = new char[size1];
	char buffer[4]= {0};
	ifstream file;
	file.open(filepath,ios::binary);
	file.read(buffer1,size1);
	for(int i =0;i<4;i++)
	{
		buffer[i] = buffer1[position+i];//将指定位置的往后连续的四个字节取出来,
	}

	memcpy(p,buffer,4);//然后将这个取出来到个字节(存储的是原始载体文件大小的二进制)复制到int指针指向的一个用来int变量,

	//为什么这样做,因为其底层二进制存好的大小,已复制形式就避免编译器对数据的转换,
	//然后用int来存,就可以直接用了;
	delete buffer1;
	return size;

}






 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值