⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redlofkillerdlg.cpp

📁 一个可以查杀Redlof病毒的小工具,界面玩具地很,但实现具一定参考价值
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -