cache over 256 trees
aCaB authored on 2009/08/11 19:23:14... | ... |
@@ -131,7 +131,7 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \ |
131 | 131 |
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \ |
132 | 132 |
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \ |
133 | 133 |
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \ |
134 |
- ishield.c ishield.h bignum.c bignum_class.h |
|
134 |
+ ishield.c ishield.h cache.c cache.h bignum.c bignum_class.h |
|
135 | 135 |
@LINK_TOMMATH_FALSE@am__objects_1 = libclamav_la-bignum.lo |
136 | 136 |
am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ |
137 | 137 |
libclamav_la-matcher-bm.lo libclamav_la-matcher.lo \ |
... | ... |
@@ -177,7 +177,8 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ |
177 | 177 |
libclamav_la-version.lo libclamav_la-mpool.lo \ |
178 | 178 |
libclamav_la-sha256.lo libclamav_la-bytecode.lo \ |
179 | 179 |
libclamav_la-bytecode_vm.lo libclamav_la-cpio.lo \ |
180 |
- libclamav_la-macho.lo libclamav_la-ishield.lo $(am__objects_1) |
|
180 |
+ libclamav_la-macho.lo libclamav_la-ishield.lo \ |
|
181 |
+ libclamav_la-cache.lo $(am__objects_1) |
|
181 | 182 |
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS) |
182 | 183 |
libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ |
183 | 184 |
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libclamav_la_CFLAGS) \ |
... | ... |
@@ -547,7 +548,7 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ |
547 | 547 |
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \ |
548 | 548 |
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \ |
549 | 549 |
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \ |
550 |
- ishield.c ishield.h $(am__append_7) |
|
550 |
+ ishield.c ishield.h cache.c cache.h $(am__append_7) |
|
551 | 551 |
noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la |
552 | 552 |
COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno |
553 | 553 |
@MAINTAINER_MODE_TRUE@BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf |
... | ... |
@@ -681,6 +682,7 @@ distclean-compile: |
681 | 681 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-bytecode_vm.Plo@am__quote@ |
682 | 682 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-bzlib.Plo@am__quote@ |
683 | 683 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-cab.Plo@am__quote@ |
684 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-cache.Plo@am__quote@ |
|
684 | 685 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-chmunpack.Plo@am__quote@ |
685 | 686 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-cpio.Plo@am__quote@ |
686 | 687 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-cvd.Plo@am__quote@ |
... | ... |
@@ -1417,6 +1419,13 @@ libclamav_la-ishield.lo: ishield.c |
1417 | 1417 |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
1418 | 1418 |
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-ishield.lo `test -f 'ishield.c' || echo '$(srcdir)/'`ishield.c |
1419 | 1419 |
|
1420 |
+libclamav_la-cache.lo: cache.c |
|
1421 |
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-cache.lo -MD -MP -MF $(DEPDIR)/libclamav_la-cache.Tpo -c -o libclamav_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c |
|
1422 |
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-cache.Tpo $(DEPDIR)/libclamav_la-cache.Plo |
|
1423 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='libclamav_la-cache.lo' libtool=yes @AMDEPBACKSLASH@ |
|
1424 |
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
1425 |
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c |
|
1426 |
+ |
|
1420 | 1427 |
libclamav_la-bignum.lo: bignum.c |
1421 | 1428 |
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bignum.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bignum.Tpo -c -o libclamav_la-bignum.lo `test -f 'bignum.c' || echo '$(srcdir)/'`bignum.c |
1422 | 1429 |
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-bignum.Tpo $(DEPDIR)/libclamav_la-bignum.Plo |
1423 | 1430 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,186 @@ |
0 |
+#include <string.h> |
|
1 |
+#include <stdlib.h> |
|
2 |
+#include <pthread.h> |
|
3 |
+ |
|
4 |
+#include "md5.h" |
|
5 |
+#include "mpool.h" |
|
6 |
+#include "clamav.h" |
|
7 |
+#include "cache.h" |
|
8 |
+ |
|
9 |
+#if HAVE_CONFIG_H |
|
10 |
+#include "clamav-config.h" |
|
11 |
+#endif |
|
12 |
+ |
|
13 |
+#define CACHE_PERTURB 10 |
|
14 |
+/* 1/10th */ |
|
15 |
+ |
|
16 |
+static mpool_t *mempool = NULL; |
|
17 |
+static struct CACHE { |
|
18 |
+ struct CACHE_ENTRY { |
|
19 |
+ unsigned char hash[15]; |
|
20 |
+ uint32_t dbver; |
|
21 |
+ uint32_t hits; |
|
22 |
+ } *items; |
|
23 |
+ pthread_mutex_t mutex; |
|
24 |
+ uint32_t lastdb; |
|
25 |
+} *cache = NULL; |
|
26 |
+static unsigned int cache_entries = 0; |
|
27 |
+ |
|
28 |
+int cache_init(unsigned int entries) { |
|
29 |
+ unsigned int i; |
|
30 |
+ |
|
31 |
+ if(!(mempool = mpool_create())) { |
|
32 |
+ cli_errmsg("mpool init fail\n"); |
|
33 |
+ return 1; |
|
34 |
+ } |
|
35 |
+ if(!(cache = mpool_malloc(mempool, sizeof(struct CACHE) * 256))) { |
|
36 |
+ cli_errmsg("mpool malloc fail\n"); |
|
37 |
+ mpool_destroy(mempool); |
|
38 |
+ return 1; |
|
39 |
+ } |
|
40 |
+ |
|
41 |
+ for(i=0; i<256; i++) { |
|
42 |
+ struct CACHE_ENTRY *e = mpool_calloc(mempool, sizeof(struct CACHE_ENTRY), entries); |
|
43 |
+ if(!e) { |
|
44 |
+ cli_errmsg("mpool calloc fail\n"); |
|
45 |
+ mpool_destroy(mempool); |
|
46 |
+ return 1; |
|
47 |
+ } |
|
48 |
+ cache[i].items = e; |
|
49 |
+ cache[i].lastdb = 0; |
|
50 |
+ if(pthread_mutex_init(&cache[i].mutex, NULL)) { |
|
51 |
+ cli_errmsg("mutex init fail\n"); |
|
52 |
+ mpool_destroy(mempool); |
|
53 |
+ return 1; |
|
54 |
+ } |
|
55 |
+ } |
|
56 |
+ cache_entries = entries; |
|
57 |
+ return 0; |
|
58 |
+} |
|
59 |
+ |
|
60 |
+void cache_swap(struct CACHE_ENTRY *e, unsigned int a) { |
|
61 |
+ struct CACHE_ENTRY t; |
|
62 |
+ unsigned int b = a-1; |
|
63 |
+ |
|
64 |
+ if(!a || e[a].hits <= e[b].hits) |
|
65 |
+ return; |
|
66 |
+ |
|
67 |
+ do { |
|
68 |
+ if(e[a].hits > e[b].hits) |
|
69 |
+ continue; |
|
70 |
+ break; |
|
71 |
+ } while(b--); |
|
72 |
+ b++; |
|
73 |
+ |
|
74 |
+ memcpy(&t, &e[a], sizeof(t)); |
|
75 |
+ memcpy(&e[a], &e[b], sizeof(t)); |
|
76 |
+ memcpy(&e[b], &t, sizeof(t)); |
|
77 |
+} |
|
78 |
+ |
|
79 |
+void updb(uint32_t db, unsigned int skip) { |
|
80 |
+ unsigned int i; |
|
81 |
+ for(i=0; i<256; i++) { |
|
82 |
+ if(i==skip) continue; |
|
83 |
+ if(pthread_mutex_lock(&cache[i].mutex)) { |
|
84 |
+ cli_errmsg("mutex lock fail\n"); |
|
85 |
+ continue; |
|
86 |
+ } |
|
87 |
+ cache[i].lastdb = db; |
|
88 |
+ pthread_mutex_unlock(&cache[i].mutex); |
|
89 |
+ } |
|
90 |
+} |
|
91 |
+ |
|
92 |
+int cache_check(unsigned char *md5, cli_ctx *ctx) { |
|
93 |
+ unsigned int i; |
|
94 |
+ int ret = CL_VIRUS; |
|
95 |
+ struct CACHE_ENTRY *e; |
|
96 |
+ struct CACHE *c; |
|
97 |
+ |
|
98 |
+ if(!cache) return ret; |
|
99 |
+ |
|
100 |
+ c = &cache[*md5]; |
|
101 |
+ e = c->items; |
|
102 |
+ if(pthread_mutex_lock(&c->mutex)) { |
|
103 |
+ cli_errmsg("mutex lock fail\n"); |
|
104 |
+ return ret; |
|
105 |
+ } |
|
106 |
+ if(c->lastdb <= ctx->engine->dbversion[0]) { |
|
107 |
+ if(c->lastdb < ctx->engine->dbversion[0]) { |
|
108 |
+ c->lastdb = ctx->engine->dbversion[0]; |
|
109 |
+ updb(c->lastdb, *md5); |
|
110 |
+ } else { |
|
111 |
+ for(i=0; i<cache_entries; i++) { |
|
112 |
+ if(!e[i].hits) break; |
|
113 |
+ if(e[i].dbver == c->lastdb && !memcmp(e[i].hash, md5 + 1, 15)) { |
|
114 |
+ e[i].hits++; |
|
115 |
+ cache_swap(e, i); |
|
116 |
+ ret = CL_CLEAN; |
|
117 |
+ cli_warnmsg("cached\n"); |
|
118 |
+ break; |
|
119 |
+ } |
|
120 |
+ } |
|
121 |
+ } |
|
122 |
+ } |
|
123 |
+ pthread_mutex_unlock(&c->mutex); |
|
124 |
+ return ret; |
|
125 |
+} |
|
126 |
+ |
|
127 |
+void cache_add(unsigned char *md5, cli_ctx *ctx) { |
|
128 |
+ unsigned int i, replace; |
|
129 |
+ struct CACHE_ENTRY *e; |
|
130 |
+ struct CACHE *c; |
|
131 |
+ |
|
132 |
+ if(!cache) return; |
|
133 |
+ |
|
134 |
+ c = &cache[*md5]; |
|
135 |
+ e = c->items; |
|
136 |
+ if(pthread_mutex_lock(&c->mutex)) { |
|
137 |
+ cli_errmsg("mutex lock fail\n"); |
|
138 |
+ return; |
|
139 |
+ } |
|
140 |
+ if(c->lastdb == ctx->engine->dbversion[0]) { |
|
141 |
+ replace = cache_entries; |
|
142 |
+ for(i=0; i<cache_entries; i++) { |
|
143 |
+ if(!e[i].hits) break; |
|
144 |
+ if(replace == cache_entries && e[i].dbver < c->lastdb) { |
|
145 |
+ replace = i; |
|
146 |
+ } else if(e[i].hits && !memcmp(e[i].hash, md5 + 1, 15)) { |
|
147 |
+ e[i].hits++; |
|
148 |
+ cache_swap(e, i); |
|
149 |
+ pthread_mutex_unlock(&c->mutex); |
|
150 |
+ return; |
|
151 |
+ } |
|
152 |
+ } |
|
153 |
+ if(replace == cache_entries) |
|
154 |
+ replace = cache_entries - 1 - (rand() % (cache_entries / CACHE_PERTURB)); |
|
155 |
+ e[replace].hits = 1; |
|
156 |
+ e[replace].dbver = c->lastdb; |
|
157 |
+ memcpy(e[replace].hash, md5 + 1, 15); |
|
158 |
+ cache_swap(e, replace); |
|
159 |
+ } |
|
160 |
+ pthread_mutex_unlock(&c->mutex); |
|
161 |
+ return; |
|
162 |
+} |
|
163 |
+ |
|
164 |
+int cache_chekdesc(int desc, size_t size, unsigned char *hash, cli_ctx *ctx) { |
|
165 |
+ cli_md5_ctx md5; |
|
166 |
+ unsigned char buf[8192]; |
|
167 |
+ |
|
168 |
+ off_t seekback = lseek(desc, 0, SEEK_CUR); |
|
169 |
+ |
|
170 |
+ if(!cache) return CL_VIRUS; |
|
171 |
+ |
|
172 |
+ cli_md5_init(&md5); |
|
173 |
+ while(size) { |
|
174 |
+ size_t readme = size < sizeof(buf) ? size : sizeof(buf); |
|
175 |
+ if(cli_readn(desc, buf, readme)!=readme) { |
|
176 |
+ lseek(desc, seekback, SEEK_SET); |
|
177 |
+ return CL_VIRUS; |
|
178 |
+ } |
|
179 |
+ cli_md5_update(&md5, buf, readme); |
|
180 |
+ size-=readme; |
|
181 |
+ } |
|
182 |
+ cli_md5_final(hash, &md5); |
|
183 |
+ lseek(desc, seekback, SEEK_SET); |
|
184 |
+ return cache_check(hash, ctx); |
|
185 |
+} |
0 | 186 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,11 @@ |
0 |
+#ifndef __CACHE_H |
|
1 |
+#define __CACHE_H |
|
2 |
+ |
|
3 |
+#include "others.h" |
|
4 |
+ |
|
5 |
+int cache_init(unsigned int entries); |
|
6 |
+int cache_check(unsigned char *md5, cli_ctx *ctx); |
|
7 |
+void cache_add(unsigned char *md5, cli_ctx *ctx); |
|
8 |
+int cache_chekdesc(int desc, size_t size, unsigned char *hash, cli_ctx *ctx); |
|
9 |
+ |
|
10 |
+#endif |
... | ... |
@@ -445,3 +445,173 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc |
445 | 445 |
|
446 | 446 |
return (acmode & AC_SCAN_FT) ? type : CL_CLEAN; |
447 | 447 |
} |
448 |
+ |
|
449 |
+int cli_scandesc_hash(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *digest) |
|
450 |
+{ |
|
451 |
+ unsigned char *buffer, *buff, *endbl, *upt; |
|
452 |
+ int ret = CL_CLEAN, type = CL_CLEAN, bytes; |
|
453 |
+ unsigned int i, evalcnt; |
|
454 |
+ uint32_t buffersize, length, maxpatlen, shift = 0, offset = 0; |
|
455 |
+ uint64_t evalids; |
|
456 |
+ struct cli_ac_data gdata, tdata; |
|
457 |
+ struct cli_matcher *groot = NULL, *troot = NULL; |
|
458 |
+ |
|
459 |
+ |
|
460 |
+ if(!ctx->engine) { |
|
461 |
+ cli_errmsg("cli_scandesc: engine == NULL\n"); |
|
462 |
+ return CL_ENULLARG; |
|
463 |
+ } |
|
464 |
+ |
|
465 |
+ if(!ftonly) |
|
466 |
+ groot = ctx->engine->root[0]; /* generic signatures */ |
|
467 |
+ |
|
468 |
+ if(ftype) { |
|
469 |
+ for(i = 1; i < CLI_MTARGETS; i++) { |
|
470 |
+ if(cli_mtargets[i].target == ftype) { |
|
471 |
+ troot = ctx->engine->root[i]; |
|
472 |
+ break; |
|
473 |
+ } |
|
474 |
+ } |
|
475 |
+ } |
|
476 |
+ |
|
477 |
+ if(ftonly) { |
|
478 |
+ if(!troot) |
|
479 |
+ return CL_CLEAN; |
|
480 |
+ |
|
481 |
+ maxpatlen = troot->maxpatlen; |
|
482 |
+ } else { |
|
483 |
+ if(troot) |
|
484 |
+ maxpatlen = MAX(troot->maxpatlen, groot->maxpatlen); |
|
485 |
+ else |
|
486 |
+ maxpatlen = groot->maxpatlen; |
|
487 |
+ } |
|
488 |
+ |
|
489 |
+ /* prepare the buffer */ |
|
490 |
+ buffersize = maxpatlen + SCANBUFF; |
|
491 |
+ if(!(buffer = (unsigned char *) cli_calloc(buffersize, sizeof(unsigned char)))) { |
|
492 |
+ cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%u)\n", buffersize); |
|
493 |
+ return CL_EMEM; |
|
494 |
+ } |
|
495 |
+ |
|
496 |
+ if(!ftonly && (ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) |
|
497 |
+ return ret; |
|
498 |
+ |
|
499 |
+ if(troot) { |
|
500 |
+ if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) |
|
501 |
+ return ret; |
|
502 |
+ } |
|
503 |
+ |
|
504 |
+ buff = buffer; |
|
505 |
+ buff += maxpatlen; /* pointer to read data block */ |
|
506 |
+ endbl = buff + SCANBUFF - maxpatlen; /* pointer to the last block |
|
507 |
+ * length of maxpatlen |
|
508 |
+ */ |
|
509 |
+ |
|
510 |
+ upt = buff; |
|
511 |
+ while((bytes = cli_readn(desc, buff + shift, SCANBUFF - shift)) > 0) { |
|
512 |
+ |
|
513 |
+ if(ctx->scanned) |
|
514 |
+ *ctx->scanned += bytes / CL_COUNT_PRECISION; |
|
515 |
+ |
|
516 |
+ length = shift + bytes; |
|
517 |
+ if(upt == buffer) |
|
518 |
+ length += maxpatlen; |
|
519 |
+ |
|
520 |
+ if(troot) { |
|
521 |
+ if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, ftype, desc)) != CL_VIRUS) |
|
522 |
+ ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, desc, ftoffset, acmode, NULL); |
|
523 |
+ |
|
524 |
+ if(ret == CL_VIRUS) { |
|
525 |
+ free(buffer); |
|
526 |
+ if(!ftonly) |
|
527 |
+ cli_ac_freedata(&gdata); |
|
528 |
+ cli_ac_freedata(&tdata); |
|
529 |
+ |
|
530 |
+ if(cli_checkfp(desc, ctx)) |
|
531 |
+ return CL_CLEAN; |
|
532 |
+ else |
|
533 |
+ return CL_VIRUS; |
|
534 |
+ } |
|
535 |
+ } |
|
536 |
+ |
|
537 |
+ if(!ftonly) { |
|
538 |
+ if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, ftype, desc)) != CL_VIRUS) |
|
539 |
+ ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, desc, ftoffset, acmode, NULL); |
|
540 |
+ |
|
541 |
+ if(ret == CL_VIRUS) { |
|
542 |
+ free(buffer); |
|
543 |
+ cli_ac_freedata(&gdata); |
|
544 |
+ if(troot) |
|
545 |
+ cli_ac_freedata(&tdata); |
|
546 |
+ if(cli_checkfp(desc, ctx)) |
|
547 |
+ return CL_CLEAN; |
|
548 |
+ else |
|
549 |
+ return CL_VIRUS; |
|
550 |
+ |
|
551 |
+ } else if((acmode & AC_SCAN_FT) && ret >= CL_TYPENO) { |
|
552 |
+ if(ret > type) |
|
553 |
+ type = ret; |
|
554 |
+ } |
|
555 |
+ } |
|
556 |
+ |
|
557 |
+ if(bytes + shift == SCANBUFF) { |
|
558 |
+ memmove(buffer, endbl, maxpatlen); |
|
559 |
+ offset += SCANBUFF; |
|
560 |
+ |
|
561 |
+ if(upt == buff) { |
|
562 |
+ upt = buffer; |
|
563 |
+ offset -= maxpatlen; |
|
564 |
+ } |
|
565 |
+ |
|
566 |
+ shift = 0; |
|
567 |
+ |
|
568 |
+ } else { |
|
569 |
+ shift += bytes; |
|
570 |
+ } |
|
571 |
+ } |
|
572 |
+ |
|
573 |
+ free(buffer); |
|
574 |
+ |
|
575 |
+ if(troot) { |
|
576 |
+ for(i = 0; i < troot->ac_lsigs; i++) { |
|
577 |
+ evalcnt = 0; |
|
578 |
+ evalids = 0; |
|
579 |
+ if(cli_ac_chklsig(troot->ac_lsigtable[i]->logic, troot->ac_lsigtable[i]->logic + strlen(troot->ac_lsigtable[i]->logic), tdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) { |
|
580 |
+ if(ctx->virname) |
|
581 |
+ *ctx->virname = troot->ac_lsigtable[i]->virname; |
|
582 |
+ ret = CL_VIRUS; |
|
583 |
+ break; |
|
584 |
+ } |
|
585 |
+ } |
|
586 |
+ cli_ac_freedata(&tdata); |
|
587 |
+ } |
|
588 |
+ |
|
589 |
+ if(groot) { |
|
590 |
+ if(ret != CL_VIRUS) for(i = 0; i < groot->ac_lsigs; i++) { |
|
591 |
+ evalcnt = 0; |
|
592 |
+ evalids = 0; |
|
593 |
+ if(cli_ac_chklsig(groot->ac_lsigtable[i]->logic, groot->ac_lsigtable[i]->logic + strlen(groot->ac_lsigtable[i]->logic), gdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) { |
|
594 |
+ if(ctx->virname) |
|
595 |
+ *ctx->virname = groot->ac_lsigtable[i]->virname; |
|
596 |
+ ret = CL_VIRUS; |
|
597 |
+ break; |
|
598 |
+ } |
|
599 |
+ } |
|
600 |
+ cli_ac_freedata(&gdata); |
|
601 |
+ } |
|
602 |
+ |
|
603 |
+ if(ret == CL_VIRUS) { |
|
604 |
+ lseek(desc, 0, SEEK_SET); |
|
605 |
+ if(cli_checkfp(desc, ctx)) |
|
606 |
+ return CL_CLEAN; |
|
607 |
+ else |
|
608 |
+ return CL_VIRUS; |
|
609 |
+ } |
|
610 |
+ |
|
611 |
+ if(!ftonly && ctx->engine->md5_hdb) { |
|
612 |
+ if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, 0, -1) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, 0, -1) != CL_VIRUS)) |
|
613 |
+ return CL_VIRUS; |
|
614 |
+ } |
|
615 |
+ |
|
616 |
+ return (acmode & AC_SCAN_FT) ? type : CL_CLEAN; |
|
617 |
+} |
... | ... |
@@ -127,6 +127,7 @@ struct cli_target_info { |
127 | 127 |
int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata); |
128 | 128 |
|
129 | 129 |
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode); |
130 |
+int cli_scandesc_hash(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *digest); |
|
130 | 131 |
|
131 | 132 |
int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname); |
132 | 133 |
|
... | ... |
@@ -96,6 +96,7 @@ |
96 | 96 |
#include "macho.h" |
97 | 97 |
#include "ishield.h" |
98 | 98 |
#include "7z.h" |
99 |
+#include "cache.h" |
|
99 | 100 |
|
100 | 101 |
#ifdef HAVE_BZLIB_H |
101 | 102 |
#include <bzlib.h> |
... | ... |
@@ -1881,6 +1882,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1881 | 1881 |
cli_file_t type, dettype = 0; |
1882 | 1882 |
struct stat sb; |
1883 | 1883 |
uint8_t typercg = 1; |
1884 |
+ unsigned char hash[16]; |
|
1884 | 1885 |
|
1885 | 1886 |
if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) { |
1886 | 1887 |
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel); |
... | ... |
@@ -1910,13 +1912,17 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1910 | 1910 |
if(cli_updatelimits(ctx, sb.st_size)!=CL_CLEAN) |
1911 | 1911 |
return CL_CLEAN; |
1912 | 1912 |
|
1913 |
+ if(cache_chekdesc(desc, sb.st_size, hash, ctx) == CL_CLEAN) |
|
1914 |
+ return CL_CLEAN; |
|
1915 |
+ |
|
1913 | 1916 |
if(!ctx->options || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */ |
1914 | 1917 |
if(ctx->recursion == ctx->engine->maxreclevel) |
1915 | 1918 |
cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n"); |
1916 | 1919 |
else |
1917 | 1920 |
cli_dbgmsg("Raw mode: No support for special files\n"); |
1918 |
- if((ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR)) == CL_VIRUS) |
|
1921 |
+ if((ret = cli_scandesc_hash(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, hash)) == CL_VIRUS) |
|
1919 | 1922 |
cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc); |
1923 |
+ else cache_add(hash, ctx); |
|
1920 | 1924 |
return ret; |
1921 | 1925 |
} |
1922 | 1926 |
|
... | ... |
@@ -2177,8 +2183,10 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2177 | 2177 |
case CL_EMAXSIZE: |
2178 | 2178 |
case CL_EMAXFILES: |
2179 | 2179 |
cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret)); |
2180 |
+ cache_add(hash, ctx); |
|
2180 | 2181 |
return CL_CLEAN; |
2181 | 2182 |
default: |
2183 |
+ if(ret == CL_CLEAN) cache_add(hash, ctx); |
|
2182 | 2184 |
return ret; |
2183 | 2185 |
} |
2184 | 2186 |
} |