修复WebCompiler被某病毒后无法打开电子书的问题

编程语言:C++
类    别:(其他)
主要功能:修复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;
}




    最后附上编译后的文件:
   点击下载
posted @ 2007-07-07 12:03  阿牛  阅读(1665)  评论(4编辑  收藏  举报