病毒木马查杀第004篇:熊猫烧香之专杀工具的编写

一、前言

如果是非感染型的病毒,完成行为分析之后,就可以开始编写专杀工具了。当然对于我们这次研究的对象——“熊猫烧香”来说,其实通过之前的行为分析,我们并没有得出它的所有恶意行为,毕竟还没有对其进行逆向分析。所以这里仅针对我们上一篇文章所得出的结果,来进行专杀工具的编写。一般来说,专杀工具既可以用批处理实现,又可以用编程语言编写,但是现实中更多的还是用后者进行制作的,因为其更加严谨、灵活。因此我这里会使用C++来写一个简单的“熊猫烧香”专杀程序。

二、病毒行为回顾与归纳

这里我们首先回顾一下病毒的行为:

        病毒行为1:病毒本身创建了名为“spoclsv.exe”的进程,该进程文件的路径为“C:\WINDOWS\system32\drivers\spoclsv.exe”。

        病毒行为2:在命令行模式下使用net share命令来取消系统中的共享。

        病毒行为3:删除安全类软件在注册表中的启动项。

        病毒行为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:向外发包,连接局域网中其他机器。

纵观以上八点行为,这里需要说明的是,其中的第二点行为,由于我不知道用户计算机在中毒前的设置,因此这条我打算忽略。第三点行为,我不知道用户的计算机安装了哪些杀毒软件,而病毒又会将所有杀软的注册表启动项删除,所以这一条我打算忽略,用户在使用本专杀工具后,可以自行重新安装杀软,或者有经验的用户也可以自行在注册表中添加回杀软名称。另外,病毒的第八点行为,我也打算忽略,因为只要删除了病毒本体,那么自然就解决了这个问题,所以我的专杀工具主要应付剩下的五个问题。在这里各位读者想必也能够发现,我的专杀工具所要做的工作,与我之前写的手动查杀的过程其实是极为相似的,这也是为什么我当时就强调,我们依旧要掌握手动查杀病毒这个技能的原因。

三、专杀工具界面的制作

如果使用批处理来杀毒,因为它运行时没有界面,因此我们往往不知道杀毒程序究竟干了些什么,也不知道究竟有没有查杀成功,这也凸显了使用高级语言开发专杀工具的优势。这里我使用MFC进行“熊猫烧香”病毒专杀工具的开发,绘制界面如下图所示:

图1 界面绘制

其中的“Edit Box”控件的属性调整如下:

图2 调整“Edit Box”控件的属性

界面非常简单,接下来就是代码的编写。

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

在查杀病毒的技术中有一种方法类似于特征码查杀法,这种方法并不从病毒内提取特征码,而是计算病毒的散列值。利用这个散列值,就可以在查杀的过程中计算每个文件的散列,然后进行比较。这种方法简单易于实现,一般在病毒刚被发现时,在逆向分析前使用。常见的计算散列的算法有MD5、Sha-1以及CRC32等。

这里使用CRC32算法计算散列值,代码如下:

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散列值,可以得到我所研究的“熊猫烧香”病毒的散列值为0x89240FCD。这里请大家注意,不同版本的病毒的散列值是不同的,我所得出的这个值仅针对我所讨论的这个版本的病毒。

五、查找进程与提升权限

我们需要在内存中查找病毒是否存在,代码如下:

BOOL 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;
}

这里还需要提升系统的权限,提升成功后,当前进程就可以访问一些受限的系统资源。代码如下:

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

六、查找并删除Desktop_.ini文件

病毒会在所有盘符下面的非系统目录中创建名为Desktop_.ini的文件,虽说这个文件看似并不会对系统产生什么危害,但是为了实现对“熊猫烧香”的彻底查杀,还是应当将其删除的。这里主要涉及两方面的知识,一个是遍历整个磁盘的文件,这需要使用FindFirstFile()与FindNextFile()这两个API函数,并采用递归调用的方法;另一个是修改文件属性,因为病毒创建出来的文件会带有系统、只读和隐藏这三个属性,若不对其进行更改,是无法删除病毒文件的。依照这个思想,编写代码如下:

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

需要说明的是,这里需要在本程序前定义一个CString类型的csTxt全局变量,用于将查杀的结果信息输出到程序界面,之后的程序中也会用到这个变量。

 

七、主程序的编写

主程序也就是“一键查杀”按钮的响应,我在代码中已添加相应的注释:

void CKillWhBoyDlg::OnBtnKill()
{
    // TODO: Add your control notification handler code here
    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");

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

至此,所有代码编写完毕,将其编译,并没有错误,直接生成可执行文件。

八、专杀工具测试

为了测试本专杀工具,我将它和“熊猫烧香”都拷贝到虚拟机中。首先运行病毒程序,之后再运行本专杀工具,如下图所示:

图3 运行专杀工具查杀病毒

可见,本程序已经将病毒彻底杀除,结合Process Monitor对本程序的监控,可以知道我们的专杀工具是切实可行的,这里不再赘述。

九、小结

因为我们这次所面对的是一个实际的病毒,因此代码显得较长,这和我之前所举的例子中,仅仅几行代码就能够删除一个“虚拟”病毒是截然不同的。在以后面对不同病毒木马的专杀工具的编写中,我还会以这个专杀工具的代码为框架进行制作。而在以后的文章中,我只会对新增的知识点进行叙述,而与这篇文章重合的知识点,我就会一笔带过。也希望各位读者能够彻底掌握本篇文章所讲述的方法。

时间: 11-09

病毒木马查杀第004篇:熊猫烧香之专杀工具的编写的相关文章

病毒木马查杀第008篇:熊猫烧香之病毒查杀总结

一.前言 之前用了六篇文章的篇幅,分别从手动查杀.行为分析.专杀工具的编写以及逆向分析等方面,对"熊猫烧香"病毒的查杀方式做了讨论.相信大家已经从中获取了自己想要的知识,希望大家在阅读完这几篇文章后,能够有一种"病毒也不过如此"的感觉,更希望这些文章能够为有志于在未来参与到反病毒工作的朋友,打下坚实的理论基础.以下就是我在这几篇文章的分析中所总结出来的一些知识点,分为静态分析与动态分析两个方面进行讨论,并加入了一些延伸知识,为大家查漏补缺. 二.病毒的静态分析 静态

病毒木马查杀第011篇:QQ盗号木马之专杀工具的编写

一.前言 由于我已经在<病毒木马查杀第004篇:熊猫烧香之专杀工具的编写>中编写了一个比较通用的专杀工具的框架,而这个框架对于本病毒来说,经过简单修改也是基本适用的,所以本文就不讨论那些重叠的知识,只针对这个病毒特有的方面来讨论专杀工具的编写,然后将其进行组合,就是完整的针对于本病毒的专杀工具了. 二.原理讨论 对于本病毒而言,其最大的特色就在于使用了进程守护技术.病毒运行后,同时有三个病毒进程存在,关闭其中的任何一个,由于还有两个病毒进程的存在,那么被关闭的又会被重新开启.要解决这个问题,不

病毒木马查杀第009篇:QQ盗号木马之手动查杀

一.前言 之前在<病毒木马查杀第002篇:熊猫烧香之手动查杀>中,我在不借助任何工具的情况下,基本实现了对于"熊猫烧香"病毒的查杀.但是毕竟"熊猫烧香"是一款比较简单的病毒,它并没有采取一些特别强的自我保护技术,所以我们完全可以"徒手"解决.但是这次研究的恶意程序就没那么简单,它采取了进程保护的技术,使得我们不能够使用常规手法对其实现查杀.所以这次我引入了两个工具--icesword与autoruns,以达到查杀的目的. 二.病毒的基

病毒木马查杀实战第026篇:“白加黑”恶意程序研究(上)

前言 众所周知,传统的恶意程序都是由单一文件构成的,从而实现某一种或者几种恶意功能.而这类的恶意程序为了避免被发现以及被查杀,往往会采用五花八门的自我隐藏技术以及免杀技术,病毒程序的作者很多时候也是脑洞大开,为了对抗杀软的查杀也是无所不用其极.我们每天所处理的恶意文件里面,反查杀手段运用得最好的就是脚本木马,关于这类程序,我在之前的<病毒木马查杀实战第025篇:JS下载者脚本木马的分析与防御>这篇博文中也做过简单的论述.可是,不论恶意程序如何进化,杀软厂商总有各种各样的方法来应对现有的以及未知

病毒木马查杀第002篇:熊猫烧香之手动查杀

一.前言 作为本系列研究的开始,我选择"熊猫烧香"这个病毒为研究对象.之所以选择这一款病毒,主要是因为它具有一定的代表性.一方面它当时造成了极大的影响,使得无论是不是计算机从业人员,都对其有所耳闻:另一方面是因为这款病毒并没有多高深的技术,即便是在当时来讲,其所采用的技术手段也是很一般的,利用我们目前掌握的知识,足够将其剖析.因此,我相信从这个病毒入手,会让从前没有接触过病毒研究的读者打消对病毒的恐惧心理,在整个学习的过程中开个好头. 本篇文章先研究如何对"熊猫烧香"

病毒木马查杀第006篇:熊猫烧香之逆向分析(中)

一.前言 上一篇文章讲解了"熊猫烧香"病毒样本的反汇编代码入口处的分析,虽然尚未研究到病毒的核心部分,但其实我们后续的分析与之前的思想是一致的.而越到核心部分,可能会遇到越来越多的API函数,结合所调用函数的参数进行分析,反而有助于我们更容易地理解病毒的行为.应当将分析出的每一个CALL函数,改为我们能够理解的名字,这往往也有助于对后续程序的理解. 二.病毒功能分析 上一篇文章的最后,我留下了三个CALL没有分析,现在进入第一个CALL,即sub_408024的内部查看一下: 图1 s

病毒木马查杀第007篇:熊猫烧香之逆向分析(下)

一.前言 这次我们会接着上一篇的内容继续对病毒进行分析.分析中会遇到一些不一样的情况,毕竟之前的代码我们只要按照流程顺序一步一步往下走,就能够弄清楚病毒的行为,但是在接下来的代码中,如果依旧如此,在某些分支中的重要代码就执行不到了,所以我们需要采取一些策略,走完每个分支,彻底分析出病毒的行为. 二.病毒分析 现在程序执行到了loc_408171位置处: 图1 loc_408171起始处的代码 程序首先进行比较操作,由于二者都为0,所以在比较过后ZF=1,那么接下来的跳转并不执行.之后的CALL获

病毒木马查杀第005篇:熊猫烧香之逆向分析(上)

一.前言 对病毒进行逆向分析,可以彻底弄清楚病毒的行为,从而采取更有效的针对手段.为了节省篇幅,在这里我不打算将"熊猫烧香"进行彻底的分析,只会讲解一些比较重要的部分,大家只要掌握了这些思想,那么就可以处理很多的恶意程序了.一般来说,对病毒的静态分析,我们采用的工具是IDA Pro,动态分析则采用OllyDbg.由于后者会使病毒实际运行起来,所以为了安全起见,最好在虚拟机中操作.另外,在实际分析过程中,我们可能还需要一些辅助工具,比如侦壳或脱壳程序等.为了简单起见,这次研究的"

病毒木马查杀实战第018篇:病毒特征码查杀之基本原理

本系列教程版权归"i春秋"所有,转载请标明出处.        本文配套视频教程,请访问"i春秋"(www.ichunqiu.com). 前言 在本系列的导论中,我曾经在"病毒查杀方法"中简单讲解过特征码查杀这种方式.而我也在对于实际病毒的专杀工具编写中,使用过CRC32算法来对目标程序进行指纹匹配,从而进行病毒判定.一般来说,类似于MD5以及CRC32这样的算法,在病毒大规模爆发时是可以提高查杀效率的,但是传统的更为常用的方法是采用以静态分析文