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