用VC编写文件捆绑器

时间:2025-04-15 06:57:17
在2002年刚学VC的时候写过文件捆绑工具,当时是配合自己写的一个QQ木马使用。后来去年在某个论坛上有人问起了文件捆绑的事,我就翻出以前的程序,写下了这篇文档,今天整理硬盘的时候,把这文章发了上来,其实很简单。

  文件捆绑可以用在很多地方,比如木马。也可以在发行软件的时候把DLL捆绑在EXE文件后面,然后在EXE执行的时候动态调用DLL等等。。

  编译环境:WIN2K+VC6。

  先假设我们要把 和这两个文件捆绑成这一个文件,然后在运行的时候实现同时运行和。

  提一个小常识,PE格式的文件只要不修改文件头和文件中间的内容,而只是在文件末尾添加数据,那么这个PE文件可以正常执行。你可以试一试在命令行方式下执行copy +,命令执行完成后,被添加到文件尾,执行合并后的虽然正常,但是得不到执行。OK,这就是我们今天要解决的问题。我的想法是这样的。把三个文件捆绑在一起,捆绑后实际包含三个文件,其中是我们自己写的程序,和是我们要捆绑的程序。

  结构如下

  ---------------------------------------
  ||||
  ---------------------------------------

  整个文件就叫,如果结构如上所示,那么我们执行的时候实际上只有才会得到执行,这里的是我们自己写的,我们就让多做点事,他要做的事就是:1、把读出来另存为c:,把的内容读出来另存为c:。2、调用CreateProcess来创建两个新进程运行和。3、调用ExitProcess结束自身的进程。

  这样一来我们的目的就达到了。同时为了隐蔽起见,我们可以把的窗口界面不显示出来。

  但是又有一个问题,读取的时候怎样才能分辨出哪一段数据是,哪一段数据是?那我们就再想办法把上面的结构再扩充一下。

  -----------------------------------------------------
  ||||len2|len1|
  -----------------------------------------------------

  在文件最后面再加两段数据,分别用来存放的文件长度和的文件长度。并且固定len2和len1为30字节的长度。这样在得到执行的时候先后面的两个30字节内容,内容就是两个文件的长度,再根据这两个长度就可以准确读取到和的内容。
 
  看看程序的关键代码:

CFile fSource(_pgmptr,CFile::modeRead | CFile::modeNoTruncate); //得到的文件长度
int iSourceLength = ();
(iSourceLength-60,CFile::begin);//移动文件指针到第文件的末尾

char buffer[40];
ZeroMemory(buffer,40);
(buffer,30);//读取第len2的内容,也就是的长度

int iTargetLength = atoi(buffer);
(iSourceLength-iTargetLength-60,CFile::begin);//移动文件指针到文件的开头

CFile fTarget("c:/",CFile::modeCreate | CFile::modeWrite |

  CFile::modeNoTruncate);//创建一个新文件为c:/

char *pBuffer = new char[iTargetLength];//分配缓冲区
ZeroMemory(pBuffer,iTargetLength);
(pBuffer,iTargetLength);//将第文件读到缓冲区
(pBuffer,iTargetLength);//将缓冲区内容写入c:
delete []pBuffer;

  好了,现在文件已经读出来了,接下来就是要读的内容,过程大同小异

(iSourceLength-30,CFile::begin);//将文件指针移动到len1的开头
ZeroMemory(buffer,40);
(buffer,30);//读取len1的内容,len1的内容是文件的长度


int filelen = atoi(buffer);
(iSourceLength-60-filelen-iTargetLength,CFile::begin);//将文件指针移动到文件头
("c:/",CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate);

pBuffer = new char[filelen];
ZeroMemory(pBuffer,filelen);

(pBuffer,filelen);//将文件读到缓冲区
(pBuffer,filelen);//将文件写入c:

delete []pBuffer;
();
();

  现在我们就用CreateProcess来运行创建两个新进程就可以运行c:和c:了。创建新进程的代码很简单我就不写了。

  这部分是写完了,但是我们捆绑文件的部分还没写完,重新新建一个基于对话框的程序。

CFile fSource("c:/",CFile::modeReadWrite | CFile::modeNoTruncate); //就是上面我们写的
();//移动文件指针到文件尾

CFile fFirstFile(m_FirstFile,CFile::modeRead | CFile::modeNoTruncate); //这段代码是把添加到尾部
int ilen = ();
int len = ilen;
char *pBuffer = new char[ilen];
ZeroMemory(pBuffer,ilen);
(pBuffer,ilen);
(pBuffer,ilen);
();
delete pBuffer;


CFile fSecondFile(m_SecondFile,CFile::modeRead | CFile::modeNoTruncate); //这段代码是捆绑的
ilen = ();
pBuffer = new char[ilen];
ZeroMemory(pBuffer,ilen);
(pBuffer,ilen);
(pBuffer,ilen);
();
delete pBuffer;



char tempbuffer[30];//将的长度转换成字符串,如果长度不够30就添加空格至30,再添加到文件尾部
ZeroMemory(tempbuffer,30);
itoa(ilen,tempbuffer,10);

while (strlen(tempbuffer) < 30)
{
strcat(tempbuffer," ");
}

(tempbuffer,30);

ZeroMemory(tempbuffer,30);//将的长度转换成字符串,如果长度不够30就添加空格至30,再添加到文件尾部
itoa(len,tempbuffer,10);

while (strlen(tempbuffer) < 30)
{
strcat(tempbuffer," ");
}

(tempbuffer,30);

();

::MessageBox(NULL,"捆绑完成","提示",MB_ICONINFORMATION);

  OK,这样我们就生成了一个新文件,这个的结构上面已经说了。执行后,首先得到执行,然后和都会执行。为了增强隐蔽性,我们在的OnInitDialog()函数里写下如下代码:

ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);
::MoveWindow(m_hWnd,0,0,0,0,TRUE);
这样执行的时候没窗口,也不会在任务栏上显示任务条。