Yesky首页| 产品报价| 行情| 手机 | 数码 | 笔记本 | 台式机 | DIY硬件 | 外设 | 网络 | 数字家庭 | 评测 | 软件 | e时代 | 游戏 | 图片 | 壁纸 | 群乐 | 社区 | 博客 | 下载
软件频道>程序开发>JavaVBVCDelphiC/C++Web开发微软专栏移动数据库程序人生软件工程|产品中心下载什么是软件架构
您现在的位置: 天极网 > 开发频道 > 杀毒软件技术之静态查毒引擎的实现
全文

杀毒软件技术之静态查毒引擎的实现

2006-09-03 07:00 作者: 马杰 朱成 出处: 程序员杂志 责任编辑:方舟
  库与引擎类

  清楚了病毒库的构成后,接下来我们看一下具体的扫描方法。关键要把引擎、库与被扫描对象之间的基本关系和分工搞清楚。

  引擎(CEngine)负责被扫描对象的遍历,对应到目前版本的代码上,引擎遍历目录,将找到的文件生成被扫描对象(CScanObj)交给当前病毒库对象的Search()方法。而病毒数据库对象(CVirusDB)则负责在自己管理的库中搜索。为了演示程序的简单,这一版的病毒库没有从文件中加载,而是直接在CVirusDB::Load()中编码进去的。从整体上来看,搜索过程经历了下面3 个阶段:

  1. CEngine遍历目录,生成被扫描对象并把该对象传递到病毒数据库中m_pcVDB->Search(&cScanObj)

  2. 病毒数据库搜索自身的记录CVirusDB::Search(),并调用被扫描对象CFileObject 的Compare()方法进行匹配;

  3. 被扫描对象返回匹配结果,病毒库对象(CVirusDB)根据结果来决定是否是病毒,并返回病毒ID。

  下面就来仔细看看以上提到的每一个关键部分:

  首先是引擎的目录遍历。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<PVRECORD>::iterator iter = m_listVRecords.begin();
while(iter!=m_listVRecords.end())
{
PVRECORD pVRec = *iter;
ASSERT(pVRec);
if(pVRec)
{
bool bVirus = true;
for(unsigned int i=0; i<pVRec->dwSignCount;
i++)
{
bVirus &= pScanObj->Compare
(pVRec->pVSing[i]->dwOffset,
pVRec->pVSing[i]->dwSize,
pVRec->pVSing[i]->Signature);
if(!bVirus) break;
}
// match all signatures
if(bVirus)
{
return pVRec->dwVirusID;
}
}
else
{
// error
return 0xFFFFFFFF;
}
iter++;
}
// no match record in VirusDB
return 0;
}

  While 循环是遍历本病毒库中所有的记录。在For循环中,根据指向VRECORD 结构的指针pVRec中dwSignCount 的内容可知特征码的数量。然后循环用pScanObj->Compare()函数比较每段特征码与文件中指定偏移处的内容是否一致,如果全部一致,则说明该文件是病毒。

  最后,被扫描对象进行特征串的匹配其实就是memcmp,这一步没有什么特别的。

  本次主要为大家介绍了根据特征码查病毒的方法,源代码可以在网站http://bav.netsv.org 下载。在真实的环境中,查毒引擎的设计要比这个例子复杂上很多,一般都有多个库,还利用了诸如脱壳,解压,虚拟机等等技术,这些我们将在日后的文章中逐渐介绍。

共3页。 9 1 2 3
网友关注
最新上市
编辑推荐
欢迎订阅天极网RSS聚合资讯:http://www.yesky.com/index.xml