/ ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <locale.h>
#include <Shlwapi.h>
#include <Shlobj.h>
#pragma comment(lib,"Shlwapi.lib")
//#pragma warning(disable: 4996)
// 宽字符转换为多字符(Unicode --> ASCII)
#define WCHAR_TO_CHAR(lpW_Char, lpChar) \
WideCharToMultiByte(CP_ACP, NULL, lpW_Char, -1, lpChar, _countof(lpChar), NULL, FALSE);
// 多字符转换为宽字符(ASCII --> Unicode)
#define CHAR_TO_WCHAR(lpChar, lpW_Char) \
MultiByteToWideChar(CP_ACP, NULL, lpChar, -1, lpW_Char, _countof(lpW_Char));
//RAR命令
enum RAR_SHELL_TYPE
{
FIND = 1, //查找
DELLPK, //解压缩
};
#define VIR_NAME L"lpk.dll"
#define NORMAL_FILE1 L"c:\\windows\\system32\\lpk.dll"
#define NORMAL_FILE2 L"c:\\windows\\system\\dllcache\\lpk.dll"
bool DelServer(TCHAR *szServerName); //删除服务,包含服务的EXE文件
bool ErrorPrompt();//错误信息
bool DelRegedit(HKEY szMainKey, TCHAR *szRegName);
bool DelFile(TCHAR *szPath);
bool TotalKillName();//全盘查杀 lpk.dll
DWORD WINAPI ThreadFun(LPVOID pM); //每一个磁盘一个线程
void FindNowFile(TCHAR *szPath); //扫描查杀
bool RarShellForLpk(TCHAR *CommandLine, DWORD dwShellType);// 判断压缩包中是否有lpk.exe
void CmdDelShell(TCHAR *szPath);
TCHAR szRarPath[MAX_PATH]; //RAR压缩软件路径
CRITICAL_SECTION g_criticalSection; // 临界区
int _tmain(int argc, _TCHAR* argv[])
{
_wsetlocale(LC_ALL, L"chs");
TCHAR szServerName[] = L"Ghijkl Nopqrstu Wxy";
if (!DelServer(szServerName)) //删除服务
{
// goto OVER;
}
TCHAR szRegName[] = L"SYSTEM\\CurrentControlSet\\services";
HKEY hKey = HKEY_LOCAL_MACHINE;
if (!DelRegedit(hKey, szRegName)) //删除注册表
{
// goto OVER;
}
TCHAR szPath[] = L"C:\\windows\\system32\\hra33.dll";
DelFile(szPath); //删除hra33.dll文件
puts("开始全盘查杀");
TotalKillName(); //全盘查杀,每一个硬盘开启一个线程,可以查杀压缩包中的lpk.dll文件
OVER:
system("pause");
return 0;
}
bool DelServer(TCHAR *szServerName)
{
// TODO: 在此添加命令处理程序代码
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
return ErrorPrompt();
}
//TCHAR szServerName[] = L"iPod Service";//Ghijkl Nopqrstu Wxy
SC_HANDLE hService = OpenService(hSCM, szServerName, SERVICE_ALL_ACCESS);
if (hService == NULL)
{
CloseServiceHandle(hSCM);
return ErrorPrompt();
}
//获取服务配置信息,地址
QUERY_SERVICE_CONFIG SerInfo;
DWORD dwSize = 8 * 1024;
DWORD pcbBytesNeeded = 0;
BOOL bQuersy = QueryServiceConfig(hService, &SerInfo;, dwSize, &pcbBytesNeeded;);
SERVICE_STATUS status;
ControlService(hService, SERVICE_CONTROL_STOP, &status;);
BOOL bDelete = DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
if (bDelete && bQuersy)
{
CmdDelShell(SerInfo.lpBinaryPathName);
puts("删除服务成功!");
return true;
}
else
{
return ErrorPrompt();
}
}
bool ErrorPrompt()
{
DWORD dwError = GetLastError();
LPTSTR lpMsgBuf = nullptr;
//错误码翻译函数
FormatMessage(0x1300, NULL, dwError,
0x400, (LPTSTR)&lpMsgBuf;, 64, NULL);
TCHAR szBuf[128] = { 0 };
wsprintf(szBuf,
_T("出错! %s"), lpMsgBuf);
LocalFree(lpMsgBuf);
wprintf(L"%s\n", szBuf);
return false;
}
bool DelRegedit(HKEY szMainKey, TCHAR *szRegName)
{
HKEY hResult = 0;//\\Ghijkl Nopqrstu Wxy
LONG lReturn = RegOpenKeyEx(szMainKey, szRegName, NULL, KEY_ALL_ACCESS, &hResult;);
if (lReturn != ERROR_SUCCESS)
{
return ErrorPrompt();
}
lReturn = RegDeleteKey(hResult, L"Ghijkl Nopqrstu Wxy");
if (lReturn != ERROR_SUCCESS)
{
return ErrorPrompt();
}
return true;
}
//删除文件
bool DelFile(TCHAR *szPath)
{
BOOL nRet = DeleteFile(szPath);
if (nRet)
return true;
else
return ErrorPrompt();
}
bool TotalKillName()
{
TCHAR szDiskName[MAX_PATH] = { 0 };
GetLogicalDriveStrings(MAX_PATH, szDiskName);
//获取RAR.exe执行路径
TCHAR szTmpRARPath[MAX_PATH] = { 0 };
DWORD dwSize = MAX_PATH;
LONG nRet = SHRegGetValue(HKEY_CLASSES_ROOT, L"WinRAR\\shell\\open\\command", 0, 2, 0, &szTmpRARPath;, &dwSize;);
PathRemoveFileSpec(szTmpRARPath); // 删除路径后面的文件名和’/’符号。该函数可以分析出一个文件的路径。
PathAppend(szTmpRARPath, L"rar.exe");
GetFileAttributes(szTmpRARPath);// 获取到压缩包rar.exe的路径
TCHAR seps[] = L"\"";
TCHAR *token = NULL;
TCHAR *next_token = NULL;
token = _tcstok_s(szTmpRARPath, seps, &next;_token);
GetShortPathName(token, szRarPath, MAX_PATH);
// 初始化临界区
InitializeCriticalSection(&g_criticalSection);
HANDLE phThreadArray[20];
DWORD dwDiskNum = 0; //磁盘数量
// HANDLE phThreadArray1[dwDiskNum];
for (int i = 0; i < szDiskName[i] != '\0'&&i < MAX_PATH; i++)
{
switch (GetDriveType(&szDiskName;[i]))
{
case DRIVE_REMOVABLE://移动硬盘
case DRIVE_FIXED: //硬盘
// case DRIVE_REMOTE://网络驱动器
// case DRIVE_CDROM: //CD-ROM驱动器
{
/*TCHAR tmp[10] = { 0 };
_tcscpy_s(tmp, 10, &szDiskName;[i]);*/
phThreadArray[dwDiskNum] = CreateThread(NULL, 0, ThreadFun, (LPVOID)szDiskName[i], 0, NULL);
dwDiskNum++;
break;
}
default:
break;
}
i += lstrlen(&szDiskName;[i]);
}
// 等待所有线程返回
WaitForMultipleObjects(dwDiskNum, phThreadArray, TRUE, -1);
return true;
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
// 进入临界区
EnterCriticalSection(&g_criticalSection);
//printf("[%d] %c\n", GetThreadId(GetCurrentThread()), szDisk);
TCHAR szPath[10] = { 0 };
szPath[0] = (TCHAR)lpThreadParameter;
_tcscat_s(szPath, 10, L":");
wprintf(L"开始查杀 %s 盘\n", szPath);
FindNowFile(szPath);
// 离开临界区
LeaveCriticalSection(&g_criticalSection);
return 0;
}
void FindNowFile(TCHAR *szPath)
{
WIN32_FIND_DATA stcFindData = { 0 };
TCHAR szSeach[MAX_PATH] = { 0 };
wsprintf(szSeach, L"%s\\*", szPath);
HANDLE hFind = FindFirstFile(szSeach,
&stcFindData;);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
do
{
// 判断当前找到的文件是否是当前或上层目录
if (wcscmp(stcFindData.cFileName, L".") == 0
||
wcscmp(stcFindData.cFileName, L"..") == 0)
{
//如果是其中之一,就结束本次循环
continue;
}
// 判断文件是否是目录,确定插入文件大小
if (stcFindData.dwFileAttributes&FILE;_ATTRIBUTE_DIRECTORY)//目录
{
TCHAR path[MAX_PATH] = { 0 };
swprintf_s(path, L"%s\\%s", szPath, stcFindData.cFileName);
//wprintf(L"目录\n");
FindNowFile(path);
}
else//文件
{
// printf("%s", stcFindData.cFileName);
//组合完整路径
TCHAR szFullPath[600] = { 0 };
TCHAR szShortPath[600] = { 0 };
_tcscpy_s(szFullPath, 600, szPath);
_tcscat_s(szFullPath, 600, L"\\");
_tcscat_s(szFullPath, 600, stcFindData.cFileName);
//转化为短路径
GetShortPathName(szFullPath, szShortPath, MAX_PATH);
LPWSTR strSuffix = PathFindExtension(stcFindData.cFileName); // 获取文件的后缀名
if (_tcscmp(stcFindData.cFileName, VIR_NAME) == 0)
{
//正常文件判断,这二个目录下为正常文件
if (_tcscmp(szFullPath, NORMAL_FILE1) == 0 || _tcscmp(szFullPath, NORMAL_FILE2) == 0)
{
continue;
}
CmdDelShell(szShortPath);
/*BOOL nRet = DeleteFile(szFullPath);
if (nRet)
{
wprintf(L"成功删除:%s\n", szFullPath);
}
else
{
wprintf(L"删除失败:%s\n", szFullPath);
}*/
}
//判断rar zip
else if (_tcscmp(strSuffix, L".rar") == 0 || _tcscmp(strSuffix, L".zip") == 0)
{
//先判断压缩包中有无"lpk.dll"
TCHAR CommandLine[600] = { 0 };
TCHAR Buffer[MAX_PATH] = { 0 };
// PathGetShortPath(szRarPath);
GetTempPath(0x104u, Buffer);
DWORD a = GetCurrentThreadId();
GetTempFileName(Buffer, L"IRAR", a, Buffer);
wsprintfW(CommandLine, L"cmd /c %s vb \"%s\" lpk.dll|find /i \"lpk.dll\"", szRarPath, szShortPath, Buffer);
bool nRet = RarShellForLpk(CommandLine, FIND);// 判断压缩包中是否有lpk.exe
if (nRet)
{
wsprintfW(CommandLine, L"cmd /c %s d %s lpk.dll", szRarPath, szShortPath);
nRet = RarShellForLpk(CommandLine, DELLPK);
if (nRet)
wprintf(L"清理压缩包中病毒成功:%s\n", szFullPath);
else
wprintf(L"清理压缩包中病毒失败:%s\n", szFullPath);
}
}
}
} while (FindNextFile(hFind, &stcFindData;));
return;
}
bool RarShellForLpk(TCHAR *CommandLine, DWORD dwShellType)
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead, hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead;, &hWrite;, &sa;, 0))
{
return ErrorPrompt();
}
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, CommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si;, π))
{
return ErrorPrompt();
}
CloseHandle(hWrite);
char buffer[4096];
memset(buffer, 0, 4096);
DWORD byteRead;
while (true)
{
if (ReadFile(hRead, buffer, 4095, &byteRead;, NULL) == NULL)
{
break;
}
}
switch (dwShellType)
{
case FIND:
{
if (strcmp(buffer, "lpk.dll\r\n") == 0)
return true;
else
return false;
}break;
case DELLPK:
{
char seps[] = "正在删除 lpk.dll\r\n完成";
char *token = NULL;
char *next_token = NULL;
token = strtok_s(buffer, seps, &next;_token);
if (token != NULL)
return true;
else
return false;
}break;
default:
break;
}
}
void CmdDelShell(TCHAR *szPath)
{
TCHAR szTDelShell[300] = { 0 };
wsprintf(szTDelShell,
_T("del /s /q /f /ah %s"), szPath);//地址
char szADelShell[300] = { 0 };
WCHAR_TO_CHAR(szTDelShell, szADelShell);
system(szADelShell);
}