• 修复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;
    }




        最后附上编译后的文件:
       点击下载
  • 相关阅读:
    基于CentOS构建企业镜像站
    Linux命令——set 和 unset
    Bash基础——命令替换
    Bash基础——内置命令
    Linux命令——logger
    Linux命令——pgrep
    Linux下制作静态库 & 动态库
    理解ld-linux.so.2
    Bash基础——printf
    【问题】man手册如何查看区分printf命令和printf函数
  • 原文地址:https://www.cnblogs.com/evlon/p/809396.html
Copyright © 2020-2023  润新知