git-svn: trunk@2965
Tomasz Kojm authored on 2007/03/24 00:11:45... | ... |
@@ -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: |