improve file type recognizer and add CL_TYPE_RARSFX

git-svn: trunk@1634
This commit is contained in:
Tomasz Kojm 2005-06-24 13:54:41 +00:00
parent 6698f32757
commit 978e3d689d
8 changed files with 42 additions and 17 deletions

View file

@ -1,3 +1,7 @@
Fri Jun 24 15:48:26 CEST 2005 (tk)
----------------------------------
* libclamav: improve file type recognizer and add CL_TYPE_RARSFX
Thu Jun 23 22:52:43 CEST 2005 (tk) Thu Jun 23 22:52:43 CEST 2005 (tk)
---------------------------------- ----------------------------------
* libclamav/mspack/qtmd.c: fix possible crash * libclamav/mspack/qtmd.c: fix possible crash

View file

@ -169,6 +169,8 @@ static const struct cli_smagic_s cli_smagic[] = {
{"3c696672616d65", "HTML data", CL_TYPE_HTML}, /* <iframe */ {"3c696672616d65", "HTML data", CL_TYPE_HTML}, /* <iframe */
{"3c494652414d45", "HTML data", CL_TYPE_HTML}, /* <IFRAME */ {"3c494652414d45", "HTML data", CL_TYPE_HTML}, /* <IFRAME */
{"526172211a0700", "RAR-SFX", CL_TYPE_RARSFX},
{NULL, NULL, CL_TYPE_UNKNOWN_DATA} {NULL, NULL, CL_TYPE_UNKNOWN_DATA}
}; };

View file

@ -46,6 +46,7 @@ typedef enum {
CL_TYPE_PDF, CL_TYPE_PDF,
/* bigger numbers have higher priority (in o-t-f detection) */ /* bigger numbers have higher priority (in o-t-f detection) */
CL_TYPE_RARSFX,
CL_TYPE_HTML, /* on the fly */ CL_TYPE_HTML, /* on the fly */
CL_TYPE_MAIL /* magic + on the fly */ CL_TYPE_MAIL /* magic + on the fly */

View file

@ -263,7 +263,7 @@ inline static int cli_findpos(const char *buffer, int offset, int length, const
return 1; return 1;
} }
int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd) int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, unsigned long int *ftoffset)
{ {
struct cli_ac_node *current; struct cli_ac_node *current;
struct cli_ac_patt *pt; struct cli_ac_patt *pt;
@ -322,6 +322,8 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
if(pt->type > type) { if(pt->type > type) {
cli_dbgmsg("Matched signature for file type: %s\n", pt->virname); cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
type = pt->type; type = pt->type;
if(ftoffset)
*ftoffset = offset + position;
} }
} }
} else { } else {
@ -341,6 +343,8 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
cli_dbgmsg("Matched signature for file type: %s\n", pt->virname); cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
type = pt->type; type = pt->type;
if(ftoffset)
*ftoffset = offset + position;
} }
} }
} else { } else {

View file

@ -23,7 +23,7 @@
#include "matcher.h" #include "matcher.h"
int cli_ac_addpatt(struct cl_node *root, struct cli_ac_patt *pattern); int cli_ac_addpatt(struct cl_node *root, struct cli_ac_patt *pattern);
int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd); int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, unsigned long int *ftoffset);
int cli_ac_buildtrie(struct cl_node *root); int cli_ac_buildtrie(struct cl_node *root);
void cli_ac_free(struct cl_node *root); void cli_ac_free(struct cl_node *root);

View file

@ -66,7 +66,7 @@ int cli_scanbuff(const char *buffer, unsigned int length, const char **virname,
} }
if((ret = cli_bm_scanbuff(buffer, length, virname, root, 0, ftype, -1)) != CL_VIRUS) if((ret = cli_bm_scanbuff(buffer, length, virname, root, 0, ftype, -1)) != CL_VIRUS)
ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff, ftype, -1); ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff, ftype, -1, NULL);
free(partcnt); free(partcnt);
free(partoff); free(partoff);
@ -237,7 +237,7 @@ int cli_validatesig(unsigned short target, unsigned short ftype, const char *off
return 1; return 1;
} }
int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype) int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype, unsigned long int *ftoffset)
{ {
char *buffer, *buff, *endbl, *pt; char *buffer, *buff, *endbl, *pt;
int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN; int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN;
@ -293,7 +293,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
length -= SCANBUFF - bytes; length -= SCANBUFF - bytes;
if(cli_bm_scanbuff(pt, length, virname, root, offset, ftype, desc) == CL_VIRUS || if(cli_bm_scanbuff(pt, length, virname, root, offset, ftype, desc) == CL_VIRUS ||
(ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, ftype, desc)) == CL_VIRUS) { (ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, ftype, desc, ftoffset)) == CL_VIRUS) {
free(buffer); free(buffer);
free(partcnt); free(partcnt);
free(partoff); free(partoff);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net> * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
#include "clamav.h" #include "clamav.h"
int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype); int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype, unsigned long int *ftoffset);
int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned short ftype); int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned short ftype);

View file

@ -189,7 +189,7 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const
if(DETECT_ENCRYPTED && metadata->encrypted) { if(DETECT_ENCRYPTED && metadata->encrypted) {
cli_dbgmsg("RAR: Encrypted files found in archive.\n"); cli_dbgmsg("RAR: Encrypted files found in archive.\n");
lseek(desc, 0, SEEK_SET); lseek(desc, 0, SEEK_SET);
ret = cli_scandesc(desc, virname, scanned, root, 0, 0); ret = cli_scandesc(desc, virname, scanned, root, 0, 0, NULL);
if(ret < 0) { if(ret < 0) {
break; break;
} else if(ret != CL_VIRUS) { } else if(ret != CL_VIRUS) {
@ -388,7 +388,7 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const
if(DETECT_ENCRYPTED && encrypted) { if(DETECT_ENCRYPTED && encrypted) {
cli_dbgmsg("Zip: Encrypted files found in archive.\n"); cli_dbgmsg("Zip: Encrypted files found in archive.\n");
lseek(desc, 0, SEEK_SET); lseek(desc, 0, SEEK_SET);
ret = cli_scandesc(desc, virname, scanned, root, 0, 0); ret = cli_scandesc(desc, virname, scanned, root, 0, 0, NULL);
if(ret < 0) { if(ret < 0) {
break; break;
} else if(ret != CL_VIRUS) { } else if(ret != CL_VIRUS) {
@ -1011,7 +1011,7 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int *
if (fd >= 0) { if (fd >= 0) {
ofd = cli_decode_ole_object(fd, dirname); ofd = cli_decode_ole_object(fd, dirname);
if (ofd >= 0) { if (ofd >= 0) {
ret = cli_scandesc(ofd, virname, scanned, root, 0, 0); ret = cli_scandesc(ofd, virname, scanned, root, 0, 0, NULL);
close(ofd); close(ofd);
} }
close(fd); close(fd);
@ -1077,7 +1077,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
snprintf(fullname, 1024, "%s/comment.html", tempname); snprintf(fullname, 1024, "%s/comment.html", tempname);
fd = open(fullname, O_RDONLY); fd = open(fullname, O_RDONLY);
if (fd >= 0) { if (fd >= 0) {
ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML); ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML, NULL);
close(fd); close(fd);
} }
@ -1092,7 +1092,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
snprintf(fullname, 1024, "%s/nocomment.html", tempname); snprintf(fullname, 1024, "%s/nocomment.html", tempname);
fd = open(fullname, O_RDONLY); fd = open(fullname, O_RDONLY);
if (fd >= 0) { if (fd >= 0) {
ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML); ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML, NULL);
close(fd); close(fd);
} }
} }
@ -1108,7 +1108,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
snprintf(fullname, 1024, "%s/script.html", tempname); snprintf(fullname, 1024, "%s/script.html", tempname);
fd = open(fullname, O_RDONLY); fd = open(fullname, O_RDONLY);
if (fd >= 0) { if (fd >= 0) {
ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML); ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML, NULL);
close(fd); close(fd);
} }
} }
@ -1406,7 +1406,7 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
if(!options) { /* raw mode (stdin, etc.) */ if(!options) { /* raw mode (stdin, etc.) */
cli_dbgmsg("Raw mode: No support for special files\n"); cli_dbgmsg("Raw mode: No support for special files\n");
if((ret = cli_scandesc(desc, virname, scanned, root, 0, 0) == CL_VIRUS)) if((ret = cli_scandesc(desc, virname, scanned, root, 0, 0, NULL) == CL_VIRUS))
cli_dbgmsg("%s found in descriptor %d\n", *virname, desc); cli_dbgmsg("%s found in descriptor %d\n", *virname, desc);
return ret; return ret;
} }
@ -1538,13 +1538,22 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
type == CL_TYPE_MAIL ? mrec-- : arec--; type == CL_TYPE_MAIL ? mrec-- : arec--;
if(type != CL_TYPE_DATA && ret != CL_VIRUS) { /* scan the raw file */ if(type != CL_TYPE_DATA && ret != CL_VIRUS) { /* scan the raw file */
int typerec; int ftrec;
unsigned long int ftoffset;
switch(type) {
case CL_TYPE_UNKNOWN_TEXT:
case CL_TYPE_MSEXE:
ftrec = 1;
break;
default:
ftrec = 0;
}
type == CL_TYPE_UNKNOWN_TEXT ? (typerec = 1) : (typerec = 0);
if(lseek(desc, 0, SEEK_SET) < 0) if(lseek(desc, 0, SEEK_SET) < 0)
cli_errmsg("lseek() failed, trying to continue anyway...\n"); cli_errmsg("lseek() failed, trying to continue anyway...\n");
if((nret = cli_scandesc(desc, virname, scanned, root, typerec, type)) == CL_VIRUS) { if((nret = cli_scandesc(desc, virname, scanned, root, ftrec, type, &ftoffset)) == CL_VIRUS) {
cli_dbgmsg("%s found in descriptor %d.\n", *virname, desc); cli_dbgmsg("%s found in descriptor %d.\n", *virname, desc);
return CL_VIRUS; return CL_VIRUS;
@ -1567,6 +1576,11 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
if(cli_scanmail(desc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS) if(cli_scanmail(desc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS)
return CL_VIRUS; return CL_VIRUS;
break; break;
case CL_TYPE_RARSFX:
if(SCAN_ARCHIVE)
cli_dbgmsg("RAR-SFX found at %d\n", ftoffset);
break;
} }
nret == CL_TYPE_MAIL ? mrec-- : arec--; nret == CL_TYPE_MAIL ? mrec-- : arec--;
} }