git-svn: trunk@1817
Tomasz Kojm authored on 2006/01/16 00:46:36... | ... |
@@ -33,7 +33,7 @@ |
33 | 33 |
#include "matcher-ac.h" |
34 | 34 |
|
35 | 35 |
struct cli_magic_s { |
36 |
- int offset; |
|
36 |
+ size_t offset; |
|
37 | 37 |
const char *magic; |
38 | 38 |
size_t length; |
39 | 39 |
const char *descr; |
... | ... |
@@ -126,7 +126,7 @@ static const struct cli_magic_s cli_magic[] = { |
126 | 126 |
{0, "\060\046\262\165\216\146\317", 7, "WMA/WMV/ASF", CL_TYPE_DATA}, |
127 | 127 |
{0, ".RMF" , 4, "Real Media File", CL_TYPE_DATA}, |
128 | 128 |
|
129 |
- {-1, NULL, 0, NULL, CL_TYPE_UNKNOWN_DATA} |
|
129 |
+ {0, NULL, 0, NULL, CL_TYPE_UNKNOWN_DATA} |
|
130 | 130 |
}; |
131 | 131 |
|
132 | 132 |
static const struct cli_smagic_s cli_smagic[] = { |
... | ... |
@@ -51,11 +51,18 @@ typedef enum { |
51 | 51 |
/* bigger numbers have higher priority (in o-t-f detection) */ |
52 | 52 |
CL_TYPE_HTML, /* on the fly */ |
53 | 53 |
CL_TYPE_MAIL, /* magic + on the fly */ |
54 |
+ CL_TYPE_SFX, /* foo SFX marker */ |
|
54 | 55 |
CL_TYPE_ZIPSFX, /* on the fly */ |
55 | 56 |
CL_TYPE_RARSFX /* on the fly */ |
56 | 57 |
|
57 | 58 |
} cli_file_t; |
58 | 59 |
|
60 |
+struct cli_matched_type { |
|
61 |
+ cli_file_t type; |
|
62 |
+ size_t offset; |
|
63 |
+ struct cli_matched_type *next; |
|
64 |
+}; |
|
65 |
+ |
|
59 | 66 |
cli_file_t cli_filetype(const char *buf, size_t buflen); |
60 | 67 |
cli_file_t cli_filetype2(int desc); |
61 | 68 |
int cli_addtypesigs(struct cl_engine *engine); |
... | ... |
@@ -260,12 +260,13 @@ 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, unsigned long int *ftoffset) |
|
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) |
|
264 | 264 |
{ |
265 | 265 |
struct cli_ac_node *current; |
266 | 266 |
struct cli_ac_patt *pt; |
267 | 267 |
int type = CL_CLEAN, dist, t; |
268 | 268 |
unsigned int i, position; |
269 |
+ struct cli_matched_type *tnode; |
|
269 | 270 |
|
270 | 271 |
|
271 | 272 |
if(!root->ac_root) |
... | ... |
@@ -316,11 +317,19 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam |
316 | 316 |
if(++partcnt[pt->sigid] == pt->parts) { /* the last one */ |
317 | 317 |
if(pt->type) { |
318 | 318 |
if(otfrec) { |
319 |
- if(pt->type > type) { |
|
319 |
+ if(pt->type > type || pt->type >= CL_TYPE_SFX) { |
|
320 | 320 |
cli_dbgmsg("Matched signature for file type: %s\n", pt->virname); |
321 | 321 |
type = pt->type; |
322 |
- if(ftoffset) |
|
323 |
- *ftoffset = offset + position; |
|
322 |
+ if(ftoffset && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) { |
|
323 |
+ if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) { |
|
324 |
+ cli_errmsg("Can't alloc memory for new type node\n"); |
|
325 |
+ return CL_EMEM; |
|
326 |
+ } |
|
327 |
+ tnode->type = type; |
|
328 |
+ tnode->offset = offset + position; |
|
329 |
+ tnode->next = *ftoffset; |
|
330 |
+ *ftoffset = tnode; |
|
331 |
+ } |
|
324 | 332 |
} |
325 | 333 |
} |
326 | 334 |
} else { |
... | ... |
@@ -336,12 +345,20 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam |
336 | 336 |
} else { /* old type signature */ |
337 | 337 |
if(pt->type) { |
338 | 338 |
if(otfrec) { |
339 |
- if(pt->type > type) { |
|
339 |
+ if(pt->type > type || pt->type >= CL_TYPE_SFX) { |
|
340 | 340 |
cli_dbgmsg("Matched signature for file type: %s\n", pt->virname); |
341 | 341 |
|
342 | 342 |
type = pt->type; |
343 |
- if(ftoffset) |
|
344 |
- *ftoffset = offset + position; |
|
343 |
+ if(ftoffset && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) { |
|
344 |
+ if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) { |
|
345 |
+ cli_errmsg("Can't alloc memory for new type node\n"); |
|
346 |
+ return CL_EMEM; |
|
347 |
+ } |
|
348 |
+ tnode->type = type; |
|
349 |
+ tnode->offset = offset + position; |
|
350 |
+ tnode->next = *ftoffset; |
|
351 |
+ *ftoffset = tnode; |
|
352 |
+ } |
|
345 | 353 |
} |
346 | 354 |
} |
347 | 355 |
} else { |
... | ... |
@@ -21,11 +21,12 @@ |
21 | 21 |
|
22 | 22 |
#include "clamav.h" |
23 | 23 |
#include "matcher.h" |
24 |
+#include "filetypes.h" |
|
24 | 25 |
|
25 | 26 |
#define AC_DEFAULT_DEPTH 2 |
26 | 27 |
|
27 | 28 |
int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern); |
28 |
-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, unsigned long int *ftoffset); |
|
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 | 30 |
int cli_ac_buildtrie(struct cli_matcher *root); |
30 | 31 |
void cli_ac_free(struct cli_matcher *root); |
31 | 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, unsigned long int *ftoffset) |
|
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) |
|
278 | 278 |
{ |
279 | 279 |
char *buffer, *buff, *endbl, *pt; |
280 | 280 |
int bytes, buffsize, length, ret, *gpartcnt, *tpartcnt; |
... | ... |
@@ -20,10 +20,11 @@ |
20 | 20 |
#define __MATCHER_H |
21 | 21 |
|
22 | 22 |
#include "clamav.h" |
23 |
+#include "filetypes.h" |
|
23 | 24 |
|
24 | 25 |
#define CL_TARGET_TABLE_SIZE 7 |
25 | 26 |
|
26 |
-int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, unsigned long int *ftoffset); |
|
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 | 28 |
|
28 | 29 |
int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, unsigned short ftype); |
29 | 30 |
|
... | ... |
@@ -285,7 +285,6 @@ static int cli_scanzip(int desc, const char **virname, unsigned long int *scanne |
285 | 285 |
lseek(desc, offset, SEEK_SET); |
286 | 286 |
|
287 | 287 |
if((zdir = zzip_dir_fdopen(dup(desc), &err)) == NULL) { |
288 |
- cli_dbgmsg("Zip: Not supported file format ?.\n"); |
|
289 | 288 |
cli_dbgmsg("Zip: zzip_dir_fdopen() return code: %d\n", err); |
290 | 289 |
/* no return with CL_EZIP due to password protected zips */ |
291 | 290 |
return CL_CLEAN; |
... | ... |
@@ -1646,7 +1645,7 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne |
1646 | 1646 |
|
1647 | 1647 |
if(type != CL_TYPE_DATA && ret != CL_VIRUS) { /* scan the raw file */ |
1648 | 1648 |
int ftrec; |
1649 |
- unsigned long int ftoffset; |
|
1649 |
+ struct cli_matched_type *ftoffset = NULL, *fpt; |
|
1650 | 1650 |
|
1651 | 1651 |
switch(type) { |
1652 | 1652 |
case CL_TYPE_UNKNOWN_TEXT: |
... | ... |
@@ -1685,19 +1684,36 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne |
1685 | 1685 |
break; |
1686 | 1686 |
|
1687 | 1687 |
case CL_TYPE_RARSFX: |
1688 |
- if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE) { |
|
1689 |
- cli_dbgmsg("RAR-SFX found at %d\n", ftoffset); |
|
1690 |
- if(cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, ftoffset) == CL_VIRUS) |
|
1691 |
- return CL_VIRUS; |
|
1692 |
- } |
|
1688 |
+ case CL_TYPE_ZIPSFX: |
|
1689 |
+ if(type == CL_TYPE_MSEXE) { |
|
1690 |
+ if(SCAN_ARCHIVE) { |
|
1691 |
+ fpt = ftoffset; |
|
1692 |
+ while(fpt) { |
|
1693 |
+ if(fpt->type == CL_TYPE_RARSFX) { |
|
1694 |
+ cli_dbgmsg("RAR-SFX signature found at %d\n", fpt->offset); |
|
1695 |
+ if((ret = cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1696 |
+ break; |
|
1697 |
+ } else if(fpt->type == CL_TYPE_ZIPSFX) { |
|
1698 |
+ cli_dbgmsg("ZIP-SFX signature found at %d\n", fpt->offset); |
|
1699 |
+ if((ret = cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS)) |
|
1700 |
+ break; |
|
1701 |
+ } |
|
1702 |
+ fpt = fpt->next; |
|
1703 |
+ } |
|
1704 |
+ } |
|
1705 |
+ |
|
1706 |
+ while(ftoffset) { |
|
1707 |
+ fpt = ftoffset; |
|
1708 |
+ ftoffset = ftoffset->next; |
|
1709 |
+ free(fpt); |
|
1710 |
+ } |
|
1711 |
+ |
|
1712 |
+ if(ret == CL_VIRUS) |
|
1713 |
+ return ret; |
|
1714 |
+ } |
|
1693 | 1715 |
break; |
1694 | 1716 |
|
1695 |
- case CL_TYPE_ZIPSFX: |
|
1696 |
- if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE) { |
|
1697 |
- cli_dbgmsg("ZIP-SFX found at %d\n", ftoffset); |
|
1698 |
- if(cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, ftoffset) == CL_VIRUS) |
|
1699 |
- return CL_VIRUS; |
|
1700 |
- } |
|
1717 |
+ default: |
|
1701 | 1718 |
break; |
1702 | 1719 |
} |
1703 | 1720 |
nret == CL_TYPE_MAIL ? mrec-- : arec--; |