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();  
            
forint 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.csdn.net/source/818026
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值