副标题#e#
将多个文件归并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了归并前的多个文件。这种措施在木马措施归并中会常常用到,你想知道它是怎么用措施实现的么?下面我就拿我用VC6.0做的一个文件绑缚器的例子代码来汇报你:
根基组成思想:其实,个中的组成思想很是简朴。归并文件时:成立一个新的二进制文件,先写入你的自身绑缚措施的数据和其文件长度,再写入你要绑缚的第一个文件的数据和其文件长度,后再直接写入你要绑缚的第二个文件的数据和文件长度……,最后可直接写入你要绑缚的最后一个文件的数据(不需其文件长度)。解析释放最终合成文件时,也就是将上面的要领思想倒过来既可:打开最终合成文件,读取源自身绑缚措施文件长度,将文件指针移到自身绑缚措施数据后,读取第一个被绑定文件的长度,接着读取其长度的文件数据并写入到一新建文件1中,再读取第二个被绑定文件的长度,接着读取其长度的数据并写入到新建文件2中……,直到最后直接读取最后一个被绑定文件的数据并将其写入到最后一个新建文件中既可。(下面实例仅汇报你如何实现二个文件的绑缚,至于多个文件的绑缚,读者只需略加窜改既可,详情请查察下载后的实例代码。)
下面我来讲讲文件绑缚最焦点的部门,以及如何详细将其用代码来实现的要领:
1、绑缚多个文件为一个可执行措施
先获得自身绑缚措施的文件长度和第一个要绑缚文件的文件长度,列举第一个要绑缚文件有无图标,有的话就用它做为最终生成文件的图标,不然用自身绑缚措施所带默认图标做最终生成文件的图标。在新建二进制文件中写入自身绑缚措施的数据和其文件长度,再写入第一个要绑缚文件的数据及其文件长度,最后直接写入第二个文件的数据既可。
#p#副标题#e#
归并措施涵数的详细代码实现如下:
//界说要利用到的绑缚措施自身文件信息的布局体
struct MODIFY_DATA {
unsigned int finder; // 常量(定位自身)
_off_t my_length; //文件长度(自身)
} modify_data = {0x12345678, 0};
//绑定二个文件为一个可执行文件
bool CBindFileDlg::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 buff[20]; //进度条状态显示变量
his_name = strFirstFilePath; //第一个绑定的文件名
_stat(my_name, &ST); //获取自身绑缚文件信息
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_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;
}
//存储自身文件信息到缓冲区(如长度)
for (i = 0; i < modify_data.my_length - sizeof(finder); i += sizeof(finder))
{
for (k = 0; k < sizeof(finder); k++)
{
if (buf[i+k] != ((BYTE*)&finder)[k])
break;
}
if (k == sizeof(finder)) //定位并生存自身数据文件信息
{
memcpy(buf+ i, &modify_data, sizeof(modify_data));
break;
}
}
if (i >= modify_data.my_length - sizeof(finder))
{
free(buf);
MessageBox("绑定文件中,不能定位自身文件时堕落!","错误");
return false;
}
//获取第一个要绑定文件的信息(文件长度)
if (_stat(strFirstFilePath, &ST) != 0 || ST.st_size == 0)
{
free(buf);
MessageBox("绑定文件中,读取第一个要绑定文件时堕落!","错误");
return false;
}
//获取自身文件图标及第一个要绑定文件的图标(如第一个要绑定文件没有图标,
//则用自身文件图标。其涵数实现请参看例程)
list_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);
MessageBox("绑定文件中,打开第一个要绑定文件时堕落!","错误");
return false;
}
//写入第一个要绑定文件的长度到最终合成文件中
totalbytes += fwrite(&ST.st_size, 1, sizeof(ST.st_size), out);
//写入最终解析后文件执行方法的符号位(同步或异步执行)
UpdateData(TRUE); //传控件值到变量m_Sync中
totalbytes += fwrite(&m_Sync, 1, sizeof(int), out);
//写入第一个要绑定文件的数据到最终合成文件中
while (bytesin = fread(buf, 1, modify_data.my_length, in))
{
totalbytes += fwrite(buf, 1, bytesin, out);
}
fclose(in); //封锁第一个绑定文件句柄
//配置进度条显示
m_Progress.SetRange(0,500);
for (int m = 0; m < 500; m++)
m_Progress.SetPos(m);
m_Parts = _ltoa(l, buff, 10);
m_Parts += _T("个文件已绑定");
UpdateData(FALSE);
l++;
in = fopen(strSecondFilePath, "rb"); //打开第二个要绑定的文件
if (in == NULL)
{
free(buf);
MessageBox("绑定文件中,打开第二个要绑定文件时堕落!","错误");
return false;
}
//直接写入第二个要绑定文件的数据到最终合成文件中
while (bytesin = fread(buf, 1, modify_data.my_length, in))
{
totalbytes += fwrite(buf, 1, bytesin, out);
}
//配置进度条显示
m_Progress.SetRange(0,500);
for (int n = 0; n < 500; n++)
m_Progress.SetPos(n);
m_Parts = _ltoa(l, buff, 10);
m_Parts += _T("个文件已绑定");
UpdateData(FALSE);
l++;
fclose(in); //封锁第二个绑定文件句柄
fclose(out); //封锁最终合成文件句柄
free(buf); //释放缓冲区
return true;
}
2、释放最终合成文件并同3、 时运行它们。
#p#分页标题#e#
打开自身文件,从中获得自身绑缚措施的文件长度,便可将文件指针定位到第一个被绑缚文件的位置,读取其文件长度和其数据,将其读出数据写入第一个新建文件中。同样,通过已读取的自身绑缚措施文件长度和第一个被绑缚文件的文件长度加上其生存这两个文件长度值的字节数,既可精确定位第二个被绑缚文件的位置,读取其数据,写入到第二个新建文件中。同时,运行这两个文件,最后再删除这两个文件既可。
 释放最终合成文件的代码详细实现如下:
//建设解析文件后,运行各解析文件时的历程
void CBindFileDlg::Create_Process(const char* temp_exe, BOOL async)
{
HANDLE hProcess; //历程句柄
HANDLE hThread; //线程句柄
PROCESS_INFORMATION PI; //历程信息
STARTUPINFO SI; //启动信息
memset(&SI, 0, sizeof(SI)); //分派必然的内存
SI.cb = sizeof(SI); //巨细赋给启动信息内CB
CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);
/* --- 暂不消,不然需要生存原始绑定的文件名称
//假如解析后的文件不是执行文件的话,则直接打开它
if(!CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI))
HINSTANCE result =ShellExecute(NULL, _T("open"), temp_exe, NULL,NULL, SW_SHOW);
--- */
hProcess = PI.hProcess;
hThread = PI.hThread;
//异步执行时,执行后不删除解析后的文件;同步执行时,执行后删除解析后的文件
if (!async) //当同步执行时
{
//一直期待,直到当前措施运行历程竣事
WaitForSingleObject(hProcess, INFINITE);
unlink(temp_exe); //删除temp.exe文件
}
}
//解析已归并的文件,同时运行它们
#p#分页标题#e#
void CBindFileDlg::Unbind()
{
FILE* myself; //自身文件
FILE* out; //解析后文件
int bytesin; //一次读出文件的字节数
int totalbytes = 0; //读出文件的总字节数
char temp_exe1[] = "temp1.exe"; //解析后的绑定文件名一(可任意取)
char temp_exe2[] = "temp2.exe"; //解析后的绑定文件名二(可任意取)
int SyncFlag; //文件最终执行符号(同步或异步)
//先分派必然巨细的缓冲区(巨细便是绑缚措施长度)
buf = (BYTE*)malloc(modify_data.my_length);
myself = fopen(my_name, "rb"); //打开最终合成文件
if (myself == NULL)
{
free(buf);
MessageBox("疏散文件中,打开自身文件时堕落!","错误");
return;
}
out = fopen(temp_exe1, "wb"); //建设第一个绑定的文件
if (out == NULL)
{
free(buf);
MessageBox("疏散文件中,建设第一个被绑定文件时堕落!","错误");
return;
}
//将文件指针定位到绑缚器措施长度尾部
fseek(myself, modify_data.my_length, SEEK_SET);
//读取第一个绑定文件的长度
if (fread(&prog1_length, sizeof(prog1_length), 1, myself) == 0)
{
free(buf);
MessageBox("疏散文件中,读取第一个被绑定文件长度时堕落!","错误");
return;
}
//读取最终文件执行方法(同步或异步执行)
if (fread(&SyncFlag, sizeof(int), 1, myself) == 0)
{
free(buf);
MessageBox("疏散文件中,读取第一个被绑定文件长度时堕落!","错误");
return;
}
//读取第一个文件内容并写入到新建的temp1.exe文件中
while (bytesin = fread(buf, 1, sizeof(buf), myself))
{
if (totalbytes + bytesin > 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;
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, SEEK_SET);
//读取第二个绑定文件内容并写入到新建的temp2.exe文件中
while (bytesin = fread(buf, 1, sizeof(buf), myself))
{
totalbytes += fwrite(buf, 1, bytesin, out);
}
fclose(out); //封锁第二个绑定文件句柄
#ifdef DEBUG_PRINT
fprintf(stderr, "已复制 %d 字节\n", totalbytes);
#endif DEBUG_PRINT
fclose(myself); //封锁最终合成文件句柄
if (totalbytes == 0)
{
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_exe2, true);
}
}
3、判定何时绑缚措施,何时又解析最终合成措施。
#p#分页标题#e#
由于本措施是将自身绑缚措施作为文件头,要绑定文件附加其后方法生成最终合成文件的。所以,只要知道自身绑缚措施的文件长度,再在初始化对话框涵数OnInitDialog()加以判定及可知道是否是最终合成文件(要不要释放内部绑定文件)。本例程用VC6.0回收静态毗连方法生成的Release版,文件巨细为184K。
故判定是绑缚照旧释放文件的代码详细实现如下:
BOOL CBindFileDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application''s main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(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 = ""; //最终合成文件名
//初始化变量
prog1_length = 0; //文件长度
his_name = ""; //绑定文件名
buf = NULL; //缓冲区置空
//获取自身文件名到my_mane变量中
::GetModuleFileName(0, my_name, sizeof(my_name));
struct _stat ST;
_stat(my_name, &ST); //获取自身文件信息(长度)
//在此插手绑缚器措施的最终巨细,来判定是绑定文件照旧解析执行文件
//当发明自身文件巨细大于原巨细184K时,为释放内部合成文件
if(ST.st_size > 184*1024)
{
Unbind(); //疏散文件并运行
exit(0); //直接退出措施,不显示绑缚措施画面
}
return TRUE; // return TRUE unless you set the focus to a control
}
个中详细实现细节问题,可在下载实例代码后,仔细查察既可(内有具体注释)。