C#实现文件寄生隐藏

来源:互联网 发布:lol意思网络用语 编辑:程序博客网 时间:2024/04/29 17:15
 

C#实现文件寄生隐藏

任何文件在其尾部追加二进制信息后,都不会影响到该文件的正常使用,我们能够看到的,仅仅只是增加了字节数,创建日期,修改日期等都没有任何变化,因此一般寄生型病毒一般都采取这种方式进行传播。我们以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 =='%'&&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=='//')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://www.netcsharp.cn/showtopic-603.aspx