Browse code

better handling of embedded stuff

git-svn: trunk@2965

Tomasz Kojm authored on 2007/03/24 00:11:45
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Mar 23 14:19:42 CET 2007 (tk)
2
+---------------------------------
3
+  * libclamav: better handling of embedded stuff
4
+
1 5
 Wed Mar 21 01:15:51 CET 2007 (tk)
2 6
 ---------------------------------
3 7
   * docs/man: use actual version and user names in man pages (bb#408),
... ...
@@ -425,7 +425,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
425 425
 	int type = CL_CLEAN, j;
426 426
         unsigned int i, position, curroff;
427 427
 	uint8_t offnum, found;
428
-	struct cli_matched_type *tnode;
428
+	struct cli_matched_type *tnode, *tnode_last = NULL;
429 429
 	struct cli_target_info info;
430 430
 
431 431
 
... ...
@@ -510,6 +510,11 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
510 510
 					if(otfrec) {
511 511
 					    if(pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) {
512 512
 						cli_dbgmsg("Matched signature for file type %s at %u\n", pt->virname, (unsigned int) mdata->inioff[pt->sigid - 1]);
513
+						mdata->offcnt[pt->sigid - 1] = 0;
514
+						mdata->offidx[pt->sigid - 1] = 0;
515
+						mdata->partcnt[pt->sigid - 1] = 0;
516
+						mdata->maxshift[pt->sigid - 1] = -1;
517
+
513 518
 						type = pt->type;
514 519
 						if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE)))  {
515 520
 						    if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) {
... ...
@@ -522,13 +527,21 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
522 522
 						    tnode->type = type;
523 523
 						    tnode->offset = mdata->inioff[pt->sigid - 1];
524 524
 
525
-						    if(*ftoffset)
526
-							tnode->cnt = (*ftoffset)->cnt + 1;
527
-						    else
528
-							tnode->cnt = 1;
525
+						    if(*ftoffset && !tnode_last) {
526
+							tnode_last = *ftoffset;
527
+							while(tnode_last->next)
528
+							    tnode_last = tnode_last->next;
529
+						    }
530
+
531
+						    if(tnode_last) {
532
+							tnode_last->next = tnode;
533
+							tnode_last = tnode;
534
+						    } else {
535
+							*ftoffset = tnode;
536
+							tnode_last = tnode;
537
+						    }
529 538
 
530
-						    tnode->next = *ftoffset;
531
-						    *ftoffset = tnode;
539
+						    (*ftoffset)->cnt++;
532 540
 						}
533 541
 					    }
534 542
 					}
... ...
@@ -560,13 +573,21 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
560 560
 					tnode->type = type;
561 561
 					tnode->offset = curroff;
562 562
 
563
-					if(*ftoffset)
564
-					    tnode->cnt = (*ftoffset)->cnt + 1;
565
-					else
566
-					    tnode->cnt = 1;
563
+					if(*ftoffset && !tnode_last) {
564
+					    tnode_last = *ftoffset;
565
+					    while(tnode_last->next)
566
+						tnode_last = tnode_last->next;
567
+					}
568
+
569
+					if(tnode_last) {
570
+					    tnode_last->next = tnode;
571
+					    tnode_last = tnode;
572
+					} else {
573
+					    *ftoffset = tnode;
574
+					    tnode_last = tnode;
575
+					}
567 576
 
568
-					tnode->next = *ftoffset;
569
-					*ftoffset = tnode;
577
+					(*ftoffset)->cnt++;
570 578
 				    }
571 579
 				}
572 580
 			    }
... ...
@@ -1748,7 +1748,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1748 1748
 static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1749 1749
 {
1750 1750
 	int ret = CL_CLEAN, nret = CL_CLEAN;
1751
-	unsigned short ftrec;
1751
+	unsigned short ftrec, break_loop = 0;
1752 1752
 	struct cli_matched_type *ftoffset = NULL, *fpt;
1753 1753
 	uint32_t lastzip, lastrar;
1754 1754
 	struct cli_exe_info peinfo;
... ...
@@ -1773,7 +1773,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1773 1773
 
1774 1774
     if(ret >= CL_TYPENO) {
1775 1775
 
1776
-	if(ret < CL_TYPE_SFX && ret != CL_TYPE_MSEXE) {
1776
+	if(type == CL_TYPE_UNKNOWN_TEXT) {
1777 1777
 	    lseek(desc, 0, SEEK_SET);
1778 1778
 
1779 1779
 	    nret = cli_scandesc(desc, ctx, 0, ret, 1, NULL);
... ...
@@ -1781,52 +1781,34 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1781 1781
 		cli_dbgmsg("%s found in descriptor %d when scanning file type %u\n", *ctx->virname, desc, ret);
1782 1782
 	}
1783 1783
 
1784
-	ret == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++;
1785
-
1786
-	if(nret != CL_VIRUS) switch(ret) {
1787
-	    case CL_TYPE_HTML:
1788
-		if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_DOC & DOC_CONF_HTML))
1789
-		    nret = cli_scanhtml(desc, ctx);
1790
-		break;
1791
-
1792
-	    case CL_TYPE_MAIL:
1793
-		if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_MAIL & MAIL_CONF_MBOX))
1794
-		    nret = cli_scanmail(desc, ctx);
1795
-		break;
1784
+	if(nret != CL_VIRUS && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP)) {
1785
+	    lastzip = lastrar = 0xdeadbeef;
1786
+	    fpt = ftoffset;
1787
+	    while(fpt) {
1788
+		switch(fpt->type) {
1789
+		    case CL_TYPE_RARSFX:
1790
+			if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_RAR)) {
1791
+			    cli_dbgmsg("RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
1792
+			    nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar);
1793
+			}
1794
+			break;
1796 1795
 
1797
-	    case CL_TYPE_RARSFX:
1798
-	    case CL_TYPE_ZIPSFX:
1799
-	    case CL_TYPE_CABSFX:
1800
-		if(type == CL_TYPE_MSEXE) {
1801
-		    if(SCAN_ARCHIVE) {
1802
-			lastzip = lastrar = 0xdeadbeef;
1803
-			fpt = ftoffset;
1804
-			while(fpt) {
1805
-			    if(fpt->type == CL_TYPE_RARSFX && (DCONF_ARCH & ARCH_CONF_RAR)) {
1806
-				cli_dbgmsg("RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
1807
-				if((nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar)) == CL_VIRUS)
1808
-				    break;
1809
-			    } else if(fpt->type == CL_TYPE_ZIPSFX && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1810
-				cli_dbgmsg("ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset);
1811
-				if((nret = cli_scanzip(desc, ctx, fpt->offset, &lastzip)) == CL_VIRUS)
1812
-				    break;
1813
-			    } else if(fpt->type == CL_TYPE_CABSFX && (DCONF_ARCH & ARCH_CONF_CAB)) {
1814
-				cli_dbgmsg("CAB-SFX signature found at %u\n", (unsigned int) fpt->offset);
1815
-				if((nret = cli_scanmscab(desc, ctx, fpt->offset)) == CL_VIRUS)
1816
-				    break;
1817
-			    }
1796
+		    case CL_TYPE_ZIPSFX:
1797
+			if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1798
+			    cli_dbgmsg("ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset);
1799
+			    nret = cli_scanzip(desc, ctx, fpt->offset, &lastzip);
1800
+			}
1801
+			break;
1818 1802
 
1819
-			    fpt = fpt->next;
1803
+		    case CL_TYPE_CABSFX:
1804
+			if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_CAB)) {
1805
+			    cli_dbgmsg("CAB-SFX signature found at %u\n", (unsigned int) fpt->offset);
1806
+			    nret = cli_scanmscab(desc, ctx, fpt->offset);
1820 1807
 			}
1821
-		    }
1822
-		}
1823
-		break;
1808
+			break;
1824 1809
 
1825
-	    case CL_TYPE_MSEXE:
1826
-		if(SCAN_PE && ctx->dconf->pe) {
1827
-		    fpt = ftoffset;
1828
-		    while(fpt) {
1829
-			if(fpt->type == CL_TYPE_MSEXE && fpt->offset) {
1810
+		    case CL_TYPE_MSEXE:
1811
+			if(SCAN_PE && ctx->dconf->pe && fpt->offset) {
1830 1812
 			    cli_dbgmsg("PE signature found at %u\n", (unsigned int) fpt->offset);
1831 1813
 			    memset(&peinfo, 0, sizeof(struct cli_exe_info));
1832 1814
 			    peinfo.offset = fpt->offset;
... ...
@@ -1838,15 +1820,37 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1838 1838
 
1839 1839
 				lseek(desc, fpt->offset, SEEK_SET);
1840 1840
 				nret = cli_scanembpe(desc, ctx);
1841
-				break; /* we can stop here, other embedded
1842
-					* executables will be found recursively
1843
-					* through the above call
1844
-					*/
1841
+				break_loop = 1; /* we can stop here and other
1842
+						 * embedded executables will
1843
+						 * be found recursively
1844
+						 * through the above call
1845
+						 */
1845 1846
 			    }
1846 1847
 			}
1847
-			fpt = fpt->next;
1848
-		    }
1848
+			break;
1849
+
1850
+		    default:
1851
+			cli_warnmsg("cli_scanraw: Type %u not handled in fpt loop\n", fpt->type);
1849 1852
 		}
1853
+
1854
+		if(nret == CL_VIRUS || break_loop)
1855
+		    break;
1856
+
1857
+		fpt = fpt->next;
1858
+	    }
1859
+	}
1860
+
1861
+	ret == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++;
1862
+
1863
+	if(nret != CL_VIRUS) switch(ret) {
1864
+	    case CL_TYPE_HTML:
1865
+		if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_DOC & DOC_CONF_HTML))
1866
+		    nret = cli_scanhtml(desc, ctx);
1867
+		break;
1868
+
1869
+	    case CL_TYPE_MAIL:
1870
+		if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_MAIL & MAIL_CONF_MBOX))
1871
+		    nret = cli_scanmail(desc, ctx);
1850 1872
 		break;
1851 1873
 
1852 1874
 	    default: