与引擎类
清楚了这两个结构,接下来我们看一下具体的扫描代码。特征串的匹配其实就是memcmp,没有什么特别的,关键讲解一下引擎、库与被扫描对象之间的基本关系和分工。
引擎(CEngine)负责被扫描对象的遍历,病毒数据库对象(CVirusDB)负责在自己管理的库中搜索。对应到目前版本的代码上,引擎遍历目录,将找到的文件生成被扫描对象(CScanObj)交给当前病毒库对象的Search()方法。
CEngine类中DFS()函数是负责文件系统深度优先搜索的函数,其中以下一段就是产生一个对象,然后传递给CVirusDB::Search()方法来查毒:
{ m_cScanResults.dwObjCount++; CFileObject cScanObj; cScanObj.m_eObjType = BO_PHY_FILE; cScanObj.m_strObjName = lpszPathName; if( !cScanObj.Open() ) { // TODO: show error here. return; } DWORD dwVID = m_pcVDB->Search(&cScanObj); if( dwVID ) { PSCAN_RECORD pScanRecord = new SCAN_RECORD; if(pScanRecord) { CFileObject* pScanObj = new CFileObject(cScanObj); pScanRecord->dwVirusID = dwVID; pScanRecord->eResult = BR_WITH_VIRUS; pScanRecord->pScanObject= pScanObj; pScanRecord->pNext = m_cScanResults.pScanRecords; m_cScanResults.pScanRecords = pScanRecord; m_cScanResults.dwRecCount++; } } cScanObj.Close(); }
CVirusDB类中的Search函数是用于在病毒库中匹配特征的成员函数,内容如下:DWORD CVirusDB::Search(CScanObject* pScanObj) { list
}
While循环是遍历本病毒库中所有的记录。在For循环中,根据指向VRECORD结构的指针pVRec中dwSignCount的内容可知特征码的数量。然后循环用pScanObj->Compare()函数比较每段特征码与文件中指定偏移处的内容是否一致,如果全部一致,则说明该文件是病毒。
本次主要为大家介绍了根据特征码查病毒的方法,源代码可以在网站http://bav.netsv.org下载。在真实的环境中,查毒引擎的设计要比这个例子复杂上很多,利用了诸如脱壳,解压,虚拟机等等技术,这些我们将在日后的文章中逐渐介绍。
