VirusDB.cpp
上传用户:chaoyu
上传日期:2013-04-28
资源大小:18k
文件大小:8k
源码类别:

杀毒

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "VirusDB.h"
  3. #include "ScanObject.h"
  4. #include "ParsePE.h"
  5. CVirusDB::CVirusDB(void)
  6. {
  7. }
  8. CVirusDB::~CVirusDB(void)
  9. {
  10. }
  11. bool CVirusDB::Load(const char* pszDBFile)
  12. {
  13. // not really load from file at this version
  14. PVRECORD pVRecord;
  15. /*
  16. //////////////////////////////////////////////////////////////////////////
  17. //
  18. // add standard eicar virus
  19. //
  20. pVRecord = new VRECORD;
  21. if(pVRecord==NULL)
  22. return false;
  23. pVRecord->nSize = sizeof(VRECORD);
  24. pVRecord->dwVirusID = 1;
  25. pVRecord->dwSignCount = 3;
  26. pVRecord->dwTreatCount = 0;
  27. static VSIGNATURE aVSign1[3]=
  28. {
  29. // Orig. Offset: 0
  30. //       Length: 32 / 0x00000020 (bytes)
  31. {
  32. BS_PHY_FILE, 0, 0, 32, BL_EQUAL, 
  33. 0x58, 0x35, 0x4F, 0x21, 0x50, 0x25, 0x40, 0x41, 0x50, 0x5B, 0x34, 0x5C, 0x50, 0x5A, 0x58, 0x35, 
  34. 0x34, 0x28, 0x50, 0x5E, 0x29, 0x37, 0x43, 0x43, 0x29, 0x37, 0x7D, 0x24, 0x45, 0x49, 0x43, 0x41, 
  35. },
  36. // Orig. Offset: 32
  37. //       Length: 32 / 0x00000020 (bytes)
  38. {
  39. BS_PHY_FILE, 0, 32, 32, BL_EQUAL,
  40. 0x52, 0x2D, 0x53, 0x54, 0x41, 0x4E, 0x44, 0x41, 0x52, 0x44, 0x2D, 0x41, 0x4E, 0x54, 0x49, 0x56, 
  41. 0x49, 0x52, 0x55, 0x53, 0x2D, 0x54, 0x45, 0x53, 0x54, 0x2D, 0x46, 0x49, 0x4C, 0x45, 0x21, 0x24, 
  42. },
  43. // Orig. Offset: 64 / 0x00000000
  44. //       Length: 4 / 0x00000004 (bytes)
  45. {
  46. BS_PHY_FILE, 0, 64, 4, BL_EQUAL,
  47. 0x48, 0x2B, 0x48, 0x2A, 
  48. },
  49. };
  50. for(int i=0; i<pVRecord->dwSignCount; i++)
  51. {
  52. PVSIGNATURE pSign = new VSIGNATURE;
  53. if(pSign)
  54. {
  55. *pSign = aVSign1[i];
  56. pVRecord->pVSing[i] = pSign;
  57. }
  58. else
  59. {
  60. pVRecord->pVSing[i] = NULL;
  61. }
  62. }
  63. m_listVRecords.push_back(pVRecord);
  64. //////////////////////////////////////////////////////////////////////////
  65. //
  66. // add notepad.exe as a fake virus
  67. //
  68. pVRecord = new VRECORD;
  69. if(pVRecord==NULL)
  70. return false;
  71. pVRecord->nSize = sizeof(VRECORD);
  72. pVRecord->dwVirusID = 2;
  73. pVRecord->dwSignCount = 4;
  74. pVRecord->dwTreatCount = 0;
  75. static VSIGNATURE aVSign2[4]=
  76. {
  77. // Orig. Offset: 256
  78. //       Length: 32 / 0x00000020 (bytes)
  79. {
  80. BS_PHY_FILE, 0, 256, 32, BL_EQUAL,
  81. 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 
  82. 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 
  83. },
  84. // Orig. Offset: 1952
  85. //       Length: 32 / 0x00000020 (bytes)
  86. {
  87. BS_PHY_FILE, 0, 1952, 32, BL_EQUAL,
  88. 0x4E, 0x00, 0x70, 0x00, 0x45, 0x00, 0x6E, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x69, 0x00, 
  89. 0x6E, 0x00, 0x67, 0x00, 0x44, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, 
  90. },
  91. // Orig. Offset: 31776
  92. //       Length: 32 / 0x00000020 (bytes)
  93. {
  94. BS_PHY_FILE, 0, 31776, 32, BL_EQUAL,
  95. 0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x70, 0x00, 0x61, 0x00, 0x64, 0x00, 0x00, 0x00, 
  96. 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
  97. },
  98. // Orig. Offset: 65184
  99. //       Length: 32 / 0x00000020 (bytes)
  100. {
  101. BS_PHY_FILE, 0, 65184, 32, BL_EQUAL,
  102. 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x4E, 0x00, 
  103. 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 
  104. }
  105. };
  106. for(int i=0; i<pVRecord->dwSignCount; i++)
  107. {
  108. PVSIGNATURE pSign = new VSIGNATURE;
  109. if(pSign)
  110. {
  111. *pSign = aVSign2[i];
  112. pVRecord->pVSing[i] = pSign;
  113. }
  114. else
  115. {
  116. pVRecord->pVSing[i] = NULL;
  117. }
  118. }
  119. m_listVRecords.push_back(pVRecord);
  120. */
  121. //////////////////////////////////////////////////////////////////////////
  122. //
  123. // add CIH virus
  124. //
  125. pVRecord = new VRECORD;
  126. if(pVRecord==NULL)
  127. return false;
  128. pVRecord->nSize = sizeof(VRECORD);
  129. pVRecord->dwVirusID = 3;
  130. pVRecord->dwSignCount = 3;
  131. pVRecord->dwTreatCount = 0;
  132. static VSIGNATURE aVSign3[3]=
  133. {
  134. {
  135. BS_STRUCT_OFFSET, BS_SUB_NT_HEADERS, -1, 1, BL_NOT_EQUAL, 
  136. 0x00
  137. },
  138. {
  139. BS_STRUCT_OFFSET, BS_SUB_ENTRY_POINT, 0, 32, BL_EQUAL, 
  140. // 00000270                 push    ebp
  141. // 00000271                 lea     eax, [esp+var_8]
  142. // 00000275                 xor     ebx, ebx
  143. // 00000277                 xchg    eax, fs:[ebx]
  144. // 0000027A                 call    $+5
  145. // 0000027F                 pop     ebx
  146. // 00000280                 lea     ecx, [ebx+42h]
  147. // 00000283                 push    ecx
  148. // 00000284                 push    eax
  149. // 00000285                 push    eax
  150. // 00000286                 sidt    qword ptr [esp-2]
  151. // 0000028B                 pop     ebx
  152. // 0000028C                 add     ebx, 1Ch
  153. // 0000028F                 cli
  154. // Orig. Offset: 0 (from entry point)
  155. //       Length: 32 / 0x00000020 (bytes)
  156. 0x55, 0x8D, 0x44, 0x24, 0xF8, 0x33, 0xDB, 0x64, 0x87, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B, 
  157. 0x8D, 0x4B, 0x42, 0x51, 0x50, 0x50, 0x0F, 0x01, 0x4C, 0x24, 0xFE, 0x5B, 0x83, 0xC3, 0x1C, 0xFA, 
  158. },
  159. {
  160. BS_STRUCT_OFFSET, BS_SUB_ENTRY_POINT, 137, 27, BL_EQUAL, 
  161. // 000002F9                 VMMCall _PageAllocate
  162. // 000002FF                 add     esp, 20h
  163. // 00000302                 xchg    eax, edi
  164. // 00000303                 lea     eax, [esi-63h]
  165. // 00000306                 iret
  166. // 00000307                 lea     eax, [edi-309h]
  167. // 0000030D                 push    eax
  168. // 0000030E                 VxDCall IFSMgr_InstallFileSystemApiHook
  169. // 00000314                 mov     dr0, eax
  170. // Orig. Offset: 137 (from entry point)
  171. //       Length: 27 / 0x0000001B (bytes)
  172. 0xCD, 0x20, 0x53, 0x00, 0x01, 0x00, 0x83, 0xC4, 0x20, 0x97, 0x8D, 0x46, 0x9D, 0xCF, 0x8D, 0x87, 
  173. 0xF7, 0xFC, 0xFF, 0xFF, 0x50, 0xCD, 0x20, 0x67, 0x00, 0x40, 0x00, 
  174. },
  175. };
  176. for(int i=0; i<pVRecord->dwSignCount; i++)
  177. {
  178. PVSIGNATURE pSign = new VSIGNATURE;
  179. if(pSign)
  180. {
  181. *pSign = aVSign3[i];
  182. pVRecord->pVSing[i] = pSign;
  183. }
  184. else
  185. {
  186. pVRecord->pVSing[i] = NULL;
  187. }
  188. }
  189. m_listVRecords.push_back(pVRecord);
  190. return true;
  191. }
  192. bool CVirusDB::Unload()
  193. {
  194. list<PVRECORD>::iterator iter = m_listVRecords.begin();
  195. while(iter!=m_listVRecords.end())
  196. {
  197. PVRECORD pVRec = *iter;
  198. if(pVRec)
  199. {
  200. for(unsigned int i=0; i<pVRec->dwSignCount; i++)
  201. {
  202. PVSIGNATURE pVSing = pVRec->pVSing[i];
  203. if(pVSing)
  204. delete pVSing;
  205. }
  206. delete pVRec;
  207. }
  208. iter++;
  209. }
  210. return true;
  211. }
  212. // search()方法放在CVirusDB中是考虑到病毒库的内部组织可以是不同的。
  213. // 例如,在这个简单的例子中,病毒库是一个list,改为tree效率应该更高。
  214. // 将特征匹配的管理也放在CVirusDB是考虑到不同的病毒库可以有不同的匹配方法。
  215. DWORD CVirusDB::Search(CScanObject* pScanObj)
  216. {
  217. list<PVRECORD>::iterator iter = m_listVRecords.begin();
  218. while(iter!=m_listVRecords.end())
  219. {
  220. PVRECORD pVRec = *iter;
  221. ASSERT(pVRec);
  222. if(pVRec)
  223. {
  224. bool bVirus = true;
  225. for(unsigned int i=0; i<pVRec->dwSignCount; i++)
  226. {
  227. PVSIGNATURE pVSing = pVRec->pVSing[i];
  228. switch(pVSing->eType)
  229. {
  230. case BS_PHY_FILE:
  231. bVirus &= pScanObj->Compare(pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
  232. break;
  233. case BS_STRUCT_OFFSET:
  234. {
  235. // determine which parser we need
  236. if(pVSing->dwSubType>=BS_SUB_PE_BEGIN && pVSing->dwSubType<=BS_SUB_PE_END)
  237. {
  238. // PE parser need BO_MEM_FILE object
  239. if(pScanObj->GetObjType()!=BO_MEM_FILE)
  240. {
  241. ASSERT(false);
  242. bVirus = false;
  243. }
  244. FSPE stFSPE;
  245. CParsePE cParser;
  246. if( cParser.BasicParse((CMemFileObject*)pScanObj, &stFSPE) )
  247. {
  248. switch(pVSing->dwSubType)
  249. {
  250. case BS_SUB_NT_HEADERS:
  251. bVirus &= pScanObj->Compare((LPBYTE)stFSPE.m_pNtHeaders+pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
  252. break;
  253. case BS_SUB_ENTRY_POINT:
  254. bVirus &= pScanObj->Compare((LPBYTE)stFSPE.m_pEntryPoint+pVSing->nOffset, pVSing->nSize, pVSing->Signature, pVSing->eLogicOp);
  255. break;
  256. default:
  257. bVirus = false;
  258. ASSERT(false);
  259. }
  260. }
  261. else
  262. {
  263. bVirus = false;
  264. }
  265. }
  266. else
  267. {
  268. ASSERT(false);
  269. }
  270. }
  271. break;
  272. default:
  273. ASSERT(false);
  274. }
  275. // quit the loop ASAP
  276. if(!bVirus) break;
  277. }
  278. // match all signatures
  279. if(bVirus)
  280. {
  281. return pVRec->dwVirusID;
  282. }
  283. }
  284. else
  285. {
  286. // error
  287. return 0xFFFFFFFF;
  288. }
  289. iter++;
  290. }
  291. // no match record in VirusDB
  292. return 0;
  293. }