企业即时通讯 - Enterprise Instant Messenger

局域网聊天工具,文字讯息、文件发送、语音通讯、高清视频通讯、远程桌面控制。

用户操作
[即时聊天] [发私信] [加为好友]
FreeEIM StudioID:i_like_cpp
972448次访问,排名32,好友4人,关注者7人。
i_like_cpp的文章
原创 888 篇
翻译 4 篇
转载 69 篇
评论 1148 篇
FreeEIM Studio的公告
最近评论
ScanerKi:#include <stdio.h>

int asm(int s)
{
int t=0;
__asm
{
mov eax, DWORD PTR [ebp+8] ;把s的值传给eax
mov t, eax ;把eax的值传给t
}
printf("- %d……
li_delong:谢谢
li_delong:谢谢
li_delong:谢谢
XUETUJIAN:
文章分类
收藏
相册
EIM 截图
相关软件图片
PI的最精确值
FreeEIM 标签
FreeEIM华军下载
XP SP2 SDK
下载FreeEIM
盛天龙
飞鸽传书
不错的网站
CPPBLOG
局域网聊天
泡妞专家
用VC写Assembly代码(RSS)
百度的Blog(RSS)
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 如何将多个文件捆绑成一个可执行文件收藏

新一篇: 最容易的第一个WINDOWS程序 | 旧一篇: 跨进程API Hook

如何将多个文件捆绑成一个可执行文件

内容:

下载示例程序代码

将多个文件合并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了合并前的多个文件。这种程序在木马程序合并中会经常用到,你想知道它是怎么用程序实现的么?下面我就拿我用VC6.0做的一个文件捆绑器的实例代码来告诉你,实例程序运行后的界面如下:

图例


基本构成思想:其实,文件捆绑的构成思想非常简单,它主要可分为合并文件和分解释放文件二大部分。合并文件时:建立一个新的二进制文件,先写入你的捆绑程序的自身数据和其文件长度,再写入你要捆绑的第一个文件的数据和其文件长度,后再直接写入你要捆绑的第二个文件的数据和其文件长度……,最后可直接写入你要捆绑的最后一个文件的数据(不再需要其文件长度)。分解释放最终合成文件时:也就是将上面的方法思想倒过来既可,打开最终合成文件,读取源捆绑程序自身文件长度,将文件指针移到捆绑程序自身数据后,读取第一个被绑定文件的长度,接着读取其后长度大小的一段文件数据并写入到一新建文件1中,再读取第二个被绑定文件的长度,接着读取其后长度大小的一段文件数据并写入到新建文件2中……,直到最后,就可直接读取最后一个被绑定文件的数据并将其写入到最后一个新建文件中既可。(下面实例代码仅告诉你如何实现二个文件的捆绑,至于多个文件的捆绑,读者只需按上面所说略加改动既可,实现详情请查看下载后的实例代码。)

下面我来讲讲文件捆绑最核心的部分,以及如何将其用代码来实现的方法:
1、 捆绑多个文件为一个可执行程序
思路:先获得捆绑程序自身的文件长度和第一个被捆绑文件的文件长度,枚举出第一个被捆绑文件的图标,有图标的话就用它做为最终生成文件的图标,否则就用捆绑程序自身所带图标做为最终生成文件的图标。然后,新建一个二进制文件,在其中写入捆绑程序自身的文件数据和其文件长度,接着写入第一个被捆绑文件的文件长度和最终合成文件的运行方式标志位(同步还是异步运行),紧接着再写入第一个被捆绑文件的文件数据,最后直接写入第二个被捆绑文件的文件数据既可。
l 合并程序涵数的具体代码实现如下:
//绑定二个文件为一个可执行文件
bool CBindFileDlg::Bind_Files()
{
…… (省略:此部分代码用来定义各成员变量)

his_name = strFirstFilePath; //第一个绑定的文件名

_stat(my_name, &ST); //获取自身捆绑文件信息
modify_data.my_length = ST.st_size; //得到自身文件长度
buf = (BYTE *)malloc(modify_data.my_length); //分配一定大小缓冲区
myself = fopen(my_name, "rb"); //打开自身文件

//先读取捆绑程序自身文件数据
bytesin = fread(buf, 1, modify_data.my_length, myself);
fclose(myself);

……(省略:此部分代码用来获取自身文件和第一个被捆绑文件长度,以及获取最终合成文件的图标)

out = fopen(strFinalFilePath, "wb"); //创建最终合成文件

//先将前面读出的自身捆绑程序的数据写入最终合成文件中
totalbytes += fwrite(buf, 1, bytesin, out);

in = fopen(strFirstFilePath, "rb"); //打开第一个要绑定的文件
//写入第一个要绑定文件的长度到最终合成文件中
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); //关闭第一个绑定文件句柄

in = fopen(strSecondFilePath, "rb"); //打开第二个要绑定的文件

//直接写入第二个要绑定文件的数据到最终合成文件中
while (bytesin = fread(buf, 1, modify_data.my_length, in))
{
totalbytes += fwrite(buf, 1, bytesin, out);
}
……(省略:此部分代码用来关闭文件句柄)
}
2、 释放最终合成文件并同时运行它们。
思路:打开自身文件,从中得到捆绑程序自身的文件长度,将文件指针定位到捆绑程序自身数据后的第一个被捆绑文件的位置,读取其第一个被捆绑文件的文件长度和最终合成文件释放后的运行方式标志(同步还是异步方式执行),接着读取其第一个被捆绑文件的文件数据,将其读出数据直接写入到一个新建的二进制文件中。同样,通过已读取的捆绑程序自身文件长度和第一个被捆绑文件的文件长度再加上其保存这两个文件长度值的字节数及最终合成文件释放后的运行标志所占字节数,既可准确定位出第二个被捆绑文件的文件数据所在的指针位置,读取其文件数据后,直接写入到一个新建二进制文件中。最后,根据前面读出的文件释放后的运行标志,来决定以何种方式来运行释放的这两个文件,如果是同步方式,顺序运行后会删除这两个生成文件,异步方式则会同时运行而不会删除这二个生成文件。
l 释放最终合成文件的代码具体实现如下:
//分解已合并的文件,同时运行它们
void CBindFileDlg::Unbind()
{
……(省略掉:此部分代码主要用来定义成员变量)

myself = fopen(my_name, "rb"); //打开最终合成文件
out = fopen(temp_exe1, "wb"); //创建第一个释放的生成文件
//将文件指针定位到捆绑器程序尾部
fseek(myself, modify_data.my_length, SEEK_SET);

//读取第一个绑定文件的长度 
fread(&prog1_length, sizeof(prog1_length), 1, myself);

//读取最终文件执行方式(同步或异步执行)
fread(&SyncFlag, sizeof(int), 1, myself) ;

//读取第一个文件内容并写入到新建的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); //关闭第一个绑定文件句柄
totalbytes = 0; //重新清零
out = fopen(temp_exe2, "wb"); //创建第二个释放的生成文件
/*将文件指针定位到最终合成文件中的第二个绑定文件头部, 偏移量 ==(捆绑器自身文件长度+保存第一个绑定文件长度所占字节数+保存最终文件执行标志所占字节数+第一个绑定文件长度)*/
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);
}

……(省略:此部分代码用来关闭文件句柄和决定生成文件的运行方式)
}
3、判断何时捆绑文件,何时又分解释放最终合成文件。
思路:由于本程序采用将捆绑程序自身直接作为最终合成文件的文件头,再把被绑定文件数据附加其后的方式来生成最终合成文件的。所以,只要知道捆绑程序自身的文件长度,根据文件长度是否大于原文件长度,就可判断出是否该释放分解文件了。可在初始化对话框涵数OnInitDialog()增加此判断,及可知道是否是最终合成文件(要不要释放内部绑定文件)。本例程用VC6.0采用静态连接方式生成的Release版,文件长度为184K,大于184K(184*1024)字节,既可判断出该做释放分解操作。
l 故判断是捆绑还是释放文件的代码具体实现如下:
BOOL CBindFileDlg::OnInitDialog()
{
……(省略:此部分代码用于初始化一些变量)

//获取自身文件名到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); //直接退出程序,不显示捆绑程序画面
}
}

以上部分代码的具体实现的细节问题,可在下载实例代码后,仔细查看源码既可(内有详细注释)。

联系方式:
地址:陕西省西安市劳动路2号院六单元
邮编:710082
作者EMAIL:jingzhou_xu@163.net
未来工作室(Future Studio)

发表于 @ 2005年06月15日 23:18:00|评论(loading...)|编辑

新一篇: 最容易的第一个WINDOWS程序 | 旧一篇: 跨进程API Hook

评论

#仆你臭街,垃圾 发表于2005-06-17 02:12:00  IP: 61.186.252.*
白痴
#wsbl52006 发表于2008-10-10 09:48:04  IP: 220.168.210.*
看起来好像还不错啊
#liutao_liutao 发表于2008-10-10 16:51:38  IP: 218.242.159.*
有什么用处??
#zhhbp 发表于2008-10-11 04:29:50  IP: 202.98.222.*
可能是我这里太卡咯 图片么出来
#Elainte 发表于2008-10-20 12:55:16  IP: 61.157.198.*
深奥....
#liuzhourunxin 发表于2008-10-23 15:53:03  IP: 222.84.93.*
真的不错啊!!!!!!
#liuzhourunxin 发表于2008-10-23 15:55:24  IP: 222.84.93.*
真的不错啊!!!!!!
#zy87637854 发表于2008-10-23 19:04:13  IP: 60.9.235.*
不太懂啊
#wskjjj2008 发表于2008-10-27 23:30:29  IP: 117.69.5.*
看不懂,水平太低了,我一定会好好学习的
#sheng123song 发表于2008-11-01 06:39:09  IP: 61.175.229.*
SAFSAF
#XUETUJIAN 发表于2008-11-02 08:38:25  IP: 58.51.89.*
发表评论  


登录
Csdn Blog version 3.1a
Copyright © FreeEIM Studio