git-svn: trunk@1831
Tomasz Kojm authored on 2006/01/25 21:11:31... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Wed Jan 25 13:09:19 CET 2006 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav: add support for signature based self-protection mode |
|
4 |
+ |
|
1 | 5 |
Tue Jan 24 16:52:21 CET 2006 (tk) |
2 | 6 |
--------------------------------- |
3 | 7 |
* libclamav/unrar: fix compilation error on old linux systems |
... | ... |
@@ -260,7 +260,7 @@ inline static int cli_findpos(const char *buffer, unsigned int depth, unsigned i |
260 | 260 |
return 1; |
261 | 261 |
} |
262 | 262 |
|
263 |
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset) |
|
263 |
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, unsigned short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset) |
|
264 | 264 |
{ |
265 | 265 |
struct cli_ac_node *current; |
266 | 266 |
struct cli_ac_patt *pt; |
... | ... |
@@ -26,7 +26,7 @@ |
26 | 26 |
#define AC_DEFAULT_DEPTH 2 |
27 | 27 |
|
28 | 28 |
int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern); |
29 |
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset); |
|
29 |
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, unsigned short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset); |
|
30 | 30 |
int cli_ac_buildtrie(struct cli_matcher *root); |
31 | 31 |
void cli_ac_free(struct cli_matcher *root); |
32 | 32 |
void cli_ac_setdepth(unsigned int depth); |
... | ... |
@@ -274,7 +274,7 @@ int cli_validatesig(unsigned short target, unsigned short ftype, const char *off |
274 | 274 |
return 1; |
275 | 275 |
} |
276 | 276 |
|
277 |
-int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset) |
|
277 |
+int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset) |
|
278 | 278 |
{ |
279 | 279 |
char *buffer, *buff, *endbl, *pt; |
280 | 280 |
int bytes, buffsize, length, ret, *gpartcnt, *tpartcnt; |
... | ... |
@@ -24,7 +24,7 @@ |
24 | 24 |
|
25 | 25 |
#define CL_TARGET_TABLE_SIZE 7 |
26 | 26 |
|
27 |
-int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset); |
|
27 |
+int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset); |
|
28 | 28 |
|
29 | 29 |
int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, unsigned short ftype); |
30 | 30 |
|
... | ... |
@@ -557,7 +557,7 @@ static int cli_loaddb(FILE *fd, struct cl_engine **engine, unsigned int *signo, |
557 | 557 |
return 0; |
558 | 558 |
} |
559 | 559 |
|
560 |
-static int cli_loadndb(FILE *fd, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
|
560 |
+static int cli_loadndb(FILE *fd, struct cl_engine **engine, unsigned int *signo, unsigned short sdb, unsigned int options) |
|
561 | 561 |
{ |
562 | 562 |
char buffer[FILEBUFF], *sig, *virname, *offset, *pt; |
563 | 563 |
struct cli_matcher *root; |
... | ... |
@@ -594,7 +594,7 @@ static int cli_loadndb(FILE *fd, struct cl_engine **engine, unsigned int *signo, |
594 | 594 |
break; |
595 | 595 |
} |
596 | 596 |
|
597 |
- if((pt = cli_strtok(buffer, 4, ":"))) { |
|
597 |
+ if((pt = cli_strtok(buffer, 4, ":"))) { /* min version */ |
|
598 | 598 |
if(!isdigit(*pt)) { |
599 | 599 |
free(virname); |
600 | 600 |
free(pt); |
... | ... |
@@ -611,6 +611,24 @@ static int cli_loadndb(FILE *fd, struct cl_engine **engine, unsigned int *signo, |
611 | 611 |
} |
612 | 612 |
|
613 | 613 |
free(pt); |
614 |
+ |
|
615 |
+ if((pt = cli_strtok(buffer, 5, ":"))) { /* max version */ |
|
616 |
+ if(!isdigit(*pt)) { |
|
617 |
+ free(virname); |
|
618 |
+ free(pt); |
|
619 |
+ ret = CL_EMALFDB; |
|
620 |
+ break; |
|
621 |
+ } |
|
622 |
+ |
|
623 |
+ if(atoi(pt) < cl_retflevel()) { |
|
624 |
+ sigs--; |
|
625 |
+ free(virname); |
|
626 |
+ free(pt); |
|
627 |
+ continue; |
|
628 |
+ } |
|
629 |
+ |
|
630 |
+ free(pt); |
|
631 |
+ } |
|
614 | 632 |
} |
615 | 633 |
|
616 | 634 |
if(!(pt = cli_strtok(buffer, 1, ":")) || !isdigit(*pt)) { |
... | ... |
@@ -677,6 +695,11 @@ static int cli_loadndb(FILE *fd, struct cl_engine **engine, unsigned int *signo, |
677 | 677 |
if(signo) |
678 | 678 |
*signo += sigs; |
679 | 679 |
|
680 |
+ if(sdb && sigs && !(*engine)->sdb) { |
|
681 |
+ (*engine)->sdb = 1; |
|
682 |
+ cli_dbgmsg("*** Self protection mechanism activated.\n"); |
|
683 |
+ } |
|
684 |
+ |
|
680 | 685 |
return 0; |
681 | 686 |
} |
682 | 687 |
|
... | ... |
@@ -970,7 +993,10 @@ static int cli_load(const char *filename, struct cl_engine **engine, unsigned in |
970 | 970 |
ret = cli_loadhdb(fd, engine, signo, 1, options); |
971 | 971 |
|
972 | 972 |
} else if(cli_strbcasestr(filename, ".ndb")) { |
973 |
- ret = cli_loadndb(fd, engine, signo, options); |
|
973 |
+ ret = cli_loadndb(fd, engine, signo, 0, options); |
|
974 |
+ |
|
975 |
+ } else if(cli_strbcasestr(filename, ".sdb")) { |
|
976 |
+ ret = cli_loadndb(fd, engine, signo, 1, options); |
|
974 | 977 |
|
975 | 978 |
} else if(cli_strbcasestr(filename, ".zmd")) { |
976 | 979 |
ret = cli_loadmd(fd, engine, signo, 1, options); |
... | ... |
@@ -1033,6 +1059,7 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne |
1033 | 1033 |
cli_strbcasestr(dent->d_name, ".hdb") || |
1034 | 1034 |
cli_strbcasestr(dent->d_name, ".fp") || |
1035 | 1035 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1036 |
+ cli_strbcasestr(dent->d_name, ".sdb") || |
|
1036 | 1037 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1037 | 1038 |
cli_strbcasestr(dent->d_name, ".rmd") || |
1038 | 1039 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -1153,6 +1180,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat) |
1153 | 1153 |
cli_strbcasestr(dent->d_name, ".hdb") || |
1154 | 1154 |
cli_strbcasestr(dent->d_name, ".fp") || |
1155 | 1155 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1156 |
+ cli_strbcasestr(dent->d_name, ".sdb") || |
|
1156 | 1157 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1157 | 1158 |
cli_strbcasestr(dent->d_name, ".rmd") || |
1158 | 1159 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -1224,6 +1252,7 @@ int cl_statchkdir(const struct cl_stat *dbstat) |
1224 | 1224 |
cli_strbcasestr(dent->d_name, ".hdb") || |
1225 | 1225 |
cli_strbcasestr(dent->d_name, ".fp") || |
1226 | 1226 |
cli_strbcasestr(dent->d_name, ".ndb") || |
1227 |
+ cli_strbcasestr(dent->d_name, ".sdb") || |
|
1227 | 1228 |
cli_strbcasestr(dent->d_name, ".zmd") || |
1228 | 1229 |
cli_strbcasestr(dent->d_name, ".rmd") || |
1229 | 1230 |
cli_strbcasestr(dent->d_name, ".cvd"))) { |
... | ... |
@@ -1438,8 +1438,7 @@ static int cli_scantnef(int desc, const char **virname, unsigned long int *scann |
1438 | 1438 |
return ret; |
1439 | 1439 |
} |
1440 | 1440 |
|
1441 |
-static int |
|
1442 |
-cli_scanuuencoded(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) |
|
1441 |
+static int cli_scanuuencoded(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) |
|
1443 | 1442 |
{ |
1444 | 1443 |
int ret; |
1445 | 1444 |
char *dir = cli_gentemp(NULL); |
... | ... |
@@ -1497,6 +1496,90 @@ static int cli_scanmail(int desc, const char **virname, unsigned long int *scann |
1497 | 1497 |
return ret; |
1498 | 1498 |
} |
1499 | 1499 |
|
1500 |
+static int cli_scanraw(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec, cli_file_t type) |
|
1501 |
+{ |
|
1502 |
+ int ret = CL_CLEAN; |
|
1503 |
+ unsigned short ftrec; |
|
1504 |
+ struct cli_matched_type *ftoffset = NULL, *fpt; |
|
1505 |
+ |
|
1506 |
+ |
|
1507 |
+ switch(type) { |
|
1508 |
+ case CL_TYPE_UNKNOWN_TEXT: |
|
1509 |
+ case CL_TYPE_MSEXE: |
|
1510 |
+ ftrec = 1; |
|
1511 |
+ break; |
|
1512 |
+ default: |
|
1513 |
+ ftrec = 0; |
|
1514 |
+ } |
|
1515 |
+ |
|
1516 |
+ if(lseek(desc, 0, SEEK_SET) < 0) { |
|
1517 |
+ cli_errmsg("cli_scanraw: lseek() failed\n"); |
|
1518 |
+ return CL_EIO; |
|
1519 |
+ } |
|
1520 |
+ |
|
1521 |
+ if((ret = cli_scandesc(desc, virname, scanned, engine, ftrec, type, &ftoffset)) == CL_VIRUS) { |
|
1522 |
+ cli_dbgmsg("%s found in descriptor %d.\n", *virname, desc); |
|
1523 |
+ return CL_VIRUS; |
|
1524 |
+ |
|
1525 |
+ } else if(ret < 0) { |
|
1526 |
+ return ret; |
|
1527 |
+ |
|
1528 |
+ } else if(ret >= CL_TYPENO) { |
|
1529 |
+ lseek(desc, 0, SEEK_SET); |
|
1530 |
+ |
|
1531 |
+ ret == CL_TYPE_MAIL ? mrec++ : arec++; |
|
1532 |
+ switch(ret) { |
|
1533 |
+ case CL_TYPE_HTML: |
|
1534 |
+ if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT) |
|
1535 |
+ if(cli_scanhtml(desc, virname, scanned, engine, limits, options, arec, mrec) == CL_VIRUS) |
|
1536 |
+ return CL_VIRUS; |
|
1537 |
+ break; |
|
1538 |
+ |
|
1539 |
+ case CL_TYPE_MAIL: |
|
1540 |
+ if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT) |
|
1541 |
+ if(cli_scanmail(desc, virname, scanned, engine, limits, options, arec, mrec) == CL_VIRUS) |
|
1542 |
+ return CL_VIRUS; |
|
1543 |
+ break; |
|
1544 |
+ |
|
1545 |
+ case CL_TYPE_RARSFX: |
|
1546 |
+ case CL_TYPE_ZIPSFX: |
|
1547 |
+ if(type == CL_TYPE_MSEXE) { |
|
1548 |
+ if(SCAN_ARCHIVE) { |
|
1549 |
+ fpt = ftoffset; |
|
1550 |
+ while(fpt) { |
|
1551 |
+ if(fpt->type == CL_TYPE_RARSFX) { |
|
1552 |
+ cli_dbgmsg("RAR-SFX signature found at %d\n", fpt->offset); |
|
1553 |
+ if((ret = cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1554 |
+ break; |
|
1555 |
+ } else if(fpt->type == CL_TYPE_ZIPSFX) { |
|
1556 |
+ cli_dbgmsg("ZIP-SFX signature found at %d\n", fpt->offset); |
|
1557 |
+ if((ret = cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1558 |
+ break; |
|
1559 |
+ } |
|
1560 |
+ fpt = fpt->next; |
|
1561 |
+ } |
|
1562 |
+ } |
|
1563 |
+ |
|
1564 |
+ while(ftoffset) { |
|
1565 |
+ fpt = ftoffset; |
|
1566 |
+ ftoffset = ftoffset->next; |
|
1567 |
+ free(fpt); |
|
1568 |
+ } |
|
1569 |
+ |
|
1570 |
+ if(ret == CL_VIRUS) |
|
1571 |
+ return ret; |
|
1572 |
+ } |
|
1573 |
+ break; |
|
1574 |
+ |
|
1575 |
+ default: |
|
1576 |
+ break; |
|
1577 |
+ } |
|
1578 |
+ ret == CL_TYPE_MAIL ? mrec-- : arec--; |
|
1579 |
+ } |
|
1580 |
+ |
|
1581 |
+ return ret; |
|
1582 |
+} |
|
1583 |
+ |
|
1500 | 1584 |
int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) |
1501 | 1585 |
{ |
1502 | 1586 |
int ret = CL_CLEAN, nret; |
... | ... |
@@ -1548,6 +1631,12 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne |
1548 | 1548 |
type = cli_filetype2(desc); |
1549 | 1549 |
lseek(desc, 0, SEEK_SET); |
1550 | 1550 |
|
1551 |
+ if(type != CL_TYPE_DATA && engine->sdb) { |
|
1552 |
+ if((ret = cli_scanraw(desc, virname, scanned, engine, limits, options, arec, mrec, type) == CL_VIRUS)) |
|
1553 |
+ return CL_VIRUS; |
|
1554 |
+ lseek(desc, 0, SEEK_SET); |
|
1555 |
+ } |
|
1556 |
+ |
|
1551 | 1557 |
type == CL_TYPE_MAIL ? mrec++ : arec++; |
1552 | 1558 |
|
1553 | 1559 |
switch(type) { |
... | ... |
@@ -1671,81 +1760,9 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne |
1671 | 1671 |
|
1672 | 1672 |
type == CL_TYPE_MAIL ? mrec-- : arec--; |
1673 | 1673 |
|
1674 |
- if(type != CL_TYPE_DATA && ret != CL_VIRUS) { /* scan the raw file */ |
|
1675 |
- int ftrec; |
|
1676 |
- struct cli_matched_type *ftoffset = NULL, *fpt; |
|
1677 |
- |
|
1678 |
- switch(type) { |
|
1679 |
- case CL_TYPE_UNKNOWN_TEXT: |
|
1680 |
- case CL_TYPE_MSEXE: |
|
1681 |
- ftrec = 1; |
|
1682 |
- break; |
|
1683 |
- default: |
|
1684 |
- ftrec = 0; |
|
1685 |
- } |
|
1686 |
- |
|
1687 |
- if(lseek(desc, 0, SEEK_SET) < 0) |
|
1688 |
- cli_errmsg("lseek() failed, trying to continue anyway...\n"); |
|
1689 |
- |
|
1690 |
- if((nret = cli_scandesc(desc, virname, scanned, engine, ftrec, type, &ftoffset)) == CL_VIRUS) { |
|
1691 |
- cli_dbgmsg("%s found in descriptor %d.\n", *virname, desc); |
|
1674 |
+ if(type != CL_TYPE_DATA && ret != CL_VIRUS && !engine->sdb) { |
|
1675 |
+ if((ret = cli_scanraw(desc, virname, scanned, engine, limits, options, arec, mrec, type) == CL_VIRUS)) |
|
1692 | 1676 |
return CL_VIRUS; |
1693 |
- |
|
1694 |
- } else if(nret < 0) { |
|
1695 |
- return nret; |
|
1696 |
- |
|
1697 |
- } else if(nret >= CL_TYPENO) { |
|
1698 |
- lseek(desc, 0, SEEK_SET); |
|
1699 |
- |
|
1700 |
- nret == CL_TYPE_MAIL ? mrec++ : arec++; |
|
1701 |
- switch(nret) { |
|
1702 |
- case CL_TYPE_HTML: |
|
1703 |
- if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT) |
|
1704 |
- if(cli_scanhtml(desc, virname, scanned, engine, limits, options, arec, mrec) == CL_VIRUS) |
|
1705 |
- return CL_VIRUS; |
|
1706 |
- break; |
|
1707 |
- |
|
1708 |
- case CL_TYPE_MAIL: |
|
1709 |
- if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT) |
|
1710 |
- if(cli_scanmail(desc, virname, scanned, engine, limits, options, arec, mrec) == CL_VIRUS) |
|
1711 |
- return CL_VIRUS; |
|
1712 |
- break; |
|
1713 |
- |
|
1714 |
- case CL_TYPE_RARSFX: |
|
1715 |
- case CL_TYPE_ZIPSFX: |
|
1716 |
- if(type == CL_TYPE_MSEXE) { |
|
1717 |
- if(SCAN_ARCHIVE) { |
|
1718 |
- fpt = ftoffset; |
|
1719 |
- while(fpt) { |
|
1720 |
- if(fpt->type == CL_TYPE_RARSFX) { |
|
1721 |
- cli_dbgmsg("RAR-SFX signature found at %d\n", fpt->offset); |
|
1722 |
- if((ret = cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1723 |
- break; |
|
1724 |
- } else if(fpt->type == CL_TYPE_ZIPSFX) { |
|
1725 |
- cli_dbgmsg("ZIP-SFX signature found at %d\n", fpt->offset); |
|
1726 |
- if((ret = cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1727 |
- break; |
|
1728 |
- } |
|
1729 |
- fpt = fpt->next; |
|
1730 |
- } |
|
1731 |
- } |
|
1732 |
- |
|
1733 |
- while(ftoffset) { |
|
1734 |
- fpt = ftoffset; |
|
1735 |
- ftoffset = ftoffset->next; |
|
1736 |
- free(fpt); |
|
1737 |
- } |
|
1738 |
- |
|
1739 |
- if(ret == CL_VIRUS) |
|
1740 |
- return ret; |
|
1741 |
- } |
|
1742 |
- break; |
|
1743 |
- |
|
1744 |
- default: |
|
1745 |
- break; |
|
1746 |
- } |
|
1747 |
- nret == CL_TYPE_MAIL ? mrec-- : arec--; |
|
1748 |
- } |
|
1749 | 1677 |
} |
1750 | 1678 |
|
1751 | 1679 |
arec++; |