任何文件在其尾部追加二进制信息后,都不会影响到该文件的正常使用,我们能够看到的,仅仅只是增加了字节数,创建日期,修改日期等都没有任何变化,因此一 般寄生型病毒一般都采取这种方式进行传播。我们以C#语言为例,选择任何一个文件作为宿主文件(最好不要选择文本文件,原因是文本文件会产生乱码在尾 部),然后选择一个寄生文件,来进行隐藏。为了便于寄生文件的检索、释放、删除,我们需要在寄生文件中加入一些分隔标志、长度信息、寄生文件名。如我们以 “%**@@”作为开始分隔符;寄生文件长度用9个字节,不够补空格;寄生文件名用200个字节,不够补空格,附加信息的总长度是216字节。
具体实现思路如:
1. 打开文件
//
打开宿主文件
FileStream mother_file
=
new
FileStream(mother_name ,FileMode.OpenOrCreate);
//
读出流到buff中
mother_file.Read(buff,
0
,(
int
)mother_file.Length);
2. 显示寄生文件的信息
public
void
review_files
{
listBox1.Items.Clear();
for( int i=0 ;i<=mother_file.Length ; i++)
{
if(buff[i]=='%'&&buff[i+1]=='*'&&buff[i+2]=='*'&&buff[i+3]=='#'&&buff[i+4]=='#'&&buff[i+5]=='@')
//隐藏文件分隔符 %**##··
{
mother_file.Seek(i+7,0) ; //跳过分隔符
byte [] filesize=new byte[9];
mother_file.Read(filesize,0,9);// 读9位文件大小
byte [] filename=new byte[200];
mother_file.Read(filename,0,200);//读200位文件名
String name=System.Text.Encoding.Default.GetString(filename,0,200);
String len=System.Text.Encoding.Default.GetString(filesize,0,9);
String offset=(i+216).ToString(); //寄生文件的位置(偏移量)
name=name.Substring(0,name.IndexOf('/0'));
name=(name+" ").Substring(0,40);
//格式化文件名为40位 len=len.Substring(0,len.IndexOf('/0'));
len=(len +" ").Substring(0,20);
//格式化文件大小为20位 String str=name+len+offset;
listBox1.Items.Add( str);
listBox1.Refresh();
}
}

}
3. 追加寄生文件
try
{
mother_file.Seek(0, SeekOrigin.End); //宿主文件尾部
}
catch
{ MessageBox.Show("宿主未打开"); return;
}
DateTime creat_old
=
File.GetCreationTime(textBox2.Text);
//
暂存文件创建时间
DateTime write_old
=
File.GetLastWriteTime(textBox2.Text);
//
暂存文件修改时间
openFileDialog1.ShowDialog();
FileStream in_file
=
new
FileStream(openFileDialog1.FileName,FileMode.Open);
byte
[] in_buff
=
new
byte
[in_file.Length];
in_file.Read(in_buff,
0
,(
int
)in_file.Length);
//
读出拟寄生文件流
mother_file.Write(System.Text.Encoding.Default.GetBytes(
"
%**##@@
"
),
0
,
7
);
//
写入分隔符
byte
[] len
=
new
byte
[
9
];
len
=
System.Text.Encoding.Default.GetBytes( in_file.Length.ToString());
mother_file.Write(len ,
0
,len.Length);
//
写入拟寄生文件的的大小
byte
[] temp
=
new
byte
[
9
-
len.Length];
mother_file.Write(temp ,
0
,temp.Length);
//
补空凑为9个字节
byte
[] name
=
new
Byte[
200
];
name
=
System.Text.Encoding.Default.GetBytes( openFileDialog1.FileName);
mother_file.Write(name,
0
,name.Length);
byte
[] temp2
=
new
byte
[
200
-
name.Length];
//
补空凑为200个字节
mother_file.Write(temp2,
0
,temp2.Length);
mother_file.Write(in_buff,
0
,(
int
)in_file.Length);
//
写入拟寄生文件流
in_file.Close();
string
mother_name
=
textBox2.Text;
//
暂存宿主文件名
mother_file.Close();
//
关闭宿主
File.SetCreationTime(mother_name,creat_old);
//
恢复旧的文件创建时间
File.SetLastWriteTime(mother_name,write_old);
//
恢复旧的文件修改时间
open_mother(mother_name);
//
打开宿主
review_files();
//
显示寄生文件
4. 释放寄生文件
String position
=
""
,file_long
=
""
, file_name
=
""
;
string
[] aa
=
new
string
[
3
];
//
定义文件信息数组
try
{
aa=fetch();//取拟释放文件信息
}
catch
{
MessageBox.Show("未选择文件"); return;
}
position
=
aa[
0
];
//
寄生文件的位置
file_long
=
aa[
1
];
//
寄生文件的大小
file_name
=
aa[
2
];
//
寄生文件的文件名
FileStream out_file
=
new
FileStream(textBox1.Text
+
"
//
"
+
file_name,FileMode.Create);
//
创建释放文件
byte
[] out_buff
=
new
byte
[buff.Length];
try
{
mother_file.Seek(int.Parse(position),SeekOrigin.Begin);
//定位寄生文件在宿主中的位置
}
catch
{
MessageBox.Show("宿主未打开");return;
}
mother_file.Read(out_buff,
0
,
int
.Parse(file_long));
//
读取拟释放文件流
out_file.Write(out_buff,
0
,
int
.Parse(file_long));
//
写入释放文件
out_file.Close();
5. 删除寄生文件
DateTime creat_old
=
File.GetCreationTime(textBox2.Text);
//
暂存文件创建时间
DateTime write_old
=
File.GetLastWriteTime(textBox2.Text);
//
暂存文件修改时间

String position
=
""
,file_long
=
""
, file_name
=
""
;
string
[] aa
=
new
string
[
3
];
try
{
aa=fetch();//取拟删除文件信息
}
catch
{
MessageBox.Show("未选择文件"); return;
}
position
=
aa[
0
];
file_long
=
aa[
1
];
file_name
=
aa[
2
];
int
mother_long;
try
{
mother_long=(int)mother_file.Length;
}
catch
{
MessageBox.Show("宿主未打开");return;
}

byte
[] del_buff
=
new
byte
[mother_long
-
int
.Parse(file_long)
-
216
];
//
在宿主中定位拟删除文件位置(含216位头信息)
Array.Copy(buff,
0
,del_buff,
0
,
int
.Parse(position)
-
216
);
//
宿主中拟删除文件前面的信息复制到del_buff中
Array.Copy(buff,
int
.Parse(position)
+
file_long.Length,del_buff,
int
.Parse(position)
-
216
,(
int
)mother_file.Length
-
int
.Parse(position)
-
int
.Parse(file_long));
//
宿主中拟删除文件后面的信息复制到del_buff中
FileStream temp_file
=
new
FileStream(
"
temp
"
,FileMode.Create);
//
创建 临时文件temp
temp_file.Write(del_buff,
0
,del_buff.Length);
//
del_buff写入temp中
temp_file.Close();
//
String old_mother=textBox2.Text.ToString();
string
mother_name
=
textBox2.Text;
//
暂存宿主文件名
mother_file.Close();
//
关闭宿主文件
File.Delete(mother_name);
//
删除旧的宿主文件
File.Copy(
"
temp
"
,mother_name);
//
复制temp为新的宿主文件
File.Delete(
"
temp
"
);
//
删除临时文件
File.SetCreationTime(mother_name,creat_old);
//
恢复旧的文件创建时间
File.SetLastWriteTime(mother_name,write_old);
//
恢复旧的文件修改时间
open_mother(mother_name);
//
打开新的宿主文件
review_files();
//
显示新宿主中的信息
附FETCH函数
private
string
[] fetch()
//
取出 {
String list_str
=
listBox1.SelectedItem.ToString();
String position
=
""
,file_long
=
""
, file_name
=
""
;
file_name
=
list_str.Substring(
0
,
40
);
//
取出前40位,内含文件名
file_name
=
file_name.Substring(
0
,file_name.IndexOf(
'
'
));
//
去尾空格
int
i;
for
( i
=
file_name.Length
-
1
; i
>=
0
; i
--
)
{
if(file_name[i]=='//')break;
}
//
定位除去路径的文件名的位置
file_name
=
file_name.Substring(i
+
1
,file_name.Length
-
i
-
1
);
//
取出文件名
file_long
=
list_str.Substring(
40
,
9
);
//
取出文件大小
file_long
=
file_long.Substring(
0
,file_long.IndexOf(
'
'
));
//
去尾空格
position
=
list_str.Substring(
60
,list_str.Length
-
60
);
//
取出寄生文件位置
string
[] aa
=
new
string
[
3
];
aa[
0
]
=
position;aa[
1
]
=
file_long; aa[
2
]
=
file_name;
return
(aa);
//
返回包含寄生文件信息的String数组
}
本方法中原有文件功能均正常,创建、修改时间均未变化,仅仅是长度大了些,隐蔽性还是比较强的,如果对写入的信息进行简单的加密操作则效果更好。
警告:
这里仅供研究探讨使用,如用于任何破坏性目的后果自负。
例子源码下载: http://download.youkuaiyun.com/source/818026
具体实现思路如:
1. 打开文件
































3. 追加寄生文件

































4. 释放寄生文件





























5. 删除寄生文件







































































警告:
这里仅供研究探讨使用,如用于任何破坏性目的后果自负。
例子源码下载: http://download.youkuaiyun.com/source/818026