修復VBS病毒感染的html文件

起因(吹會牛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.重裝系統(反正我這麼做了)


下載鏈接:自用修復工具


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章