病毒木馬查殺實戰第017篇:U盤病毒之專殺工具的編寫
阿新 • • 發佈:2019-02-17
BOOL CUVirusKillerDlg::OnDeviceChange( UINT nEventType, // An event type. DWORD dwData // The address of a structure that // contains event-specific data. ) { // The system broadcasts the DBT_DEVICEARRIVAL device event when // a device or piece of media has been inserted and becomes available. if ( nEventType == DBT_DEVICEARRIVAL ) { // 在未對U盤進行查殺之前,令“安全開啟U盤”不可用 m_SafeOpen.EnableWindow(FALSE); SetDlgItemText(IDC_LIST, csTxt); //獲取碟符名稱 GetDriverName(dwData); //顯示可移動磁碟的碟符 CString TmpFile; TmpFile.Format("檢測到可移動磁碟為:%c\r\n", i + 'A'); csTxt += TmpFile; SetDlgItemText(IDC_LIST, csTxt); // 如果成功獲取碟符,則繼續執行 if ( DriverName != "" ) { // 建立CString型別的File,令其儲存autorun.inf的完整路徑 CString File = DriverName; File += "\\autorun.inf"; // 用於儲存由autorun.inf所啟動的程式名 char szBuff[MAX_PATH] = { 0 }; // 判斷可移動磁碟中的autorun.inf檔案是否存在 if ( GetFileAttributes(File.GetBuffer(0)) == -1 ) { csTxt += "在可移動磁碟中沒有檢測到autorun.inf\r\n"; SetDlgItemText(IDC_LIST, csTxt); // 如果當前U盤中不存在autorun.inf,則令“安全開啟U盤”按鈕可用 m_SafeOpen.EnableWindow(TRUE); return FALSE; } csTxt += "在可移動磁碟中檢測到autorun.inf\r\n"; csTxt += "正在解析autorun.inf的啟動內容\r\n"; SetDlgItemText(IDC_LIST, csTxt); // 獲取AutoRun.inf檔案中open後面的內容,即所要自動開啟的可疑檔案 GetPrivateProfileString( "AutoRun", //The name of the section containing the key name. "open", //The name of the key whose associated string is to be retrieved. NULL, //A default string. szBuff, //A pointer to the buffer that receives the retrieved string. MAX_PATH, //The size of the buffer pointed to by the lpReturnedString //parameter, in characters. File.GetBuffer(0) //The name of the initialization file. ); // DelFile儲存由autorun.inf啟動的程式的路徑 CString DelFile = DriverName; DelFile += '\\'; DelFile += szBuff; csTxt += "由autorun.inf啟動的程式為:"; csTxt += DelFile; csTxt += "\r\n正在計算病毒程式的雜湊值...\r\n"; SetDlgItemText(IDC_LIST, csTxt); // 獲取病毒程式的CRC32值 VirusCRC32 = CalcCRC32(DelFile); // 刪除可移動磁碟中的autorun.inf以及由之啟動的檔案,需要首先將病毒程式的屬性調整為NORMAL csTxt += "正在刪除可移動磁碟中的autorun.inf以及由之啟動的程式...\r\n"; SetFileAttributes(File, FILE_ATTRIBUTE_NORMAL); // 刪除autorun.inf BOOL bRet = DeleteFile(File); csTxt += File; if (bRet) { csTxt += _T("病毒程式被刪除!\r\n"); } else { csTxt += _T("病毒程式無法刪除!\r\n"); } SetFileAttributes(DelFile, FILE_ATTRIBUTE_NORMAL); // 刪除由autorun.inf啟動的病毒程式 bRet = DeleteFile(DelFile); csTxt += DelFile; if (bRet) { csTxt += _T("病毒程式被刪除!\r\n"); } else { csTxt += _T("病毒程式無法刪除!\r\n"); } SearchAndDeleteVirus(DriverName); csTxt += _T("U盤修復完畢,您現在可以安全地開啟U盤或修復本地系統!\r\n"); SetDlgItemText(IDC_LIST, csTxt); //令"安全開啟U盤"按鈕可用 m_SafeOpen.EnableWindow(TRUE); } } //The system broadcasts the DBT_DEVICEREMOVECOMPLETE device event //when a device or piece of media has been physically removed. else if ( nEventType == DBT_DEVICEREMOVECOMPLETE ) { //當U盤被拔出時,令"安全開啟U盤"按鈕不可用 m_SafeOpen.EnableWindow(FALSE); } return TRUE; }
編寫“修復本地系統”按鈕事件程式碼
void CUVirusKillerDlg::OnBtnRepair() { // TODO: Add your control notification handler code here csTxt += _T("開始檢測本地系統...\r\n正在檢查登錄檔啟動項...\r\n"); char RegName[]="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\"; DWORD dwType = 0; DWORD dwBufferSize = MAXBYTE; DWORD dwKeySize = MAXBYTE; char szValueName[MAXBYTE] = { 0 }; char szValueKey[MAXBYTE] = { 0 }; //開啟登錄檔啟動項 HKEY hKey = NULL; LONG lRetRun = RegOpenKey(HKEY_LOCAL_MACHINE, RegName, &hKey); if ( lRetRun != ERROR_SUCCESS ) { AfxMessageBox("登錄檔啟動項開啟失敗!"); return ; } int i = 0; while ( TRUE ) { // 列舉鍵項 lRetRun = RegEnumValue(hKey, i, szValueName, &dwBufferSize, NULL, &dwType, (unsigned char *)szValueKey, &dwKeySize); if ( lRetRun == ERROR_NO_MORE_ITEMS ) { break; } // 如果鍵項為6個字元,並且鍵值指向的程式的CRC32指紋與病毒指紋匹配,則關閉病毒程序以及刪除鍵項與病毒本體 if ( lstrlen(szValueName) == 6 && CalcCRC32(szValueKey) == VirusCRC32 ) { BOOL bRet = FALSE; DWORD dwPid = 0; // 刪除病毒的登錄檔啟動項 RegDeleteValue(hKey, szValueName); csTxt += _T("登錄檔啟動項清理完畢!\r\n"); strcat(szValueName, ".EXE"); bRet = FindTargetProcess(szValueName, &dwPid); if(TRUE) { csTxt += _T("檢查系統記憶體...\r\n"); csTxt += _T("系統中存在病毒程序:"); csTxt += szValueName; csTxt += _T("準備進行查殺...\r\n"); SetDlgItemText(IDC_LIST,csTxt); // 提升許可權 bRet = EnableDebugPrivilege(SE_DEBUG_NAME); if (bRet == FALSE) { csTxt += _T("提升許可權失敗\r\n"); } else { csTxt += _T("提升許可權成功!\r\n"); } SetDlgItemText(IDC_LIST,csTxt); // 開啟並嘗試結束病毒程序 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid); if (hProcess == INVALID_HANDLE_VALUE) { csTxt += _T("無法結束病毒程序\r\n"); return ; } bRet = TerminateProcess(hProcess,0); if (bRet == FALSE) { csTxt += _T("無法結束病毒程序\r\n"); return ; } csTxt += _T("病毒程序已經結束\r\n"); SetDlgItemText(IDC_LIST,csTxt); CloseHandle(hProcess); } break; } //清空緩衝區 ZeroMemory(szValueName,MAXBYTE); ZeroMemory(szValueKey, MAXBYTE); i++; } RegCloseKey(hKey); // 刪除自啟動的病毒程式 csTxt += szValueKey; // 獲取病毒程式所在資料夾的路徑 szValueKey[lstrlen(szValueKey)-11] = '\0'; SetFileAttributes(szValueKey, FILE_ATTRIBUTE_NORMAL); BOOL bRet = DeleteDirectory(szValueKey); if (bRet) { csTxt += _T("病毒程式被刪除!\r\n"); } else { csTxt += _T("病毒程式無法刪除!\r\n"); } // 獲取儲存有病毒DLL檔案的資料夾路徑 char tempPath[100]; DWORD dwSize = 100; GetTempPath(dwSize, tempPath); lstrcat(tempPath, "\E_N4"); SetFileAttributes(tempPath, FILE_ATTRIBUTE_NORMAL); // 刪除病毒資料夾 bRet = DeleteDirectory(tempPath); csTxt += tempPath; if (bRet) { csTxt += _T("病毒資料夾被刪除!\r\n"); } else { csTxt += _T("病毒資料夾無法刪除!\r\n"); } SetDlgItemText(IDC_LIST,csTxt); }
至此,所有主要的程式編寫完畢,接下來就可以進行專殺工具的測試了。
專殺工具的測試
這裡我們需要讓本地系統還有U盤保持中毒的狀態,先拔出U盤,然後啟動專殺工具,使其開始進行監控,之後插入U盤,專殺工具就會自動開始查殺:
圖7
此時如果點選“安全開啟U盤”,就會開啟U盤,可以發現此時U盤中已經沒有了病毒程式,並且被隱藏的資料夾也都顯示出來了。如果點選“修復本地系統”,那麼專殺工具會首先結束掉病毒程序,之後再刪除系統中的病毒程式,從而對系統進行徹底的清理。