起因(吹会牛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.重装系统(反正我这么做了)
下载链接:自用修复工具