熊猫烧香专杀工具
(注:本篇文章是参考了其他的一些技术文章)
一.终止病毒的进程
终止进程的思路:
- 利用
ToolHelpAPI
获得快照句柄,而后再利用Process32First
和Process32Next
枚举当前的进程,枚举的过程当中获取结构体ProcessEntry32
这个结构体里面的相关信息(包括进程名和进程ID); - 找到目标进程之后,利用OpenProcess获取当前的进程句柄,最后再利用
TerminateProcess
终止病毒进程.
二.删除文件
调用DeleteFile
即可:
Bool DeleteFile (LPCTSTR lpFilename);
把lpFilename设为要指向删除的文件的文件名的指针即可,可以包含具体路径.
三.修改注册表,删除启动项
RegOpenKeyEx()
打开目标主键,并返回句柄,然后利用RegSetValueEx
进行修改键值,最后可以利用RegSetValueEx
来删除键值,最后利用RegCloseKey
来进行关闭;
以上三条为最基本的建议!具体的实际情况还要随机应变,进行适当扩展!
下面来回顾一下分析的熊猫烧香:
先回顾一下这个病毒的几个行为:
- 该病毒首先创建了一个名为“spoclsv.exe”的进程,该进程在系统目录文件下面
- 向外发送数据包,连接上网
- 删除安全类软件在注册表中的启动项
- 在注册表中创建svcshare,用于在开机时启动位于在系统目录下面的创建的spoclsv.exe
- 修改注册表,使得隐藏文件无法通过普通的设置进行显示
- 将自身拷贝至根目录,并命名为"setup.exe",同时创建"autorun.inf"用于病毒的自启动,这两个文件属性都为隐藏.
- 创建名为"Desktop_.ini"的隐藏文件
- 在命令行模式下使用net share命令来取消系统中的共享
针对第二点需要说明的是,由于将病毒本体删除了之后,此问题将得一解决,针对第三点需要说明的是,用户只需自行设置将让杀毒软件关闭即可
故本专杀工具主要面向的是剩下的五点
本工具主要使用MFC来编写,
//1.在内存中查找病毒是否存在
bool C专杀工具Dlg::FindTargetProcrss(char *pszProcessName, DWORD *dwpid)
{
bool bFind = false;
HANDLE hprocessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hprocessSnap ==INVALID_HANDLE_VALUE)
{
return bFind;
}
PROCESSENTRY32 pe = {0};
pe.dwSize = sizeof(pe);
BOOL bRet = Process32First(hprocessSnap,&pe);
while (bRet)
{
if (lstrcmp(pe.szExeFile,(LPCWSTR)pszProcessName)==0)
{
*dwpid = pe.th32ProcessID;
bFind = true;
break;
}
bRet = Process32Next(hprocessSnap,&pe);
}
CloseHandle(hprocessSnap);
return bFind;
}
//2.提升权限,访问一些受限制的系统资源
bool C专杀工具Dlg::EnableDebugPrivilege(char * pszPrivilege)
{
HANDLE hToken = INVALID_HANDLE_VALUE;
LUID luid;
TOKEN_PRIVILEGES tp;
BOOL bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
if (bRet == FALSE)
{
return bRet;
}
bRet = LookupPrivilegeValue(NULL, (LPCWSTR)pszPrivilege, &luid);//这里需要进行类型转换,将pszPrivilege转换成LPCWSTR类型
if (bRet == FALSE)
{
return bRet;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
return bRet;
}
DWORD CRC32(BYTE* ptr, DWORD Size)
{
DWORD crcTable[256], crcTmp1;
//动态生成CRC-32表
for (int i = 0; i < 256; i++)
{
crcTmp1 = i;
for (int j = 8; j > 0; j--)
{
if (crcTmp1 & 1) crcTmp1 = (crcTmp1 >> 1) ^ 0xEDB88320L;
else crcTmp1 >>= 1;
}
crcTable[i] = crcTmp1;
}
//计算CRC32值
DWORD crcTmp2 = 0xFFFFFFFF;
while (Size--)
{
crcTmp2 = ((crcTmp2 >> 8) & 0x00FFFFFF) ^ crcTable[(crcTmp2 ^ (*ptr)) & 0xFF];
ptr++;
}
return (crcTmp2 ^ 0xFFFFFFFF);
}
//主函数:!!!!!!!!!!!!!!!!!!!
void C专杀工具Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//char * pszProcessName;
DWORD dwpid = 0;
bool bRet = false;
CString csTxt;
//1.在内存中查找病毒是否存在,如果找到spoclsv.exe进程,则结束掉它,并删除病毒程序本身
bRet= FindTargetProcrss("spoclsv.exe", &dwpid);
if (bRet == true)
{
CString csTXT = _T("检查系统内存...\r\n");
csTXT += _T("系统中存在病毒内存:spoclsv.exe\r\n");
csTXT += _T("准备进行查杀...\r\n");
SetDlgItemText(IDC_LIST1,csTXT);//IDC_LIST1要与对应的控件IDC对应
//提升权限
bRet = EnableDebugPrivilege((char *)SE_DEBUG_NAME);//这里也要进行类型转换
//
if (bRet == FALSE)
{
csTxt += _T("提升权限失败\r\n");
}
else
{
csTxt += _T("提升权限成功!\r\n");
}
SetDlgItemText(IDC_LIST1, csTxt);
// 打开并尝试结束病毒进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwpid);
if (hProcess == INVALID_HANDLE_VALUE)
{
csTxt += _T("无法结束病毒进程\r\n");
return;
}
bRet = TerminateProcess(hProcess, 0);
if (bRet == FALSE)
{
csTxt += _T("无法结束病毒进程\r\n");
return;
}
csTxt += _T("病毒进程已经结束\r\n");
SetDlgItemText(IDC_LIST1, csTxt);
CloseHandle(hProcess);
}
else
{
csTxt += _T("系统中不存在spoclsv.exe病毒进程\r\n");
}
Sleep(10);
// 查杀磁盘中是否存在名为spoclsv.exe的病毒文件
char szSysPath[MAX_PATH] = { 0 };
GetSystemDirectory((LPWSTR)szSysPath, MAX_PATH);
lstrcat((LPWSTR)szSysPath, (LPCWSTR)"\\drivers\\spoclsv.exe");
csTxt += _T("检查硬盘中是否存在spoclsv.exe文件...\r\n");
if (GetFileAttributes((LPCWSTR)szSysPath) == (DWORD)0xFFFFFFFF)
{
csTxt += _T("spoclsv.exe病毒文件不存在\r\n");
}
else
{
csTxt += _T("spoclsv.exe病毒文件存在,正在计算散列值\r\n");
HANDLE hFile = CreateFile((LPWSTR)szSysPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Error"));
return;
}
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize == 0xFFFFFFFF)
{
AfxMessageBox(_T("GetFileSize Error"));
return;
}
BYTE *pFile = (BYTE*)malloc(dwSize);
if (pFile == NULL)
{
AfxMessageBox(_T("malloc Error"));
return;
}
DWORD dwNum = 0;
ReadFile(hFile, pFile, dwSize, &dwNum, NULL);
// 计算spoclsv.exe的散列值!!!!!!!!!!!!
DWORD dwCrc32 = CRC32(pFile, dwSize);
if (pFile != NULL)
{
free(pFile);
pFile = NULL;
}
CloseHandle(hFile);
// 0x89240FCD是“熊猫烧香”病毒的散列值
if (dwCrc32 != 0x89240FCD)
{
csTxt += _T("spoclsv.exe校验和验证失败\r\n");
}
else
{
csTxt += _T("spoclsv.exe校验和验证成功,正在删除...\r\n");
// 去除文件的隐藏、系统以及只读属性
DWORD dwFileAttributes = GetFileAttributes((LPCWSTR)szSysPath);
dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
SetFileAttributes((LPCWSTR)szSysPath, dwFileAttributes);
// 删除spoclsv.exe
bRet = DeleteFile((LPCWSTR)szSysPath);
if (bRet)
{
csTxt += _T("spoclsv.exe病毒被删除!\r\n");
}
else
{
csTxt += _T("spoclsv.exe病毒无法删除\r\n");
}
}
}
SetDlgItemText(IDC_LIST1, csTxt);
Sleep(10);
///
// 删除每个盘符下的setup.exe与autorun.inf,以及Desktop_.ini
///
char szDriverString[MAXBYTE] = { 0 };
char *pTmp = NULL;
//获取字符串类型的驱动器列表
GetLogicalDriveStrings(MAXBYTE, (LPWSTR)szDriverString);
pTmp = szDriverString;
while (*pTmp)
{
char szAutorunPath[MAX_PATH] = { 0 };
char szSetupPath[MAX_PATH] = { 0 };
lstrcat((LPWSTR)szAutorunPath, (LPCWSTR)pTmp);
lstrcat((LPWSTR)szAutorunPath, (LPCWSTR)"autorun.inf");
lstrcat((LPWSTR)szSetupPath,(LPCWSTR)pTmp);
lstrcat((LPWSTR)szSetupPath, (LPCWSTR)"setup.exe");
if (GetFileAttributes((LPCWSTR)szSetupPath) == 0xFFFFFFFF)
{
csTxt += pTmp;
csTxt += _T("setup.exe病毒文件不存在\r\n");
}
else
{
csTxt += pTmp;
csTxt += _T("setup.exe病毒文件存在,正在进行计算校验和...\r\n");
HANDLE hFile = CreateFile((LPCWSTR)szSetupPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Error"));
return;
}
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize == 0xFFFFFFFF)
{
AfxMessageBox(_T("GetFileSize Error"));
return;
}
BYTE *pFile = (BYTE*)malloc(dwSize);
if (pFile == NULL)
{
AfxMessageBox(_T("malloc Error"));
return;
}
DWORD dwNum = 0;
ReadFile(hFile, pFile, dwSize, &dwNum, NULL);
DWORD dwCrc32 = CRC32(pFile, dwSize);
if (pFile != NULL)
{
free(pFile);
pFile = NULL;
}
CloseHandle(hFile);
if (dwCrc32 != 0x89240FCD)
{
csTxt += _T("校验和验证失败\r\n");
}
else
{
csTxt += _T("校验和验证成功,正在删除...\r\n");
// 去除文件的隐藏、系统以及只读属性
DWORD dwFileAttributes = GetFileAttributes((LPCWSTR)szSetupPath);
dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
SetFileAttributes((LPCWSTR)szSetupPath, dwFileAttributes);
// 删除setup.exe
bRet = DeleteFile((LPCWSTR)szSetupPath);
if (bRet)
{
csTxt += pTmp;
csTxt += _T("setup.exe病毒被删除!\r\n");
}
else
{
csTxt += pTmp;
csTxt += _T("setup.exe病毒无法删除\r\n");
}
}
}
// 去除文件的隐藏、系统以及只读属性
DWORD dwFileAttributes = GetFileAttributes((LPCWSTR)szAutorunPath);
}
(注:本篇文章也是对其他的一些技术文章整理:)