起因(吹會牛X):
平時只用來寫代碼的筆記本,最近打開MyEclipse居然卡的一匹???WTF,好歹也是I7/16G的啊,仔細一看,連硬盤的儲存空間都快滿了,機智的我果然想到中毒了(????一直以來只有我搞別人的啊,我還被搞了????),然後看了佔硬盤空間多的文件夾,發現是我的幾個web根目錄,再仔細一看,最大的html文件有7.62m?????打開後發現了一段段有趣的代碼,上圖:
發現幾乎所有在硬盤裏的html文件都不能避免,然後無奈的下載了一個360殺毒,掃了一下下,2000多的感染exe和dll,再搞了一下,發現360只能修復exe和dll,而對這些html文件只隔離。搜索引擎了一會,居然沒找到修復工具,我無奈(無聊)啊,好歹也是個代碼狗,超過90秒的工作都交給機器吧,只好自己寫個小工具出來把html文件修復,釋放硬盤空間了。
修復思路:
發現vbs病毒代碼的特徵:
1.特徵碼:
<SCRIPT Language=VBScript><!--DropFileName = "svchost.exe"WriteData = "
2.大小超過200kb的html文件
於是簡要就截取了" <SCRIPT Language=VBScript> ",再每個目錄不斷遍歷超過200k的html文件,並對其讀取文件內容,尋找特徵碼,找到特徵碼之前的所有正常文本內容,刪除源文件,創建同名文件,並把正常文本內容寫入同名文件中,把修復好的html文件記錄下來,搞定。
發現硬盤太大,想出兩種方案
1.全盤遍歷,掃描電腦所有磁盤分區,然後每個分區創造一條新線程去修復本分區
2.種指定路徑。直接拖拉!
說了那麼多沒什麼用的,上代碼,上鍊接!
編譯環境:Visual Studio 2013
(參考了網上一些前輩的代碼)
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <io.h> #include <fstream> #include <atlstr.h> #include <windows.h> //#pragma comment(linker, "/STACK:102400000,102400000") using namespace std; int commonFileSize[2] = { 204800, 1024000 }; int maxSize = 1024 * 1024 * 20; bool delFlag = false; typedef struct pathData { char pathName[]; }PATHDATA; int dealVirusHtml(string filename) { fstream in(filename, ios::in); int fileSize = 0; long index = 0; char* buffer = NULL; if (!in) { cout << "Open the " << filename << " failure...\n"; } in.seekg(0, ios::end); fileSize = in.tellg(); if (fileSize < commonFileSize[0]) return 9; if (fileSize < maxSize) { buffer = (char*)malloc(sizeof(char)*fileSize + 10);//new char[fileSize+10]; } else { fileSize = maxSize; buffer = (char*)malloc(sizeof(char)*maxSize + 10);//new char[maxSize+10]; } in.seekg(0); in.read(buffer, fileSize); in.close(); string content(buffer); index = content.find("<SCRIPT Language=VBScript><!--"); string rs; if (delFlag &&index>0) { rs = filename + " Successful repaired and deleted !! "; remove(filename.data()); } else { rs = filename + " Successful repaired!! "; filename = filename.substr(0, filename.find(".html")) + "_repaired" + ".html"; } if (index > 0) { fstream out(filename, ios::out); content = content.substr(0, index); out.write(content.data(), content.length()); out.close(); } char szFilePath[MAX_PATH]; if (GetModuleFileName(NULL, szFilePath, MAX_PATH)>0) { (*strrchr(szFilePath, '\\')) = '\0';//丟掉文件名,得到路徑 } string logPath(szFilePath); logPath += "\\log.txt"; fstream log(logPath, ios::app | ios::out); log << rs << endl; log.close(); free(buffer); if (buffer != NULL) buffer = NULL; return 6; } //深度優先遞歸遍歷當前目錄下文件夾和文件及子文件夾和文件 void DfsFolder(string path) { _finddata_t file_info; string current_path = path + "/*.*"; //也可以用/*來匹配所有 int handle = _findfirst(current_path.c_str(), &file_info); //返回值爲-1則查找失敗 if (-1 == handle) { cout << "cannot match the path" << endl; return; } do { //判斷是否子目錄 if (file_info.attrib == _A_SUBDIR) { if (strcmp(file_info.name, "..") != 0 && strcmp(file_info.name, ".") != 0) DfsFolder(path + '/' + file_info.name); } else { string filename = file_info.name; if (filename.find(".html") != string::npos) { cout << "path:" << path << "/" << file_info.name << " repairing....." << endl; string html(path + "/"); html += file_info.name; int result = dealVirusHtml(html); if (result == 6) { cout << html << " Successful repaired!! " << endl; } else if (result == 9) { cout << html << " Not infected!! " << endl; } } } } while (!_findnext(handle, &file_info)); //返回0則遍歷完 //關閉文件句柄 _findclose(handle); } DWORD WINAPI WorkThread(LPVOID pM) { PATHDATA *data = (PATHDATA*)pM; DfsFolder(data->pathName); return 0; } int main(int argc, char *argv[]) { cout << "-------------------------------------------------------------------------" << endl; cout << "-------------------------------------------------------------------------" << endl; cout << "-------------------------------------------------------------------------" << endl; cout << "-------------------你要刪除原來的病毒文件嗎?-----------------------------" << endl; cout << "-------------------------------------------------------------------------" << endl; cout << "1.YES 2.NO" << endl; cout << "-------------------------------------------------------------------------" << endl; cout << "----------------------q.quit---------------------------------------------" << endl; int del = 2; cin >> del; if (del == 1) { delFlag = true; } int singal = 2; cout << "------------------------指定路徑(不指定會全盤恢復)-------------------" << endl; cout << "1.YES 2.NO" << endl; cin >> singal; if (singal == 2) { char rootPath[10] = { 0 }; //獲取所有磁盤 UINT nType; for (char a = 'A'; a <= 'Z'; a++) { sprintf(rootPath, "%c:\\", a); nType = GetDriveType(rootPath); if (nType != DRIVE_NO_ROOT_DIR) // DRIVE_NO_ROOT_DIR: 路徑無效 { //遞歸遍歷文件夾 //DfsFolder(rootPath); PATHDATA * data1 = (PATHDATA *)malloc(sizeof(PATHDATA)); strcpy(data1->pathName, rootPath); CreateThread(NULL, 0, WorkThread, data1, 0, NULL); //每個磁盤分區一個線程 } } while (getchar() == 'q' || getchar() == 'Q') { break; }; } else { cout << "------------請輸入要恢復的指定路徑(可以直接拖拉文件夾)?----------" << endl; char disk[512] = { 0 }; cin >> disk; DfsFolder(disk); } getchar(); return 0; }
嗯,效果還不錯!!
至於exe病毒推薦兩個方案:
1.360(感覺效果一般)
2.重裝系統(反正我這麼做了)
下載鏈接:自用修復工具