在阅读这篇文章时请先阅读第三篇,第三篇链接如下:
http://blog.csdn.net/qq78442761/article/details/54893792
这一节里面我们要做的是 把一个exe程序放入bmp文件中。但不放入alpha通道,而是对文件进行扩大,但不影响图片浏览器打开。
而,这个exe程序的作用是从百度云上下载一张图片:
相关文章在此链接http://blog.csdn.net/qq78442761/article/details/54605217
下面是这个exe的代码:
#include
#include
#include
#pragma comment(lib,"URlmon")
int main()
{
char buffer[MAX_PATH];
_getcwd(buffer, MAX_PATH);
strcat_s(buffer, "//1.jpg");
HRESULT Result = URLDownloadToFileA(NULL, "http://shcm09.baidupcs.com/file/de0243d60205717a2a74aea53c0c500c?bkt=p3-1400de0243d60205717a2a74aea53c0c500cb056e2ab00000000b511&fid=2555278822-250528-705479749498397&time=1486386954&sign=FDTAXGERLBH-DCb740ccc5511e5e8fedcff06b081203-dMTIm7f6FISsqD5yejddiOMciJ0%3D&to=sh09vb&fm=Yan,B,M,mn&sta_dx=46353&sta_cs=1&sta_ft=jpg&sta_ct=4&sta_mt=4&fm2=Yangquan,B,M,mn&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=1400de0243d60205717a2a74aea53c0c500cb056e2ab00000000b511&sl=76480590&expires=8h&rt=sh&r=807535541&mlogid=855491576450374303&vuk=2555278822&vbdid=1170054185&fin=1.jpg&fn=1.jpg&slt=pm&uta=0&rtype=1&iv=0&isw=0&dp-logid=855491576450374303&dp-callid=0.1.1&csl=80&csign=1QjHmPbR1MqUYVwmwISHS%2FlW2A0%3D", buffer, 0, NULL);
switch (Result)
{
case S_OK:printf("The download started successfully.\n"); break;
case E_OUTOFMEMORY: printf("The buffer length is invalid, or there is insufficient memory to complete the operation.\n"); break;
}
system("pause");
return 0;
}
现在我们把这个程序的release模式中运行库设置为MT,如下图所示:
随后我们生成release版的文件(如下图所示):
这时我们把他拷贝进HideFileDemo这个工程里面(如下图所示):
要隐藏的文件做好了 ,下面要做的是对BMP进行修改。
在打代码前,我们先说下原理:
打开这个BMP文件后 我们可以看到一个叫size的变量(如下图所示):
我们可以看到一个bfSize,图片查看器并不会自己把一个文件的大小读取出去,而是直接读取这个参数,
所以我们可以做一件事情,就是对这个图片的大小进行扩大,但不改变这个bfSize的值。
如下图所示:
我们发现他本身的大小和那个结构体不一样。我们保存后,看看图片会不会正常显示。
我们发现,这并没有什么影响,所以。我们的思路就是写一个程序,这个程序把要插入的程序读取成二进制模式,然后插入到这个bmp文件的最后。
下面是关键代码:(待会会提供源码下载地址)
void CBMPHide::saveExeFile(char* FileName)
{
this->sExEFileName = FileName;
if (pExEBuf) //如果已经生成就释放掉
{
delete[]pExEBuf;
}
HANDLE hfile = CreateFileA(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (hfile == INVALID_HANDLE_VALUE)
{
return;
}
dwExESize = GetFileSize(hfile, 0); //获取文件的大小
pExEBuf = new byte[dwExESize];
DWORD dwRead = 0;
ReadFile(hfile, pExEBuf, dwExESize, &dwRead, 0);
if (dwRead != dwExESize)
{
delete[]pExEBuf;
pExEBuf = 0;
return;
}
CloseHandle(hfile);
LPBYTE pEnd = pBuf+dwBmpSize;
int nHide; //成功隐藏的字节数
for (nHide = 0; nHide < dwExESize; nHide++, pEnd++)
{
*pEnd = pExEBuf[nHide]; //写入一个字节
}
this->save();
}
void CBMPHide::showExeFile(char* szBmpFIleName /*= NULL*/)
{
string sDstFileName = "";
if (szBmpFIleName == 0)
{
sDstFileName = sBmpFileName + ".hide.bmp";
}
else
sDstFileName = szBmpFIleName;
HANDLE hfile = CreateFileA(sDstFileName.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, 0, 0);
if (hfile == INVALID_HANDLE_VALUE)
{
return;
}
DWORD dwSize = GetFileSize(hfile, 0);
LPBYTE pBuf1 = new byte[dwSize];
DWORD dwRead = 0;
ReadFile(hfile, pBuf1, dwSize, &dwRead, 0);
CloseHandle(hfile);
//文件内容读取到pBuf1中
LPBYTE pStr = pBuf1 + m_fileHdr->bfSize;
char szTmp[1024*1000];
RtlZeroMemory(szTmp, 1024 * 1000);
for (int i = 0; i < dwExESize; i++)
{
szTmp[i] = *pStr;
pStr += 1;
}
string sDstFileName2 = sBmpFileName + ".hide.exe";
HANDLE hfile1 = CreateFileA(sDstFileName2.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS, 0, 0);
if (hfile1 == INVALID_HANDLE_VALUE)
{
return;
}
DWORD dwWritten = 0;
WriteFile(hfile, szTmp, dwExESize, &dwWritten, 0);
if (dwBmpSize != dwWritten)
{
return;
}
CloseHandle(hfile1);
delete[]pBuf1;
}
http://download.csdn.net/detail/qq78442761/9748468
下面是运行结果:
在此,本套C/C++信息隐写术暂时结束了,谢谢大家捧场。