推荐.NET教程: ASP.NET C# 开发环境 Ajax教程 控件开发 统计报表 数据库 Web服务 安装部署 CommunityServer NHibernate DataGrid/GridView 实用代码 VS2005
示例源码 MVC/三层 SqlHelper 入门源码 开源 CMS Ajax/Atlas C#.net 毕业设计 源码 经典代码 商业 本站作品 持久层 随书源码 WebService 英文/汉化 Asp.net2.0

阿牛·乐园

每天进步一点点

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  80 随笔 :: 14 文章 :: 389 评论 :: 13 引用
编程语言: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 on 2007-07-07 12:03 阿牛 阅读(750) 评论(4)  编辑 收藏 网摘 所属分类: C++

评论

很有效果!强烈支持!
  回复  引用    

#2楼  2008-04-06 19:20 unicornxc [未注册用户]
真是踏破铁鞋无觅处,网上搜索多时,终于找到如此快捷的修复方式,感谢博主了。你的博客很有技术含量,先收藏了
  回复  引用    

#3楼  2008-04-08 17:27 hjszy [未注册用户]
请问如何使用?谢谢!
  回复  引用    

#4楼  2008-10-30 19:29 飞到 [未注册用户]
为什么,执行后,窗口内没反映?
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: