📄 redlofkillerdlg.cpp
字号:
return SCAN_OK;
}
//**********************************************************
//函数名:
//功能描述:初始化目标扩展名数组
//@return : 0
//**********************************************************
int CRedLofKillerDlg::InitApp()
{
m_strExt.Add(".htt");
m_strExt.Add(".html");
m_strExt.Add(".htm");
m_strExt.Add(".asp");
m_strExt.Add(".jsp");
m_strExt.Add(".vbs");
m_strExt.Add(".dll");
strcpy(m_lpVirusFlag, "KJ_start");
strcpy(m_lpVirusExecStart, "<script language=vbscript>");
strcpy(m_lpVirusExecEnd, "</script>");
m_bUseToAll = FALSE;
m_handleType = CRedLofKillerDlg::VIRUS_CLEAR;
return 0;
}
//**********************************************************
//函数名:ScanFile
//功能描述:对参数指定的文件进行扫描
//@param: CString& argFile 要被扫描的文件名称
//@return: SCAN_OK 扫描成功
// SCAN_FAILED 扫描失败
//**********************************************************
int CRedLofKillerDlg::ScanFile(CString& argFile)
{
HANDLE hFile; //打开的文件句柄
HANDLE hMapFile; //建立的映象文件句柄
LPVOID lpFile = NULL; //文件被映象到文件中的地址
LPVOID lpFileToWrite = NULL; //要被重新写入带毒文件中的内容
DWORD dwFileSize = 0; //存储文件长度
DWORD dwFileWriteSize = 0; //要被写入文件中的长度(使用此方法实现对病毒的清除)
DWORD dwWrittenSize = 0; //被写入文件中的内容长度
DWORD dwAttrPrev; //存储文件的以前的属性(归档,隐藏或系统...)
DWORD dwPosStart = 0, dwPosEnd = 0; //存储病毒执行体的起始位置和结束位置
DWORD dwErrCode =0; //错误Code
CString strErrMsg; //错误信息
LPCTSTR lpszFile = NULL;
//保存文件原始属性
dwAttrPrev = ::GetFileAttributes(argFile);
//设置文件属性为归档型,方便下面的写回操作
::SetFileAttributes(argFile, FILE_ATTRIBUTE_ARCHIVE);
hFile = ::CreateFile(argFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL, OPEN_EXISTING, dwAttrPrev, NULL);
//如果文件打开失败
if (INVALID_HANDLE_VALUE == hFile)
{
dwErrCode = ::GetLastError();
//如果其他进程正在使用被扫描的文件而导致打开文件出错则忽略
if (32 == dwErrCode)
{
return SCAN_OK;
}
strErrMsg.LoadString(IDS_MSG_FILE_OPEN_FAILED);
strErrMsg.Insert(0,argFile);
AfxMessageBox(strErrMsg);
return SCAN_FAILED;
}
else
{
dwFileSize = ::GetFileSize(hFile,NULL);
//初始化要写回文件的内容为文件的原长度
dwFileWriteSize = dwFileSize;
//如果文件长度==0,不存在感染病毒的可能
//直接返回 ,否则强行为之建立文件map的话
//会失败
if (0 == dwFileSize)
{
::CloseHandle(hFile);
return SCAN_OK;
}
//创建文件映象句柄
hMapFile = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
//如果创建文件映像句柄失败的话
if (NULL == hMapFile)
{
strErrMsg.LoadString(IDS_MSG_FILEMAP_MAKE_FAILED);
strErrMsg.Insert(0,argFile);
AfxMessageBox(strErrMsg);//error handler
//关闭已经打开的文件句柄
::CloseHandle(hFile);
}
else
{
lpFile = ::MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
// 如果映象文件失败的话
if (NULL == lpFile)
{
strErrMsg.LoadString(IDS_MSG_FILEMAPPING_FAILED);
strErrMsg.Insert(0,argFile);
AfxMessageBox(strErrMsg);
::CloseHandle(hMapFile);
::CloseHandle(hFile);
return SCAN_FAILED;
}
DWORD dwErr = ::GetLastError();
//需得先将LPVOID转化成LPTSTR,才能用+操作对不同起始处的内容进行扫描
lpszFile = (LPCTSTR)lpFile;
//在文件映象到的内存中寻找是否有病毒特征字符串
for (DWORD i = 0; i < dwFileSize; i++)
{
if (!::memcmp((const void*)(lpszFile + i), m_lpVirusFlag, strlen((const char*)m_lpVirusFlag)))
{
break;
}
}
//如果找到病毒特征字符串
if (dwFileSize > i)
{
CString strMsg;
strMsg.LoadString(IDS_MSG_INFECTED);
strMsg.Insert(0,argFile);
//计数
m_nInfectedCnt++;
m_lstInfected.AddString(argFile);
::MessageBeep(MB_ICONEXCLAMATION);
//如果文件被感染的话,并且用户没有设置沿用以前的处理方式,提示用户选一种操作模式
if (!m_bUseToAll)
{
::SendMessage(this->m_hWnd, WM_CONFIRM, 0, (LPARAM)(&argFile));
}
dwAttrPrev = ::GetFileAttributes(argFile);
switch (m_handleType)
{
//用户选择删除文件的话
case CRedLofKillerDlg::VIRUS_DEL:
//首先关闭扫描时用的文件映象句柄
::UnmapViewOfFile(lpFile);
::CloseHandle(hMapFile);
::CloseHandle(hFile);
//删除带毒文件
::DeleteFile(argFile);
m_nDelCnt++;
return SCAN_OK; //直接返回
break;
//用户选择清除文件病毒的话
case CRedLofKillerDlg::VIRUS_CLEAR:
//清除带毒文件中的病毒
//清除病毒特征字符串,避免在下次查毒时重复查杀
::memset(( void*)(lpszFile + i), ' ', strlen(m_lpVirusFlag));
//清除病毒的算法大致是这样考虑的
for (; i < dwFileSize; i ++)
{
//如果尚未找到病毒执行体起始字符串的话
if (dwPosStart == 0)
{
//如果找到病毒执行代码的起始字符串的话
//开始进行清除
if (!::memcmp((const void*)(lpszFile + i),
m_lpVirusExecStart, strlen((const char*)m_lpVirusExecStart)))
{
dwPosStart = i;
}
}
else
{ //如果已经找到病毒执行体起始字符串的话
//就继续寻找病毒执行体的结束字符串
if (!::memcmp((const void*)(lpszFile + i),
m_lpVirusExecEnd, strlen((const char*)m_lpVirusExecEnd)))
{
//找到病毒执行体结束字符串的话,就开始清除
dwPosEnd = i;
dwFileWriteSize -= (dwPosEnd - dwPosStart - strlen(m_lpVirusExecStart));
memcpy((void*)(lpszFile + dwPosStart + strlen(m_lpVirusExecStart)),
(const void*)(lpszFile + dwPosEnd),
dwFileSize - dwPosEnd
);
i = dwPosStart + strlen(m_lpVirusExecStart);
dwPosStart = 0;
dwPosEnd = 0;
}
}
} //end of for()
m_nKilledCnt++;
break;
//用户选择忽略处理带毒文件的话
case CRedLofKillerDlg::VIRUS_IGNORE:
//忽略处理带毒文件,直接返回
::UnmapViewOfFile(lpFile);
::CloseHandle(hMapFile);
::CloseHandle(hFile);
::SetFileAttributes(argFile, dwAttrPrev);
m_nIgnoreCnt++;
return SCAN_OK;
break;
}
}
//将不带毒的内容写回文件
lpFileToWrite = malloc(sizeof(BYTE)*dwFileWriteSize);
if (lpFileToWrite)
{
::memcpy(lpFileToWrite, lpFile, dwFileWriteSize);
}
else
{
strErrMsg.LoadString(IDS_MSG_KILL_FAILED);
strErrMsg.Insert(0, argFile);
AfxMessageBox(strErrMsg);
return SCAN_FAILED;
}
//解除文件映像
::UnmapViewOfFile(lpFile);
::CloseHandle(hMapFile);
::CloseHandle(hFile);
hFile = ::CreateFile(argFile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
TRUNCATE_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
::WriteFile(hFile, lpFileToWrite, dwFileWriteSize, &dwWrittenSize, NULL);
::CloseHandle(hFile);
}
::SetFileAttributes(argFile, dwAttrPrev);
//release已经分配的内存资源
free(lpFileToWrite);
lpFileToWrite = NULL;
}
}
return SCAN_OK;
}
//***********************************************************
//函数名称:"开始扫描"按钮响应事件
//函数功能:对指定文件夹进行扫描
//***********************************************************
void CRedLofKillerDlg::OnScanStart()
{
DWORD dwTemp;
if (!m_strFolderScan.IsEmpty())
{
m_nScanTotalCount = 0;
InitCnt();
m_bExitScan = FALSE;
m_hThreadScan = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ScanThread, this, 0, &dwTemp);
//ScanFolder(m_strFolderScan);
}
else
{
CString strMsg;
strMsg.LoadString(IDS_MSG_NO_FOLDER_SET);
AfxMessageBox(strMsg);
}
}
//************************************************************
//函数名称:OnScanStop
//函数功能:"停止扫描"按扭响应事件
//************************************************************
void CRedLofKillerDlg::OnScanStop()
{
m_bExitScan = TRUE;
}
//************************************************************
//函数名称:InitCnt
//函数功能:初始化扫描中用到的计数器变量
//@return 0
//************************************************************
int CRedLofKillerDlg::InitCnt()
{
m_nScanTotalCount = 0;
m_nInfectedCnt = 0;
m_nKilledCnt = 0;
m_nDelCnt = 0;
m_nIgnoreCnt = 0;
return 0;
}
//************************************************************
//函数名称:ScanThread
//函数功能:扫描线程函数
//@param:LPVOID lpParam
//@return :
//************************************************************
DWORD WINAPI CRedLofKillerDlg::ScanThread(LPVOID lpParam)
{
CRedLofKillerDlg * pDlg = (CRedLofKillerDlg*)lpParam;
pDlg->ScanFolder(pDlg->m_strFolderScan);
CString strMsg;
strMsg.Format("共有%d个文件被扫描\n%d个文件被感染,%d个文件被清除,%d个文件被删除,%d个文件被忽略", pDlg->m_nScanTotalCount, pDlg->m_nInfectedCnt, pDlg->m_nKilledCnt, pDlg->m_nDelCnt, pDlg->m_nIgnoreCnt);
AfxMessageBox(strMsg);
return 0;
}
//自定义响应消息
void CRedLofKillerDlg::OnConfirm(WPARAM wParam, LPARAM lParam)
{
CConfirmDlg dlgConfirm(CWnd::FromHandle(this->m_hWnd), (*(CString*)lParam));
dlgConfirm.m_dlgHolder = this;
dlgConfirm.DoModal();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -