自已写的一段清除Vking病毒文件感染的代码

一次不小心误中了威金病毒(即VKING)的变种,机器上的所有EXE文件都感染了,EXE文件都变成了DOS程序的图标.到网上找遍了杀毒的工具,很遗憾的是没有找到可以真正清除病毒的工具,一般都是直接把文件删除,说是感染了病毒. 由于不想重装系统,有很多东东要装,太累人,没办法,只有自已手动解决.

在清除病毒驻留程序后,要小心不能再点击那些已经病毒感染变成DOS图标的文件,否则就会再次感染.找一个被病毒已经感染的文件,然后找到未被感染的文件(从RAR包里面重新解压出来),然后用16进制编辑器比较后,发现被感染的文件都变大了64K左右,仔细查看后发现感染的文件头与原来的不一样,再查看一下,发现原来就是在文件的前面一段把病毒文件插了进去,在病毒代码的后面就是原来的EXE文件.每个感染的文件都是在64K左右的地方还有一个"MZ"标志.

SO,开始动手清除,先提取病毒段存成一个文件(用它来作匹配查找),由于系统的一些文件也被感染了,所以VC6不能编译MFC,只有用标准的SDK写法,也没有用什么类,一个CPP搞定.主要涉及的地方就是文件的遍历和映射,日志保存和文件备份.全部代码如下 

#include  " stdafx.h "
#pragma  warning(disable:4786)
#include 
< Shlwapi.h >
#include 
< assert.h >
#include 
< iostream >
#include 
< string >
#include 
< vector >
#include 
< fstream >
using   namespace  std;

const  UINT VIRUSLENGTH  =   63018 ; // 病毒原体长度


void  CheckDir( string  str);
void  CheckFile( const   char   * szFile);
LPBYTE MapFile(
const   char   * szFile, HANDLE  & hFile, HANDLE  & hMap,
               DWORD dwLenght 
=  VIRUSLENGTH, BOOL bNew  =  FALSE);
void  ReleaseAll();
void  KillAllVirus();
DWORD GetFileLength(
const   char   * szFile);
void  ErrorLog( const   char   * szFile,  const   char   *  szError);

HANDLE hViruFile 
=  NULL;
BYTE 
*  lpVirus  =  NULL;
HANDLE hViruMap 
=  NULL;
vector
< string >  vec_vf;

int  main( int  argc,  char *  argv[])
{
    
string str("");
    
while(str.empty())
    
{
        cout
<<"please type a dir"<<endl;
        cin
>>str;
        
if(!str.empty() && ::PathFileExists(str.c_str()))
            
break;
    }


    ::DeleteFile(
"log.txt");
    
char szVirus[MAX_PATH];
    GetModuleFileName(NULL,szVirus, MAX_PATH);
    lstrcpy(strrchr(szVirus, 
'/'), "/virus.bak");
    lpVirus 
= MapFile(szVirus, hViruFile, hViruMap);
    
if(lpVirus == NULL)
    
{
        cout 
<< szVirus << "未能成功建立文件映射" <<endl;
        
while(1)
        
{
            
string str;
            cin 
>> str;
            
if(!str.empty())
                
break;
        }
;
        
return 0;
    }

    vec_vf.clear();
    CheckDir(str);
    
if(vec_vf.empty())
    
{
        cout 
<< "未找到病毒文件" <<endl;
        
while(1)
        
{
            
string str;
            cin 
>> str;
            
if(!str.empty())
                
break;
        }
;
        
return 0;
    }

    
else
    
{
        cout
<<"找到病毒文件"<< vec_vf.size() <<"" <<endl;
        cout 
<<"press any key to kill virus" <<endl;

        
while(1)
        
{
            
string str;
            cin 
>> str;
            
if(!str.empty())
                
break;
        }
;

        KillAllVirus();
        cout 
<<"杀毒完成" <<endl;
    }

    ReleaseAll();
    
while(1)
    
{
        
string str;
        cin 
>> str;
        
if(!str.empty())
            
break;
    }
;
    
return 0;
}


void  ReleaseAll()
{
    
if(lpVirus !=NULL)
    
{
        ::UnmapViewOfFile(lpVirus);
        lpVirus 
= NULL;
    }

    
if(hViruMap != NULL)
        CloseHandle(hViruMap);
    
    
if(hViruFile != INVALID_HANDLE_VALUE)
        CloseHandle(hViruFile);

}


LPBYTE MapFile(
const   char   * szFile, HANDLE  & hFile, HANDLE  & hMap, DWORD dwLength , BOOL bNew)
{
    hFile 
= CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, 
        bNew 
? CREATE_NEW : OPEN_EXISTING,    FILE_ATTRIBUTE_NORMAL, NULL);
    
if(hFile == INVALID_HANDLE_VALUE)
    
{
        cout 
<< szFile << "打开失败" <<endl;
        ErrorLog(szFile, 
"打开失败");
        
return NULL;
    }

    hMap 
= ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwLength, NULL);
    
if(hMap == NULL)
    
{
        cout 
<<szFile <<"映射失败" <<endl;
        ErrorLog(szFile, 
"映射失败");
        
return NULL;
    }

    
return (LPBYTE)::MapViewOfFile(hMap, FILE_MAP_WRITE, 00,dwLength);
}



void  CheckDir( string  str)
{
    
//string strExt = "*.*";
    string strFile = str + "/*.*";
    WIN32_FIND_DATA fd;
    HANDLE hf 
= ::FindFirstFile(strFile.c_str(), &fd);
    
if(hf == INVALID_HANDLE_VALUE)
        
return;
    BOOL bWork 
= TRUE;
    
while(bWork)
    
{
        
string strFileName = fd.cFileName;
        
if(strFileName == "." || strFileName == "..")
            ;
        
else if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 
        
{
            
string strNext = str + "/" + fd.cFileName;
            CheckDir(strNext);
        }

        
else if(strFileName.size() > 4 && ((strFileName.substr(strFileName.size() - 44== ".exe")
            
|| (strFileName.substr(strFileName.size() - 44== ".EXE")))
        
{
            
string strCheckFile = str + "/" + strFileName;
            CheckFile(strCheckFile.c_str());
        }

        bWork 
= ::FindNextFile(hf, &fd);
    }

    FindClose(hf);
}



void  CheckFile( const   char   * szFile)
{
    
if(GetFileLength(szFile) < VIRUSLENGTH)
        
return;
    
int  bCheck;
    HANDLE hCheckFile 
= NULL;
    HANDLE hCheckMap 
= NULL;
    LPBYTE lpCheck 
= NULL;

    lpCheck 
= MapFile(szFile, hCheckFile, hCheckMap);
    
if(lpCheck == NULL)
    
{
        cout 
<< szFile << "映射文件失败" <<endl;
        
goto ERRORCHECK;
    }


     bCheck 
= memcmp(lpCheck, lpVirus, VIRUSLENGTH);
    
if(memcmp(lpCheck, lpVirus, VIRUSLENGTH) == 0)
    
{
        cout 
<< "--------发现病毒文件" << szFile <<endl;
        vec_vf.push_back(szFile);
    }

ERRORCHECK:
    
if(lpCheck != NULL)
        ::UnmapViewOfFile(lpCheck);
    
if(hCheckMap != NULL)
        CloseHandle(hCheckMap);
    
if(hCheckFile != NULL)
        CloseHandle(hCheckFile);
}


void  KillAllVirus()
{
    vector
<string>::iterator it;
    
for(it = vec_vf.begin(); it != vec_vf.end(); ++it)
    
{
        
string strNewFile( it->substr(0, it->size() - 3));
        strNewFile 
+= "zjh";
        
int result = ::rename(it->c_str(), strNewFile.c_str());
        
if(result != 0)
        
{
            cout
<< *it << "文件改名备份失败" << endl;
            ErrorLog(it
->c_str(), "文件改名备份失败");
            
continue;
        }

        DWORD dwFileLength 
= GetFileLength(strNewFile.c_str());
        assert(dwFileLength);    
        
        HANDLE hSrcFile, hSrcMap;
        HANDLE hDestFile, hDestMap;
        LPBYTE lpSrc, lpDest;
        FILETIME ftCreate, ftAccess,ftWrite;
        DWORD dwRealLen 
= dwFileLength - VIRUSLENGTH;
        lpSrc 
= MapFile(strNewFile.c_str(), hSrcFile, hSrcMap, dwFileLength);
        lpDest 
= MapFile(it->c_str(), hDestFile, hDestMap, dwRealLen, TRUE);
        
if(hSrcFile != NULL)
            ::GetFileTime(hSrcFile, 
&ftCreate, &ftAccess, &ftWrite);
        
if(lpSrc != NULL && lpDest != NULL)
        
{
            memcpy(lpDest,lpSrc 
+ VIRUSLENGTH, dwRealLen); 
            ::FlushViewOfFile(lpDest, dwRealLen);
        }

        
else if(lpSrc == NULL)
        
{
            cout 
<< strNewFile << "建立映射失败" << endl;
            ErrorLog(strNewFile.c_str(), 
"建立映射失败" );
            
goto Error;
        }

        
else
        
{
            cout 
<< *it << "建立新文件,映射失败" << endl;
            ErrorLog(it
->c_str(), "建立新文件,映射失败" );
            
goto Error;
        }

Error:
        
if(lpSrc != NULL)
            ::UnmapViewOfFile(lpSrc);
        
        
if(lpDest != NULL)
            ::UnmapViewOfFile(lpDest);
        
if(hSrcMap != NULL)
            CloseHandle(hSrcMap);
        
if(hDestMap != NULL)
            CloseHandle(hDestMap);
        
if(hSrcFile != NULL)
            CloseHandle(hSrcFile);
        
if(hDestFile != NULL)
        
{
            ::SetFileTime(hDestFile, 
&ftCreate, &ftAccess, &ftWrite);
            CloseHandle(hDestFile);
        }

    }

}


DWORD GetFileLength(
const   char   * szFile)
{
    HANDLE hFile 
= CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, NULL);
    
if(hFile == INVALID_HANDLE_VALUE)
        
return 0;
    DWORD dwLength 
= ::GetFileSize(hFile, NULL);
    CloseHandle(hFile);
    
return dwLength;
}


void  ErrorLog( const   char   * szFile,  const   char   *  szError)
{
    ofstream f(
"log.txt", ios::app);
    f 
<< szFile << szError <<endl;
    f.close();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值