第6篇 熊猫烧香专杀工具编写

Posted sliver呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第6篇 熊猫烧香专杀工具编写相关的知识,希望对你有一定的参考价值。

目录

一、实验清单

二、病毒行为回顾

三、专杀工具的功能

四、专杀工具界面的编写

 五、专杀工具程序的编写

1、计算病毒程序的散列值

2、查找进程

3、提升权限

4、查找并删除文件

5、主程序的编写

六、将程序与MFC结合

 七、实验效果


一、实验清单

        操作系统:windows xp sp3

        软件:hash.exe(吾爱获取)、vc++ 6.0

        熊猫烧香样本:MD5:87551E33D517442424E586D25A9F8522

                                CRC32: 89240FCD

二、病毒行为回顾

        1、病毒本身创建了名为“spoclsv.exe”的进程,该进程文件的路径为“C:\\WINDOWS\\system32\\drivers\\spoclsv.exe”。
        2、在命令行模式下使用net share命令来取消系统中的共享。(X)
        3、删除安全类软件在注册表中的启动项。(X)
        4、在注册表“HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run”中创建“svcshare”,用于在开机时启动位于“C:\\WINDOWS\\system32\\drivers\\spoclsv.exe”的病毒程序。
        5、修改注册表,使得隐藏文件无法通过普通的设置进行显示,该位置为:HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\Hidden\\SHOWALL,病毒将CheckedValue的键值设置为了0。
        6、将自身拷贝到根目录,并命名为“setup.exe”,同时创建“autorun.inf”用于病毒的启动,这两个文件的属性都是“隐藏”。
        7、在一些目录中创建名为“Desktop_.ini”的隐藏文件。
        8、向外发包,连接局域网中其他机器。(X)

        对于病毒的第二条和第三条行为,因为我们实现并不知道私人电脑上的分区如何,也不知道私人电脑上安装了什么杀毒软件,而我们专杀工具的编写注重的是通用性,故不考虑这两点行为。

        对于病毒的第八点行为,一旦我们将病毒进程停止、删除病毒文件,病毒的这点行为也就没了,所以也不考虑这一点。

三、专杀工具的功能

        1、检查系统中的进程,将病毒进程结束掉。并将该进程在硬盘中隐藏的文件删除掉;
        2、全盘检查病毒创建的文件,并删除。这里需要修改病毒文件的属性,并根据校验值来判断病毒文件;
        3、修复病毒对注册表的更改。将病毒从自启动项中删除,以及修复文件的隐藏显示注册表项。

四、专杀工具界面的编写

        该工具用MFC编写,关于具体的MFC知识请参阅相关书籍。

 1、打开VC6.0,新建工程,选择"MFC AppWizard(exe)",命名“工程名称”,“确认”;

2、 选择“基本对话框”,直接“完成”;

 3、建立工程之后,会出现以下界面,选中之后,“delete”删除默认的三个控件;

 4、将如下图所示的两个控件拖入;

 5、适当更改控件的大小,如下图所示;

 6、以编辑框为例,选中编辑框,右键——属性;

 7、在常规栏更改ID为“IDC_LIST”;其实不更改也可以,只是之后代码中,会用到SetDlgItemText函数,需要注意函数中第一个参数与编辑框的ID一致。

 8、如图更改样式栏;

 9、同样的方法进入到按钮框的属性,更改按钮的标题;

 10、同第九部,更改对话框的标题,最终效果:

 五、专杀工具程序的编写

1、计算病毒程序的散列值

        散列值,可以理解为指纹,唯一标识该文件,常用的散列算法:MD5、CRC32、SHA1。

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);

        该函数的参数有两个,一个是指向缓冲区的指针,第二个是缓冲区的长度。它将文件全部读入缓冲区中,然后用CRC32函数计算文件的CRC32散列值。关于自己所用的熊猫烧香样本的CRC32散列值,可以通过hash.exe获取。

2、查找进程

OOL FindTargetProcess(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,pszProcessName) == 0)
        
            *dwPid = pe.th32ProcessID;
            bFind = TRUE;
            break;
        
        bRet = Process32Next(hProcessSnap,&pe);
    

    CloseHandle(hProcessSnap);

    return bFind;

        查找进程的目的是停止病毒进程。

3、提升权限

        目的:访问一些受限的系统资源。

BOOL 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,pszPrivilege,&luid);
    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;

 4、查找并删除文件

DWORD WINAPI FindFiles(LPVOID lpszPath)

 WIN32_FIND_DATA stFindFile;
 HANDLE hFindFile;
 // 扫描路径
 char szPath[MAX_PATH];    
 char szFindFile[MAX_PATH];
 char szSearch[MAX_PATH];
 char *szFilter;
 int len;
 int ret = 0;

 szFilter = "*.*";
 lstrcpy(szPath, (char *)lpszPath);

 len = lstrlen(szPath);
 if(szPath[len-1] != '\\\\')
 
  szPath[len] = '\\\\';
  szPath[len+1] = '\\0';
 

 lstrcpy(szSearch, szPath);
 lstrcat(szSearch,szFilter);

 hFindFile = FindFirstFile(szSearch, &stFindFile);
 if(hFindFile != INVALID_HANDLE_VALUE)
 
     do
  
      lstrcpy(szFindFile, szPath);
            lstrcat(szFindFile, stFindFile.cFileName);

   if(stFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
   
       if(stFindFile.cFileName[0] != '.')
    
        FindFiles(szFindFile);
    
   
   else
   
    if(!lstrcmp(stFindFile.cFileName,"Desktop_.ini"))
    
        // 去除文件的隐藏、系统以及只读属性
     DWORD dwFileAttributes = GetFileAttributes(szFindFile);
                    dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
                    dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
                    dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
     SetFileAttributes(szFindFile, dwFileAttributes);
                    // 删除Desktop_.ini
              BOOL bRet = DeleteFile(szFindFile); 
     csTxt += szFindFile;
     if (bRet)
     
                        csTxt += _T("被删除!\\r\\n");
      
                    else
     
                        csTxt += _T("无法删除\\r\\n");
     
    
   
   ret = FindNextFile(hFindFile, &stFindFile);
  while(ret != 0);
 

 FindClose(hFindFile);

 return 0;

5、主程序的编写

(1)主程序编写思路

    1)查找病毒进程FindTargetProcess();
    2)提升系统权限EnableDebugPrivilege();
    3)打开并尝试结束病毒进程,OpenProcess()、TerminateProcess();
    4)全盘查找病毒文件,如果找到,对比散列值,去除相关属性,删除病毒文件;
    5)修复注册表内容,在自启动项中删除病毒启动项,修复文件的隐藏显示。

(2)程序编写

    //CDialog::OnOK();
	BOOL bRet = FALSE;
    DWORD dwPid = 0; 
///
//  结束spoclsv.exe进程,并删除病毒程序本身
///
    bRet = FindTargetProcess("spoclsv.exe", &dwPid);
    if (bRet == TRUE)
    
        csTxt = _T("检查系统内存...\\r\\n");
        csTxt += _T("系统中存在病毒进程:spoclsv.exe\\r\\n");
        csTxt += _T("准备进行查杀...\\r\\n");
        SetDlgItemText(IDC_LIST,csTxt);   
        // 提升权限
     bRet = EnableDebugPrivilege(SE_DEBUG_NAME);
        if (bRet == FALSE)
  
            csTxt += _T("提升权限失败\\r\\n");
  
        else
  
            csTxt += _T("提升权限成功!\\r\\n");
  
     SetDlgItemText(IDC_LIST,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_LIST,csTxt);
        CloseHandle(hProcess);
    
    else
    
        csTxt += _T("系统中不存在spoclsv.exe病毒进程\\r\\n");
    

    Sleep(10);
    // 查杀磁盘中是否存在名为spoclsv.exe的病毒文件
    char szSysPath[MAX_PATH] =  0 ;
    GetSystemDirectory(szSysPath,MAX_PATH);
    //lstrcat(szSysPath,"\\drivers\\spoclsv.exe");
	lstrcat(szSysPath,"\\\\drivers\\\\spoclsv.exe");

    csTxt += _T("检查硬盘中是否存在spoclsv.exe文件...\\r\\n");

    if (GetFileAttributes(szSysPath) == 0xFFFFFFFF)
    
        csTxt += _T("spoclsv.exe病毒文件不存在\\r\\n");
    
    else
    
        csTxt += _T("spoclsv.exe病毒文件存在,正在计算散列值\\r\\n");

        HANDLE hFile = CreateFile(szSysPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        
            AfxMessageBox("Create Error");
            return ;
        
        DWORD dwSize = GetFileSize(hFile,NULL);
        if (dwSize == 0xFFFFFFFF)
        
            AfxMessageBox("GetFileSize Error");
            return ;
        
        BYTE *pFile = (BYTE*)malloc(dwSize);
        if (pFile == NULL)
        
            AfxMessageBox("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(szSysPath);
            dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
            dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
            dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
   SetFileAttributes(szSysPath, dwFileAttributes);
            // 删除spoclsv.exe
   bRet = DeleteFile(szSysPath);
            if (bRet)
            
                csTxt += _T("spoclsv.exe病毒被删除!\\r\\n");
             
            else
            
                csTxt += _T("spoclsv.exe病毒无法删除\\r\\n");
            
        
      
    SetDlgItemText(IDC_LIST,csTxt);
    Sleep(10);
///
//  删除每个盘符下的setup.exe与autorun.inf,以及Desktop_.ini
///
    char szDriverString[MAXBYTE] =  0 ;  
    char *pTmp = NULL;  
    //获取字符串类型的驱动器列表  
    GetLogicalDriveStrings(MAXBYTE, szDriverString);  

    pTmp = szDriverString;  

    while( *pTmp )  
      
  char szAutorunPath[MAX_PATH] =  0 ;    
  char szSetupPath[MAX_PATH] =  0 ;
        lstrcat(szAutorunPath,pTmp);
  lstrcat(szAutorunPath,"autorun.inf");
        lstrcat(szSetupPath,pTmp);
  lstrcat(szSetupPath,"setup.exe");

        if (GetFileAttributes(szSetupPath) == 0xFFFFFFFF)
  
            csTxt += pTmp;
   csTxt += _T("setup.exe病毒文件不存在\\r\\n");
  
        else
  
            csTxt += pTmp;
   csTxt += _T("setup.exe病毒文件存在,正在进行计算校验和...\\r\\n");
            HANDLE hFile = CreateFile(szSetupPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
            if (hFile == INVALID_HANDLE_VALUE)
   
                AfxMessageBox("Create Error");
                return ;
   
            DWORD dwSize = GetFileSize(hFile,NULL);
            if (dwSize == 0xFFFFFFFF)
   
                AfxMessageBox("GetFileSize Error");
                return ;
   
            BYTE *pFile = (BYTE*)malloc(dwSize);
            if (pFile == NULL)
   
                AfxMessageBox("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(szSetupPath);
                dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
                dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
                dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
    SetFileAttributes(szSetupPath, dwFileAttributes);
    // 删除setup.exe
          bRet = DeleteFile(szSetupPath); 
                if (bRet)
    
                    csTxt += pTmp;
     csTxt += _T("setup.exe病毒被删除!\\r\\n");
     
                else
    
                    csTxt += pTmp;
     csTxt += _T("setup.exe病毒无法删除\\r\\n");
    
   
  
  // 去除文件的隐藏、系统以及只读属性
  DWORD dwFileAttributes = GetFileAttributes(szAutorunPath);
        dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
        dwFileAttributes &= ~FILE_ATTRIBUTE_SYSTEM;
        dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
  SetFileAttributes(szAutorunPath, dwFileAttributes);
        // 删除autorun.inf
  bRet = DeleteFile(szAutorunPath); 
        csTxt += pTmp;
  if (bRet)
           
   csTxt += _T("autorun.inf被删除!\\r\\n");
   
        else
  
   csTxt += _T("autorun.inf不存在或无法删除\\r\\n");
  
  // 删除Desktop_.ini
  FindFiles(pTmp);
  // 检查下一个盘符
        pTmp += 4;  
   
    Sleep(10);
///
//  修复注册表内容,删除病毒启动项并修复文件的隐藏显示
///
    csTxt += _T("正在检查注册表...\\r\\n");
    SetDlgItemText(IDC_LIST,csTxt);
    // 首先检查启动项
    char RegRun[] = "Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run";   
    HKEY hKeyHKCU = NULL;    
    LONG lSize = MAXBYTE;
 char cData[MAXBYTE] =  0 ;

 long lRet = RegOpenKey(HKEY_CURRENT_USER, RegRun, &hKeyHKCU);
    if(lRet == ERROR_SUCCESS)
    
        lRet = RegQueryValueEx(hKeyHKCU,"svcshare",NULL,NULL,(unsigned char *)cData,(unsigned long *)&lSize);
        if ( lRet == ERROR_SUCCESS)
        
            if (lstrcmp(cData,"C:\\\\WINDOWS\\\\system32\\\\drivers\\\\spoclsv.exe") == 0)
            
                csTxt += _T("注册表启动项中存在病毒信息\\r\\n");
            

            lRet = RegDeleteValue(hKeyHKCU,"svcshare");
            if (lRet == ERROR_SUCCESS)
            
                csTxt += _T("注册表启动项中的病毒信息已删除!\\r\\n");
            
            else
            
                csTxt += _T("注册表启动项中的病毒信息无法删除\\r\\n");
            
        
        else
        
            csTxt += _T("注册表启动项中不存在病毒信息\\r\\n");
        
        RegCloseKey(hKeyHKCU);
     
    else
    
        csTxt += _T("注册表启动项信息读取失败\\r\\n");
    
    // 接下来修复文件的隐藏显示,需要将CheckedValue的值设置为1
    char RegHide[] = "SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Advanced\\\\Folder\\\\Hidden\\\\SHOWALL"; 
    HKEY hKeyHKLM = NULL; 
 DWORD dwFlag = 1;

 long lRetHide = RegOpenKey(HKEY_LOCAL_MACHINE, RegHide, &hKeyHKLM);
 if(lRetHide == ERROR_SUCCESS)
 
     csTxt += _T("检测注册表的文件隐藏选项...\\r\\n");
  if( ERROR_SUCCESS == RegSetValueEx(
       hKeyHKLM,             //subkey handle  
                "CheckedValue",       //value name  
                0,                    //must be zero  
                REG_DWORD,            //value type  
                (CONST BYTE*)&dwFlag, //pointer to value data  
                4))                   //length of value data
  
      csTxt += _T("注册表修复完毕!\\r\\n");
  
  else
  
      csTxt += _T("无法恢复注册表的文件隐藏选项\\r\\n");
  
 
///
// 病毒查杀完成
///
 csTxt += _T("病毒查杀完成,请使用专业杀毒软件进行全面扫描!\\r\\n");
    SetDlgItemText(IDC_LIST,csTxt);

六、将程序与MFC结合

1、右击按钮控件,进入“类向导”,给按钮设置一个单击的消息,也就是你单击一下“一键查杀”这个按钮,就可以执行查杀程序。

 2、双击按钮控件,增加成员函数,将其命名为“Onok”,进入;

 3、将主程序写入CPandakillDlg::Onok函数内部;将四个子程序写在CPandakillDlg::Onok函数外部。

4、在文件开头,引入一个“TlHelp32.h”的头文件,并且将四个子函数以及一个CSting变量跟下图一样写,类似全局变量的意思。

 七、实验效果

 

 

 

以上是关于第6篇 熊猫烧香专杀工具编写的主要内容,如果未能解决你的问题,请参考以下文章

熊猫烧香分析报告

什么是“熊猫烧香”啊

熊猫烧香病毒分析

练手之经典病毒熊猫烧香分析(上)

熊猫烧香病毒分析

熊猫烧香病毒-源码学习