类 别:(其他)
主要功能:修复WebCompiler被某病毒后,无法打开电子书的问题
说明:有种病毒在电子书最后几个字节加上了一些代码.
先看一下文件最后4个字节
红线上的部分,是多出来的几个字节,就是它造成了电子书不能打开!!
由于我有好多电子书,要是手动改,也太麻烦了.所以写了一个工具,希望有遇到我和一样烦恼的人,可以重新修复电子书.
修复前要备份电子书呀,我不敢保证所有病毒都这样破坏我们的电子书
下面我们来看看代码实现
// FixBOOK.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <list>
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <ctype.h>
using namespace std;
typedef std::wstring tstring;
void VERIFY(BOOL exp)
{
}
class FileOperator
{
public:
virtual void operator()(const tstring& path, LPWIN32_FIND_DATA pfdd) = NULL;
};
bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir, FileOperator* fileOperator = NULL);
class FixEBOOK : public FileOperator
{
protected:
bool IsHasVirus(FILE* pfile)
{
BYTE endFlag[] = {0xef,0x51,0x2a,0x01};
VERIFY(0 == ::fseek(pfile,-8,SEEK_END));
BYTE buf[8];
int nBufSize = sizeof(buf)/ sizeof(buf[0]);
::ZeroMemory(buf,nBufSize);
VERIFY(nBufSize == ::fread_s(buf,nBufSize,sizeof(BYTE),nBufSize,pfile));
if(::memcmp(endFlag,buf + 4,4) == 0)
{
//是电子书,且格式正确
wcout << _T("是电子书,且格式正确") ;
return false;
}
else if(::memcmp(endFlag,buf,4) == 0)
{
//是电子书,但已被破坏
wcout << _T("是电子书,但已被破坏") ;
return true;
}
else
{
//好像不是电子书
wcout << _T("好像不是电子书") ;
return false;
}
}
bool FixVirusBook(FILE* pfile, FILE* pfileOK)
{
::fseek(pfile,0,SEEK_END);
long nSize = ::ftell(pfile);
::fseek(pfile,0,SEEK_SET);
BYTE buf[1024];
for(long i = nSize - 4,n = 0; i > 0; i-=n)
{
n = (long)::fread_s(buf,1024,sizeof(BYTE), min(i,1024),pfile);
::fwrite(buf,sizeof(BYTE),n,pfileOK);
}
return true;
}
bool TryFixVirusBook(tstring file)
{
FILE* pfile = NULL;
errno_t errCode = ::_tfopen_s(&pfile, file.c_str(),_T("r+b"));
if(errCode != 0)
return false;
bool bRet = false;
wcout << endl << _T("EBOOK:") << file << endl;
if(IsHasVirus(pfile))
{
tstring fileOK(file + _T(".fix"));
FILE* pfileOK = NULL;
errCode = ::_tfopen_s(&pfileOK, fileOK.c_str(),_T("w+b"));
if(errCode == 0)
{
VERIFY(this->FixVirusBook(pfile,pfileOK));
::fclose(pfileOK);
::fclose(pfile);
::_tremove(file.c_str());
::_trename(fileOK.c_str(), file.c_str());
wcout << _T("修复完成!!");
return true;
}
else
{
::fclose(pfile);
return false;
}
}
else
{
::fclose(pfile);
return false;
}
}
public:
void operator()(const tstring& path, LPWIN32_FIND_DATA pfd)
{
WIN32_FIND_DATA& fd = *pfd;
tstring file(path + _T("\\") + fd.cFileName);
tstring fileExt = file.substr(file.rfind('.'));
transform(fileExt.begin(),fileExt.end(),fileExt.begin(),tolower);
if(fileExt != _T(".exe"))
return;
DWORD dwNewAttributes = fd.dwFileAttributes;
if(dwNewAttributes & FILE_ATTRIBUTE_READONLY)
dwNewAttributes^= FILE_ATTRIBUTE_READONLY;
if(dwNewAttributes & FILE_ATTRIBUTE_SYSTEM)
dwNewAttributes^= FILE_ATTRIBUTE_SYSTEM;
if(dwNewAttributes & FILE_ATTRIBUTE_HIDDEN)
dwNewAttributes^= FILE_ATTRIBUTE_HIDDEN;
bool bSet = false;
if(dwNewAttributes != fd.dwFileAttributes)
{
::SetFileAttributes(file.c_str(), dwNewAttributes);
bSet = true;
}
//操作
this->TryFixVirusBook(file);
if(bSet)
{
::SetFileAttributes(file.c_str(), fd.dwFileAttributes);
}
return;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
locale loc(""),oldloc;
oldloc=wcout.imbue(loc);//设置以便输出中文
TCHAR szCurrentPath[MAX_PATH];
::GetCurrentDirectory(MAX_PATH,szCurrentPath);
//声明操作
FixEBOOK oper;
//遍历每个文件,进行操作
FindPathFiles(szCurrentPath,_T(".exe"),true, &oper);
wcout << endl << endl << "修改完成" << endl;
wcin.get();
wcout.imbue(oldloc); //用完恢复
return 0;
}
bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir, FileOperator* fileOperator/* = NULL*/)
{
WIN32_FIND_DATA fd;
list<tstring> directories;
directories.push_back(tstring(pPath));
while(directories.size() > 0)
{
tstring path = directories.front();
directories.pop_front();
tstring pathFind = path + _T("\\*");
HANDLE hFind = NULL;
hFind = ::FindFirstFile(pathFind.c_str(),&fd);
if (hFind == INVALID_HANDLE_VALUE)
{
return false;
}
bool bFinished = false;
while(!bFinished)
{
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
//是目录
tstring strFileName(fd.cFileName);
if(includeSubdir)
{
if(strFileName != _T(".") && strFileName != _T(".."))
{
directories.push_back(path + _T("\\") + strFileName);
}
}
}
else
{
if(fileOperator)
{
(*fileOperator)(path, &fd);
}
else
{
wcout << fd.cFileName << endl;
}
}
BOOL bRet = ::FindNextFile(hFind,&fd);
if(!bRet)
{
bFinished = true;
}
}
::FindClose(hFind);
}
return true;
}
//
#include "stdafx.h"
#include <windows.h>
#include <list>
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <ctype.h>
using namespace std;
typedef std::wstring tstring;
void VERIFY(BOOL exp)
{
}
class FileOperator
{
public:
virtual void operator()(const tstring& path, LPWIN32_FIND_DATA pfdd) = NULL;
};
bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir, FileOperator* fileOperator = NULL);
class FixEBOOK : public FileOperator
{
protected:
bool IsHasVirus(FILE* pfile)
{
BYTE endFlag[] = {0xef,0x51,0x2a,0x01};
VERIFY(0 == ::fseek(pfile,-8,SEEK_END));
BYTE buf[8];
int nBufSize = sizeof(buf)/ sizeof(buf[0]);
::ZeroMemory(buf,nBufSize);
VERIFY(nBufSize == ::fread_s(buf,nBufSize,sizeof(BYTE),nBufSize,pfile));
if(::memcmp(endFlag,buf + 4,4) == 0)
{
//是电子书,且格式正确
wcout << _T("是电子书,且格式正确") ;
return false;
}
else if(::memcmp(endFlag,buf,4) == 0)
{
//是电子书,但已被破坏
wcout << _T("是电子书,但已被破坏") ;
return true;
}
else
{
//好像不是电子书
wcout << _T("好像不是电子书") ;
return false;
}
}
bool FixVirusBook(FILE* pfile, FILE* pfileOK)
{
::fseek(pfile,0,SEEK_END);
long nSize = ::ftell(pfile);
::fseek(pfile,0,SEEK_SET);
BYTE buf[1024];
for(long i = nSize - 4,n = 0; i > 0; i-=n)
{
n = (long)::fread_s(buf,1024,sizeof(BYTE), min(i,1024),pfile);
::fwrite(buf,sizeof(BYTE),n,pfileOK);
}
return true;
}
bool TryFixVirusBook(tstring file)
{
FILE* pfile = NULL;
errno_t errCode = ::_tfopen_s(&pfile, file.c_str(),_T("r+b"));
if(errCode != 0)
return false;
bool bRet = false;
wcout << endl << _T("EBOOK:") << file << endl;
if(IsHasVirus(pfile))
{
tstring fileOK(file + _T(".fix"));
FILE* pfileOK = NULL;
errCode = ::_tfopen_s(&pfileOK, fileOK.c_str(),_T("w+b"));
if(errCode == 0)
{
VERIFY(this->FixVirusBook(pfile,pfileOK));
::fclose(pfileOK);
::fclose(pfile);
::_tremove(file.c_str());
::_trename(fileOK.c_str(), file.c_str());
wcout << _T("修复完成!!");
return true;
}
else
{
::fclose(pfile);
return false;
}
}
else
{
::fclose(pfile);
return false;
}
}
public:
void operator()(const tstring& path, LPWIN32_FIND_DATA pfd)
{
WIN32_FIND_DATA& fd = *pfd;
tstring file(path + _T("\\") + fd.cFileName);
tstring fileExt = file.substr(file.rfind('.'));
transform(fileExt.begin(),fileExt.end(),fileExt.begin(),tolower);
if(fileExt != _T(".exe"))
return;
DWORD dwNewAttributes = fd.dwFileAttributes;
if(dwNewAttributes & FILE_ATTRIBUTE_READONLY)
dwNewAttributes^= FILE_ATTRIBUTE_READONLY;
if(dwNewAttributes & FILE_ATTRIBUTE_SYSTEM)
dwNewAttributes^= FILE_ATTRIBUTE_SYSTEM;
if(dwNewAttributes & FILE_ATTRIBUTE_HIDDEN)
dwNewAttributes^= FILE_ATTRIBUTE_HIDDEN;
bool bSet = false;
if(dwNewAttributes != fd.dwFileAttributes)
{
::SetFileAttributes(file.c_str(), dwNewAttributes);
bSet = true;
}
//操作
this->TryFixVirusBook(file);
if(bSet)
{
::SetFileAttributes(file.c_str(), fd.dwFileAttributes);
}
return;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
locale loc(""),oldloc;
oldloc=wcout.imbue(loc);//设置以便输出中文
TCHAR szCurrentPath[MAX_PATH];
::GetCurrentDirectory(MAX_PATH,szCurrentPath);
//声明操作
FixEBOOK oper;
//遍历每个文件,进行操作
FindPathFiles(szCurrentPath,_T(".exe"),true, &oper);
wcout << endl << endl << "修改完成" << endl;
wcin.get();
wcout.imbue(oldloc); //用完恢复
return 0;
}
bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir, FileOperator* fileOperator/* = NULL*/)
{
WIN32_FIND_DATA fd;
list<tstring> directories;
directories.push_back(tstring(pPath));
while(directories.size() > 0)
{
tstring path = directories.front();
directories.pop_front();
tstring pathFind = path + _T("\\*");
HANDLE hFind = NULL;
hFind = ::FindFirstFile(pathFind.c_str(),&fd);
if (hFind == INVALID_HANDLE_VALUE)
{
return false;
}
bool bFinished = false;
while(!bFinished)
{
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
//是目录
tstring strFileName(fd.cFileName);
if(includeSubdir)
{
if(strFileName != _T(".") && strFileName != _T(".."))
{
directories.push_back(path + _T("\\") + strFileName);
}
}
}
else
{
if(fileOperator)
{
(*fileOperator)(path, &fd);
}
else
{
wcout << fd.cFileName << endl;
}
}
BOOL bRet = ::FindNextFile(hFind,&fd);
if(!bRet)
{
bFinished = true;
}
}
::FindClose(hFind);
}
return true;
}
最后附上编译后的文件:
点击下载