分享
 
 
 

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

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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

作者:徐景周

下载示例程序代码(http://www.csdn.net/cnshare/soft/10/10356.shtm)

将多个文件合并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了合并前的多个文件。这种程序在木马程序合并中会经常用到,你想知道它是怎么用程序实现的么?下面我就拿我用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)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有