www.pudn.com > BAV.v2.rar > VirusDB.cpp, change:2005-08-21,size:8679b
#include "StdAfx.h"
#include "VirusDB.h"
#include "ScanObject.h"
#include "ParsePE.h"
CVirusDB::CVirusDB(void)
{
}
CVirusDB::~CVirusDB(void)
{
}
bool CVirusDB::Load(const char* pszDBFile)
{
// not really load from file at this version
PVRECORD pVRecord;
/*
//////////////////////////////////////////////////////////////////////////
//
// add standard eicar virus
//
pVRecord = new VRECORD;
if(pVRecord==NULL)
return false;
pVRecord->nSize = sizeof(VRECORD);
pVRecord->dwVirusID = 1;
pVRecord->dwSignCount = 3;
pVRecord->dwTreatCount = 0;
static VSIGNATURE aVSign1[3]=
{
// Orig. Offset: 0
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 0, 32, BL_EQUAL,
0x58, 0x35, 0x4F, 0x21, 0x50, 0x25, 0x40, 0x41, 0x50, 0x5B, 0x34, 0x5C, 0x50, 0x5A, 0x58, 0x35,
0x34, 0x28, 0x50, 0x5E, 0x29, 0x37, 0x43, 0x43, 0x29, 0x37, 0x7D, 0x24, 0x45, 0x49, 0x43, 0x41,
},
// Orig. Offset: 32
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 32, 32, BL_EQUAL,
0x52, 0x2D, 0x53, 0x54, 0x41, 0x4E, 0x44, 0x41, 0x52, 0x44, 0x2D, 0x41, 0x4E, 0x54, 0x49, 0x56,
0x49, 0x52, 0x55, 0x53, 0x2D, 0x54, 0x45, 0x53, 0x54, 0x2D, 0x46, 0x49, 0x4C, 0x45, 0x21, 0x24,
},
// Orig. Offset: 64 / 0x00000000
// Length: 4 / 0x00000004 (bytes)
{
BS_PHY_FILE, 0, 64, 4, BL_EQUAL,
0x48, 0x2B, 0x48, 0x2A,
},
};
for(int i=0; i<pVRecord->dwSignCount; i++)
{
PVSIGNATURE pSign = new VSIGNATURE;
if(pSign)
{
*pSign = aVSign1[i];
pVRecord->pVSing[i] = pSign;
}
else
{
pVRecord->pVSing[i] = NULL;
}
}
m_listVRecords.push_back(pVRecord);
//////////////////////////////////////////////////////////////////////////
//
// add notepad.exe as a fake virus
//
pVRecord = new VRECORD;
if(pVRecord==NULL)
return false;
pVRecord->nSize = sizeof(VRECORD);
pVRecord->dwVirusID = 2;
pVRecord->dwSignCount = 4;
pVRecord->dwTreatCount = 0;
static VSIGNATURE aVSign2[4]=
{
// Orig. Offset: 256
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 256, 32, BL_EQUAL,
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
},
// Orig. Offset: 1952
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 1952, 32, BL_EQUAL,
0x4E, 0x00, 0x70, 0x00, 0x45, 0x00, 0x6E, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x69, 0x00,
0x6E, 0x00, 0x67, 0x00, 0x44, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00,
},
// Orig. Offset: 31776
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 31776, 32, BL_EQUAL,
0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x70, 0x00, 0x61, 0x00, 0x64, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
},
// Orig. Offset: 65184
// Length: 32 / 0x00000020 (bytes)
{
BS_PHY_FILE, 0, 65184, 32, BL_EQUAL,
0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x4E, 0x00,
0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00,
}
};
for(int i=0; i<pVRecord->dwSignCount; i++)
{
PVSIGNATURE pSign = new VSIGNATURE;
if(pSign)
{
*pSign = aVSign2[i];
pVRecord->pVSing[i] = pSign;
}
else
{
pVRecord->pVSing[i] = NULL;
}
}
m_listVRecords.push_back(pVRecord);
*/
//////////////////////////////////////////////////////////////////////////
//
// add CIH virus
//
pVRecord = new VRECORD;
if(pVRecord==NULL)
return false;
pVRecord->nSize = sizeof(VRECORD);
pVRecord->dwVirusID = 3;
pVRecord->dwSignCount = 3;
pVRecord->dwTreatCount = 0;
static VSIGNATURE aVSign3[3]=
{
{
BS_STRUCT_OFFSET, BS_SUB_NT_HEADERS, -1, 1, BL_NOT_EQUAL,
0x00
},
{
BS_STRUCT_OFFSET, BS_SUB_ENTRY_POINT, 0, 32, BL_EQUAL,
// 00000270 push ebp
// 00000271 lea eax, [esp+var_8]
// 00000275 xor ebx, ebx
// 00000277 xchg eax, fs:[ebx]
// 0000027A call $+5
// 0000027F pop ebx
// 00000280 lea ecx, [ebx+42h]
// 00000283 push ecx
// 00000284 push eax
// 00000285 push eax
// 00000286 sidt qword ptr [esp-2]
// 0000028B pop ebx
// 0000028C add ebx, 1Ch
// 0000028F cli
// Orig. Offset: 0 (from entry point)
// Length: 32 / 0x00000020 (bytes)
0x55, 0x8D, 0x44, 0x24, 0xF8, 0x33, 0xDB, 0x64, 0x87, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B,
0x8D, 0x4B, 0x42, 0x51, 0x50, 0x50, 0x0F, 0x01, 0x4C, 0x24, 0xFE, 0x5B, 0x83, 0xC3, 0x1C, 0xFA,
},
{
BS_STRUCT_OFFSET, BS_SUB_ENTRY_POINT, 137, 27, BL_EQUAL,
// 000002F9 VMMCall _PageAllocate
// 000002FF add esp, 20h
// 00000302 xchg eax, edi
// 00000303 lea eax, [esi-63h]
// 00000306 iret
// 00000307 lea eax, [edi-309h]
// 0000030D push eax
// 0000030E VxDCall IFSMgr_InstallFileSystemApiHook
// 00000314 mov dr0, eax
// Orig. Offset: 137 (from entry point)
// Length: 27 / 0x0000001B (bytes)
0xCD, 0x20, 0x53, 0x00, 0x01, 0x00, 0x83, 0xC4, 0x20, 0x97, 0x8D, 0x46, 0x9D, 0xCF, 0x8D, 0x87,
0xF7, 0xFC, 0xFF, 0xFF, 0x50, 0xCD, 0x20, 0x67, 0x00, 0x40, 0x00,
},
};
for(int i=0; i<pVRecord->dwSignCount; i++)
{
PVSIGNATURE pSign = new VSIGNATURE;
if(pSign)
{
*pSign = aVSign3[i];
pVRecord->pVSing[i] = pSign;
}
else
{
pVRecord->pVSing[i] = NULL;
}
}
m_listVRecords.push_back(pVRecord);
return true;
}
bool CVirusDB::Unload()
{
list<PVRECORD>::iterator iter = m_listVRecords.begin();
while(iter!=m_listVRecords.end())
{
PVRECORD pVRec = *iter;
if(pVRec)
{
for(unsigned int i=0; i<pVRec->dwSignCount; i++)
{
PVSIGNATURE pVSing = pVRec->pVSing[i];
if(pVSing)
delete pVSing;
}
delete pVRec;
}
iter++;
}
return true;
}
// search()方法放在CVirusDB中是考虑到病毒库的内部组织可以是不同的。
// 例如,在这个简单的例子中,病毒库是一个list,改为tree效率应该更高。
// 将特征匹配的管理也放在CVirusDB是考虑到不同的病毒库可以有不同的匹配方法。
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++)
{
PVSIGNATURE pVSing = pVRec->pVSing[i];
switch(pVSing->eType)
{
case BS_PHY_FILE:
bVirus &= pScanObj->Compare(pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
break;
case BS_STRUCT_OFFSET:
{
// determine which parser we need
if(pVSing->dwSubType>=BS_SUB_PE_BEGIN && pVSing->dwSubType=BS_SUB_PE_END)
{
// PE parser need BO_MEM_FILE object
if(pScanObj->GetObjType()!=BO_MEM_FILE)
{
ASSERT(false);
bVirus = false;
}
FSPE stFSPE;
CParsePE cParser;
if( cParser.BasicParse((CMemFileObject*)pScanObj, &stFSPE) )
{
switch(pVSing->dwSubType)
{
case BS_SUB_NT_HEADERS:
bVirus &= pScanObj->Compare((LPBYTE)stFSPE.m_pNtHeaders+pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
break;
case BS_SUB_ENTRY_POINT:
bVirus &= pScanObj->Compare((LPBYTE)stFSPE.m_pEntryPoint+pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
break;
default:
bVirus = false;
ASSERT(false);
}
}
else
{
bVirus = false;
}
}
else
{
ASSERT(false);
}
}
break;
default:
ASSERT(false);
}
// quit the loop ASAP
if(!bVirus) break;
}
// match all signatures
if(bVirus)
{
return pVRec->dwVirusID;
}
}
else
{
// error
return 0xFFFFFFFF;
}
iter++;
}
// no match record in VirusDB
return 0;
}