... | ... |
@@ -116,7 +116,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx) |
116 | 116 |
|
117 | 117 |
if (d == NULL) |
118 | 118 |
return; |
119 |
- if (!(d->options & CL_SCAN_ALLMATCHES)) |
|
119 |
+ if (!(d->options & CL_SCAN_ALLMATCHES) && !(d->options & CL_SCAN_HEURISTIC_PRECEDENCE)) |
|
120 | 120 |
return; |
121 | 121 |
if (virname == NULL) |
122 | 122 |
return; |
... | ... |
@@ -124,6 +124,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx) |
124 | 124 |
fname = (c && c->filename) ? c->filename : "(filename not set)"; |
125 | 125 |
|
126 | 126 |
if (virname) { |
127 |
+ d->infected++; |
|
127 | 128 |
conn_reply_virus(d->conn, fname, virname); |
128 | 129 |
if(c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled) |
129 | 130 |
logg("~%s: %s(%s:%llu) FOUND\n", fname, virname, c->virhash, c->virsize); |
... | ... |
@@ -274,19 +275,18 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea |
274 | 274 |
} |
275 | 275 |
|
276 | 276 |
if (ret == CL_VIRUS) { |
277 |
- scandata->infected++; |
|
278 | 277 |
|
279 |
- if (scandata->options & CL_SCAN_ALLMATCHES) { |
|
278 |
+ if (scandata->options & CL_SCAN_ALLMATCHES || (scandata->infected && scandata->options & CL_SCAN_HEURISTIC_PRECEDENCE)) { |
|
280 | 279 |
if(optget(scandata->opts, "PreludeEnable")->enabled){ |
281 | 280 |
prelude_logging(filename, virname, context.virhash, context.virsize); |
282 | 281 |
} |
283 | 282 |
virusaction(filename, virname, scandata->opts); |
284 | 283 |
} else { |
284 |
+ scandata->infected++; |
|
285 | 285 |
if (conn_reply_virus(scandata->conn, filename, virname) == -1) { |
286 | 286 |
free(filename); |
287 | 287 |
return CL_ETIMEOUT; |
288 | 288 |
} |
289 |
- |
|
290 | 289 |
if(optget(scandata->opts, "PreludeEnable")->enabled){ |
291 | 290 |
prelude_logging(filename, virname, context.virhash, context.virsize); |
292 | 291 |
} |
... | ... |
@@ -108,11 +108,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) { |
108 | 108 |
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); |
109 | 109 |
if(res == SZ_ERROR_ENCRYPTED && DETECT_ENCRYPTED) { |
110 | 110 |
cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n"); |
111 |
- cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); |
|
112 |
- viruses_found++; |
|
113 |
- if(!SCAN_ALL) { |
|
114 |
- found = CL_VIRUS; |
|
115 |
- } |
|
111 |
+ found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); |
|
116 | 112 |
} else if(res == SZ_OK) { |
117 | 113 |
UInt32 i, blockIndex = 0xFFFFFFFF; |
118 | 114 |
Byte *outBuffer = 0; |
... | ... |
@@ -164,11 +160,13 @@ int cli_7unz (cli_ctx *ctx, size_t offset) { |
164 | 164 |
encrypted = 1; |
165 | 165 |
if(DETECT_ENCRYPTED) { |
166 | 166 |
cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n"); |
167 |
- cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); |
|
168 |
- viruses_found++; |
|
169 |
- if(!SCAN_ALL) { |
|
170 |
- found = CL_VIRUS; |
|
171 |
- break; |
|
167 |
+ found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); |
|
168 |
+ if (found != CL_CLEAN) { |
|
169 |
+ if (found == CL_VIRUS) { |
|
170 |
+ if (SCAN_ALL) |
|
171 |
+ viruses_found++; |
|
172 |
+ } else |
|
173 |
+ break; |
|
172 | 174 |
} |
173 | 175 |
} |
174 | 176 |
} |
... | ... |
@@ -248,6 +248,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size |
248 | 248 |
int ret = CL_CLEAN, tmp = CL_CLEAN; |
249 | 249 |
off_t pos; |
250 | 250 |
uint32_t max_prtns = 0; |
251 |
+ int virus_found = 0; |
|
251 | 252 |
|
252 | 253 |
prtn_intxn_list_init(&prtncheck); |
253 | 254 |
|
... | ... |
@@ -286,35 +287,30 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size |
286 | 286 |
|
287 | 287 |
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount); |
288 | 288 |
if (tmp != CL_CLEAN) { |
289 |
- if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { |
|
289 |
+ if (tmp == CL_VIRUS) { |
|
290 | 290 |
apm_parsemsg("Name: %s\n", (char*)aptable.name); |
291 | 291 |
apm_parsemsg("Type: %s\n", (char*)aptable.type); |
292 | 292 |
|
293 | 293 |
cli_dbgmsg("cli_scanapm: detected intersection with partitions " |
294 | 294 |
"[%u, %u]\n", pitxn, i); |
295 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
295 |
+ ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
296 |
+ if (ret == CL_VIRUS) |
|
297 |
+ virus_found = 1; |
|
298 |
+ if (SCAN_ALL || ret == CL_CLEAN) |
|
299 |
+ tmp = 0; |
|
300 |
+ else |
|
301 |
+ goto leave; |
|
302 |
+ } else { |
|
296 | 303 |
ret = tmp; |
297 |
- tmp = 0; |
|
298 |
- } |
|
299 |
- else if (tmp == CL_VIRUS) { |
|
300 |
- apm_parsemsg("Name: %s\n", (char*)aptable.name); |
|
301 |
- apm_parsemsg("Type: %s\n", (char*)aptable.type); |
|
302 |
- |
|
303 |
- cli_dbgmsg("cli_scanapm: detected intersection with partitions " |
|
304 |
- "[%u, %u]\n", pitxn, i); |
|
305 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
306 |
- prtn_intxn_list_free(&prtncheck); |
|
307 |
- return CL_VIRUS; |
|
308 |
- } |
|
309 |
- else { |
|
310 |
- prtn_intxn_list_free(&prtncheck); |
|
311 |
- return tmp; |
|
304 |
+ goto leave; |
|
312 | 305 |
} |
313 | 306 |
} |
314 |
- |
|
315 | 307 |
pos += sectorsize; |
316 | 308 |
} |
317 | 309 |
|
310 |
+ leave: |
|
318 | 311 |
prtn_intxn_list_free(&prtncheck); |
312 |
+ if (virus_found) |
|
313 |
+ return CL_VIRUS; |
|
319 | 314 |
return ret; |
320 | 315 |
} |
... | ... |
@@ -2810,11 +2810,10 @@ int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo, |
2810 | 2810 |
if (ctx.virname) { |
2811 | 2811 |
int rc; |
2812 | 2812 |
cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname); |
2813 |
- cli_append_virus(cctx, ctx.virname); |
|
2814 | 2813 |
if (!strncmp(ctx.virname, "BC.Heuristics", 13)) |
2815 |
- rc = cli_found_possibly_unwanted(cctx); |
|
2816 |
- else |
|
2817 |
- rc = CL_VIRUS; |
|
2814 |
+ rc = cli_append_possibly_unwanted(cctx, ctx.virname); |
|
2815 |
+ else |
|
2816 |
+ rc = cli_append_virus(cctx, ctx.virname); |
|
2818 | 2817 |
cli_bytecode_context_clear(&ctx); |
2819 | 2818 |
return rc; |
2820 | 2819 |
} |
... | ... |
@@ -604,6 +604,7 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize |
604 | 604 |
off_t pos; |
605 | 605 |
size_t maplen; |
606 | 606 |
uint32_t max_prtns = 0; |
607 |
+ int virus_found = 0; |
|
607 | 608 |
|
608 | 609 |
maplen = (*ctx->fmap)->real_len; |
609 | 610 |
|
... | ... |
@@ -647,23 +648,19 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize |
647 | 647 |
else { |
648 | 648 |
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1); |
649 | 649 |
if (tmp != CL_CLEAN) { |
650 |
- if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { |
|
650 |
+ if (tmp == CL_VIRUS) { |
|
651 | 651 |
cli_dbgmsg("cli_scangpt: detected intersection with partitions " |
652 | 652 |
"[%u, %u]\n", pitxn, i); |
653 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
653 |
+ ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
654 |
+ if (ret == CL_VIRUS) |
|
655 |
+ virus_found = 1; |
|
656 |
+ if (SCAN_ALL || ret == CL_CLEAN) |
|
657 |
+ tmp = 0; |
|
658 |
+ else |
|
659 |
+ goto leave; |
|
660 |
+ } else { |
|
654 | 661 |
ret = tmp; |
655 |
- tmp = 0; |
|
656 |
- } |
|
657 |
- else if (tmp == CL_VIRUS) { |
|
658 |
- cli_dbgmsg("cli_scangpt: detected intersection with partitions " |
|
659 |
- "[%u, %u]\n", pitxn, i); |
|
660 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
661 |
- prtn_intxn_list_free(&prtncheck); |
|
662 |
- return CL_VIRUS; |
|
663 |
- } |
|
664 |
- else { |
|
665 |
- prtn_intxn_list_free(&prtncheck); |
|
666 |
- return tmp; |
|
662 |
+ goto leave; |
|
667 | 663 |
} |
668 | 664 |
} |
669 | 665 |
} |
... | ... |
@@ -672,6 +669,9 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize |
672 | 672 |
pos += hdr.tableEntrySize; |
673 | 673 |
} |
674 | 674 |
|
675 |
+ leave: |
|
675 | 676 |
prtn_intxn_list_free(&prtncheck); |
677 |
+ if (virus_found) |
|
678 |
+ return CL_VIRUS; |
|
676 | 679 |
return ret; |
677 | 680 |
} |
... | ... |
@@ -176,8 +176,8 @@ struct macho_fat_arch |
176 | 176 |
if(matcher) \ |
177 | 177 |
return -1; \ |
178 | 178 |
if(DETECT_BROKEN) { \ |
179 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); \ |
|
180 |
- return CL_VIRUS; \ |
|
179 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Broken.Executable")) \ |
|
180 |
+ return CL_VIRUS; \ |
|
181 | 181 |
} \ |
182 | 182 |
return CL_EFORMAT |
183 | 183 |
|
... | ... |
@@ -738,16 +738,15 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char ** |
738 | 738 |
newres->offset = adjbuffer+p_res.match[0]; |
739 | 739 |
*res = newres; |
740 | 740 |
} else { |
741 |
- if (ctx && SCAN_ALL) { |
|
742 |
- viruses_found = 1; |
|
743 |
- cli_append_virus(ctx, (const char *)pm->virname); |
|
744 |
- } |
|
741 |
+ ret = CL_CLEAN; |
|
742 |
+ viruses_found = 1; |
|
743 |
+ if (ctx) |
|
744 |
+ ret = cli_append_virus(ctx, (const char *)pm->virname); |
|
745 | 745 |
if (virname) |
746 | 746 |
*virname = pm->virname; |
747 |
- if (!ctx || !SCAN_ALL) { |
|
748 |
- ret = CL_VIRUS; |
|
749 |
- break; |
|
750 |
- } |
|
747 |
+ if (!ctx || !SCAN_ALL) |
|
748 |
+ if (ret != CL_CLEAN) |
|
749 |
+ break; |
|
751 | 750 |
} |
752 | 751 |
} |
753 | 752 |
} |
... | ... |
@@ -157,8 +157,9 @@ static inline int matcher_run(const struct cli_matcher *root, |
157 | 157 |
if (SCAN_ALL) |
158 | 158 |
viruses_found = 1; |
159 | 159 |
else { |
160 |
- cli_append_virus(ctx, *virname); |
|
161 |
- return ret; |
|
160 |
+ ret = cli_append_virus(ctx, *virname); |
|
161 |
+ if (ret != CL_CLEAN) |
|
162 |
+ return ret; |
|
162 | 163 |
} |
163 | 164 |
} |
164 | 165 |
} |
... | ... |
@@ -169,8 +170,9 @@ static inline int matcher_run(const struct cli_matcher *root, |
169 | 169 |
if (SCAN_ALL) |
170 | 170 |
viruses_found = 1; |
171 | 171 |
else { |
172 |
- cli_append_virus(ctx, *virname); |
|
173 |
- return ret; |
|
172 |
+ ret = cli_append_virus(ctx, *virname); |
|
173 |
+ if (ret != CL_CLEAN) |
|
174 |
+ return ret; |
|
174 | 175 |
} |
175 | 176 |
} else if (ret > CL_TYPENO && acmode & AC_SCAN_VIR) |
176 | 177 |
saved_ret = ret; |
... | ... |
@@ -227,7 +229,7 @@ static inline int matcher_run(const struct cli_matcher *root, |
227 | 227 |
/* end experimental fragment */ |
228 | 228 |
|
229 | 229 |
if (ctx && !SCAN_ALL && ret == CL_VIRUS) |
230 |
- cli_append_virus(ctx, *virname); |
|
230 |
+ return cli_append_virus(ctx, *virname); |
|
231 | 231 |
if (ctx && SCAN_ALL && viruses_found) |
232 | 232 |
return CL_VIRUS; |
233 | 233 |
|
... | ... |
@@ -501,6 +503,11 @@ void cli_targetinfo(struct cli_target_info *info, unsigned int target, fmap_t *m |
501 | 501 |
|
502 | 502 |
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
503 | 503 |
{ |
504 |
+ return cli_checkfp_virus(digest, size, ctx, NULL); |
|
505 |
+} |
|
506 |
+ |
|
507 |
+int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname) |
|
508 |
+{ |
|
504 | 509 |
char md5[33]; |
505 | 510 |
unsigned int i; |
506 | 511 |
const char *virname=NULL; |
... | ... |
@@ -525,11 +532,11 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
525 | 525 |
sprintf(md5 + i * 2, "%02x", digest[i]); |
526 | 526 |
md5[32] = 0; |
527 | 527 |
cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, |
528 |
- cli_get_last_virus(ctx) ? cli_get_last_virus(ctx) : "Name"); |
|
528 |
+ vname ? vname : "Name"); |
|
529 | 529 |
} |
530 | 530 |
|
531 |
- if(cli_get_last_virus(ctx)) |
|
532 |
- do_dsig_check = strncmp("W32S.", cli_get_last_virus(ctx), 5); |
|
531 |
+ if(vname) |
|
532 |
+ do_dsig_check = strncmp("W32S.", vname, 5); |
|
533 | 533 |
|
534 | 534 |
map = *ctx->fmap; |
535 | 535 |
have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size) |
... | ... |
@@ -586,7 +593,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
586 | 586 |
for(i=0; i<SHA1_HASH_SIZE; i++) |
587 | 587 |
sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]); |
588 | 588 |
|
589 |
- cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, cli_get_last_virus(ctx), ctx->entry_filename); |
|
589 |
+ cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, vname?vname:"noname", ctx->entry_filename); |
|
590 | 590 |
} else |
591 | 591 |
cli_errmsg("can't compute sha\n!"); |
592 | 592 |
|
... | ... |
@@ -614,10 +621,10 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
614 | 614 |
} |
615 | 615 |
|
616 | 616 |
if (ctx->engine->cb_hash) |
617 |
- ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, cli_get_last_virus(ctx), ctx->cb_ctx); |
|
617 |
+ ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, vname?vname:"noname", ctx->cb_ctx); |
|
618 | 618 |
|
619 | 619 |
if (ctx->engine->cb_stats_add_sample) |
620 |
- ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, §ions, ctx->engine->stats_data); |
|
620 |
+ ctx->engine->cb_stats_add_sample(vname?vname:"noname", digest, size, §ions, ctx->engine->stats_data); |
|
621 | 621 |
|
622 | 622 |
if (sections.sections) |
623 | 623 |
free(sections.sections); |
... | ... |
@@ -768,8 +775,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data |
768 | 768 |
return CL_CLEAN; |
769 | 769 |
if(matchicon(ctx, &target_info->exeinfo, ac_lsig->tdb.icongrp1, ac_lsig->tdb.icongrp2) == CL_VIRUS) { |
770 | 770 |
if(!ac_lsig->bc_idx) { |
771 |
- cli_append_virus(ctx, ac_lsig->virname); |
|
772 |
- return CL_VIRUS; |
|
771 |
+ rc = cli_append_virus(ctx, ac_lsig->virname); |
|
772 |
+ if (rc != CL_CLEAN) |
|
773 |
+ return rc; |
|
773 | 774 |
} else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { |
774 | 775 |
return CL_VIRUS; |
775 | 776 |
} |
... | ... |
@@ -777,8 +785,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data |
777 | 777 |
return CL_CLEAN; |
778 | 778 |
} |
779 | 779 |
if(!ac_lsig->bc_idx) { |
780 |
- cli_append_virus(ctx, ac_lsig->virname); |
|
781 |
- return CL_VIRUS; |
|
780 |
+ rc = cli_append_virus(ctx, ac_lsig->virname); |
|
781 |
+ if (rc != CL_CLEAN) |
|
782 |
+ return rc; |
|
782 | 783 |
} |
783 | 784 |
if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { |
784 | 785 |
return CL_VIRUS; |
... | ... |
@@ -808,7 +817,7 @@ static int yara_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data |
808 | 808 |
if (ac_lsig->flag & CLI_LSIG_FLAG_PRIVATE) { |
809 | 809 |
rc = CL_CLEAN; |
810 | 810 |
} else { |
811 |
- cli_append_virus(ctx, ac_lsig->virname); |
|
811 |
+ rc = cli_append_virus(ctx, ac_lsig->virname); |
|
812 | 812 |
} |
813 | 813 |
} |
814 | 814 |
return rc; |
... | ... |
@@ -1172,19 +1181,18 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
1172 | 1172 |
/* If matched size-based hash ... */ |
1173 | 1173 |
if (found % 2) { |
1174 | 1174 |
viruses_found = 1; |
1175 |
- cli_append_virus(ctx, virname); |
|
1176 |
- if (!SCAN_ALL) |
|
1175 |
+ ret = cli_append_virus(ctx, virname); |
|
1176 |
+ if (!SCAN_ALL || ret != CL_CLEAN) |
|
1177 | 1177 |
break; |
1178 | 1178 |
virname = NULL; |
1179 | 1179 |
} |
1180 | 1180 |
/* If matched size-agnostic hash ... */ |
1181 | 1181 |
if (found > 1) { |
1182 | 1182 |
viruses_found = 1; |
1183 |
- cli_append_virus(ctx, virname_w); |
|
1184 |
- |
|
1185 |
- if (!SCAN_ALL) |
|
1183 |
+ ret = cli_append_virus(ctx, virname_w); |
|
1184 |
+ if (!SCAN_ALL || ret != CL_CLEAN) |
|
1186 | 1185 |
break; |
1187 |
- } |
|
1186 |
+ } |
|
1188 | 1187 |
} |
1189 | 1188 |
} |
1190 | 1189 |
|
... | ... |
@@ -1228,6 +1236,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1228 | 1228 |
{ |
1229 | 1229 |
const struct cli_cdb *cdb; |
1230 | 1230 |
unsigned int viruses_found = 0; |
1231 |
+ int ret = CL_CLEAN; |
|
1231 | 1232 |
|
1232 | 1233 |
cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n", |
1233 | 1234 |
cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, |
... | ... |
@@ -1237,10 +1246,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1237 | 1237 |
if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { |
1238 | 1238 |
cli_dbgmsg("inner file blacklisted by callback: %s\n", fname); |
1239 | 1239 |
|
1240 |
- cli_append_virus(ctx, "Detected.By.Callback"); |
|
1240 |
+ ret = cli_append_virus(ctx, "Detected.By.Callback"); |
|
1241 | 1241 |
viruses_found++; |
1242 |
- if(!SCAN_ALL) |
|
1243 |
- return CL_VIRUS; |
|
1242 |
+ if(!SCAN_ALL || ret != CL_CLEAN) |
|
1243 |
+ return ret; |
|
1244 | 1244 |
} |
1245 | 1245 |
|
1246 | 1246 |
if(!ctx->engine || !(cdb = ctx->engine->cdb)) |
... | ... |
@@ -1273,10 +1282,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1273 | 1273 |
if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH)) |
1274 | 1274 |
continue; |
1275 | 1275 |
|
1276 |
- cli_append_virus(ctx, cdb->virname); |
|
1276 |
+ ret = cli_append_virus(ctx, cdb->virname); |
|
1277 | 1277 |
viruses_found++; |
1278 |
- if(!SCAN_ALL) |
|
1279 |
- return CL_VIRUS; |
|
1278 |
+ if(!SCAN_ALL || ret != CL_CLEAN) |
|
1279 |
+ return ret; |
|
1280 | 1280 |
|
1281 | 1281 |
} while((cdb = cdb->next)); |
1282 | 1282 |
|
... | ... |
@@ -208,6 +208,7 @@ int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acd |
208 | 208 |
int cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max); |
209 | 209 |
|
210 | 210 |
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx); |
211 |
+int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname); |
|
211 | 212 |
|
212 | 213 |
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2); |
213 | 214 |
|
... | ... |
@@ -590,9 +590,8 @@ cli_parse_mbox(const char *dir, cli_ctx *ctx) |
590 | 590 |
|
591 | 591 |
if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted && |
592 | 592 |
(*ctx->virname == NULL || SCAN_ALL)) { |
593 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email"); |
|
593 |
+ retcode = cli_append_virus(ctx, "Heuristics.Phishing.Email"); |
|
594 | 594 |
ctx->found_possibly_unwanted = 0; |
595 |
- retcode = CL_VIRUS; |
|
596 | 595 |
} |
597 | 596 |
|
598 | 597 |
cli_dbgmsg("cli_mbox returning %d\n", retcode); |
... | ... |
@@ -502,23 +502,17 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size |
502 | 502 |
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, mbr.entries[i].firstLBA, |
503 | 503 |
mbr.entries[i].numLBA); |
504 | 504 |
if (tmp != CL_CLEAN) { |
505 |
- if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { |
|
505 |
+ if (tmp == CL_VIRUS) { |
|
506 | 506 |
cli_dbgmsg("cli_scanmbr: detected intersection with partitions " |
507 | 507 |
"[%u, %u]\n", pitxn, i); |
508 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
508 |
+ ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
509 |
+ if (SCAN_ALL || ret == CL_CLEAN) |
|
510 |
+ tmp = 0; |
|
511 |
+ else |
|
512 |
+ goto leave; |
|
513 |
+ } else { |
|
509 | 514 |
ret = tmp; |
510 |
- tmp = 0; |
|
511 |
- } |
|
512 |
- else if (tmp == CL_VIRUS) { |
|
513 |
- cli_dbgmsg("cli_scanmbr: detected intersection with partitions " |
|
514 |
- "[%u, %u]\n", pitxn, i); |
|
515 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
516 |
- prtn_intxn_list_free(&prtncheck); |
|
517 |
- return CL_VIRUS; |
|
518 |
- } |
|
519 |
- else { |
|
520 |
- prtn_intxn_list_free(&prtncheck); |
|
521 |
- return tmp; |
|
515 |
+ goto leave; |
|
522 | 516 |
} |
523 | 517 |
} |
524 | 518 |
|
... | ... |
@@ -547,6 +541,7 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size |
547 | 547 |
} |
548 | 548 |
} |
549 | 549 |
|
550 |
+leave: |
|
550 | 551 |
prtn_intxn_list_free(&prtncheck); |
551 | 552 |
return ret; |
552 | 553 |
} |
... | ... |
@@ -559,6 +554,7 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl |
559 | 559 |
unsigned i, pitxn; |
560 | 560 |
int ret = CL_CLEAN, tmp = CL_CLEAN, mbr_base = 0; |
561 | 561 |
off_t pos = 0, logiclba = 0; |
562 |
+ int virus_found = 0; |
|
562 | 563 |
|
563 | 564 |
mbr_base = sectorsize - sizeof(struct mbr_boot_record); |
564 | 565 |
|
... | ... |
@@ -585,23 +581,19 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl |
585 | 585 |
/* assume that logical record is first and extended is second */ |
586 | 586 |
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, logiclba, ebr.entries[0].numLBA); |
587 | 587 |
if (tmp != CL_CLEAN) { |
588 |
- if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { |
|
588 |
+ if (tmp == CL_VIRUS) { |
|
589 | 589 |
cli_dbgmsg("cli_scanebr: detected intersection with partitions " |
590 | 590 |
"[%u, %u]\n", pitxn, i); |
591 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
591 |
+ ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
592 |
+ if (ret == CL_VIRUS) |
|
593 |
+ virus_found = 1; |
|
594 |
+ if (SCAN_ALL || ret == CL_CLEAN) |
|
595 |
+ tmp = 0; |
|
596 |
+ else |
|
597 |
+ goto leave; |
|
598 |
+ } else { |
|
592 | 599 |
ret = tmp; |
593 |
- tmp = 0; |
|
594 |
- } |
|
595 |
- else if (tmp == CL_VIRUS) { |
|
596 |
- cli_dbgmsg("cli_scanebr: detected intersection with partitions " |
|
597 |
- "[%u, %u]\n", pitxn, i); |
|
598 |
- cli_append_virus(ctx, PRTN_INTXN_DETECTION); |
|
599 |
- prtn_intxn_list_free(&prtncheck); |
|
600 |
- return CL_VIRUS; |
|
601 |
- } |
|
602 |
- else { |
|
603 |
- prtn_intxn_list_free(&prtncheck); |
|
604 |
- return tmp; |
|
600 |
+ goto leave; |
|
605 | 601 |
} |
606 | 602 |
} |
607 | 603 |
|
... | ... |
@@ -616,6 +608,9 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl |
616 | 616 |
++i; |
617 | 617 |
} while (logiclba != 0 && (*prtncount) < ctx->engine->maxpartitions); |
618 | 618 |
|
619 |
- prtn_intxn_list_free(&prtncheck); |
|
619 |
+ leave: |
|
620 |
+ prtn_intxn_list_free(&prtncheck); |
|
621 |
+ if (virus_found) |
|
622 |
+ return CL_VIRUS; |
|
620 | 623 |
return ret; |
621 | 624 |
} |
... | ... |
@@ -1088,15 +1088,39 @@ int cli_unlink(const char *pathname) |
1088 | 1088 |
return 0; |
1089 | 1089 |
} |
1090 | 1090 |
|
1091 |
-void cli_append_virus(cli_ctx * ctx, const char * virname) |
|
1091 |
+void cli_virus_found_cb(cli_ctx * ctx) |
|
1092 |
+{ |
|
1093 |
+ if (ctx->engine->cb_virus_found) |
|
1094 |
+ ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), (const char *)*ctx->virname, ctx->cb_ctx); |
|
1095 |
+} |
|
1096 |
+ |
|
1097 |
+int cli_append_possibly_unwanted(cli_ctx * ctx, const char * virname) |
|
1098 |
+{ |
|
1099 |
+ if (SCAN_ALL) |
|
1100 |
+ return cli_append_virus(ctx, virname); |
|
1101 |
+ else if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) |
|
1102 |
+ return cli_append_virus(ctx, virname); |
|
1103 |
+ else if (ctx->num_viruses == 0 && ctx->virname != NULL && *ctx->virname == NULL) { |
|
1104 |
+ ctx->found_possibly_unwanted = 1; |
|
1105 |
+ ctx->num_viruses++; |
|
1106 |
+ *ctx->virname = virname; |
|
1107 |
+ } |
|
1108 |
+ return CL_CLEAN; |
|
1109 |
+} |
|
1110 |
+ |
|
1111 |
+int cli_append_virus(cli_ctx * ctx, const char * virname) |
|
1092 | 1112 |
{ |
1093 | 1113 |
if (ctx->virname == NULL) |
1094 |
- return; |
|
1114 |
+ return CL_CLEAN; |
|
1115 |
+ if (ctx->fmap != NULL && (*ctx->fmap) != NULL && CL_VIRUS != cli_checkfp_virus((*ctx->fmap)->maphash, (*ctx->fmap)->len, ctx, virname)) |
|
1116 |
+ return CL_CLEAN; |
|
1117 |
+ if (!SCAN_ALL && ctx->num_viruses != 0) |
|
1118 |
+ if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) |
|
1119 |
+ return CL_CLEAN; |
|
1095 | 1120 |
if (ctx->limit_exceeded == 0 || SCAN_ALL) { |
1096 |
- if (ctx->engine->cb_virus_found) |
|
1097 |
- ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), virname, ctx->cb_ctx); |
|
1098 | 1121 |
ctx->num_viruses++; |
1099 | 1122 |
*ctx->virname = virname; |
1123 |
+ cli_virus_found_cb(ctx); |
|
1100 | 1124 |
} |
1101 | 1125 |
#if HAVE_JSON |
1102 | 1126 |
if (SCAN_PROPERTIES && ctx->wrkproperty) { |
... | ... |
@@ -1105,17 +1129,18 @@ void cli_append_virus(cli_ctx * ctx, const char * virname) |
1105 | 1105 |
arrobj = json_object_new_array(); |
1106 | 1106 |
if (NULL == arrobj) { |
1107 | 1107 |
cli_errmsg("cli_append_virus: no memory for json virus array\n"); |
1108 |
- return; |
|
1108 |
+ return CL_EMEM; |
|
1109 | 1109 |
} |
1110 | 1110 |
json_object_object_add(ctx->wrkproperty, "Viruses", arrobj); |
1111 | 1111 |
} |
1112 | 1112 |
virobj = json_object_new_string(virname); |
1113 | 1113 |
if (NULL == virobj) { |
1114 | 1114 |
cli_errmsg("cli_append_virus: no memory for json virus name object\n"); |
1115 |
- return; |
|
1115 |
+ return CL_EMEM; |
|
1116 | 1116 |
} |
1117 | 1117 |
json_object_array_add(arrobj, virobj); |
1118 | 1118 |
} |
1119 |
+ return CL_VIRUS; |
|
1119 | 1120 |
#endif |
1120 | 1121 |
} |
1121 | 1122 |
|
... | ... |
@@ -601,9 +601,10 @@ static inline void cli_writeint32(void *offset, uint32_t value) |
601 | 601 |
} |
602 | 602 |
#endif |
603 | 603 |
|
604 |
-void cli_append_virus(cli_ctx *ctx, const char *virname); |
|
604 |
+int cli_append_virus(cli_ctx *ctx, const char *virname); |
|
605 | 605 |
const char *cli_get_last_virus(const cli_ctx *ctx); |
606 | 606 |
const char *cli_get_last_virus_str(const cli_ctx *ctx); |
607 |
+void cli_virus_found_cb(cli_ctx *ctx); |
|
607 | 608 |
|
608 | 609 |
void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size); |
609 | 610 |
cli_file_t cli_get_container_type(cli_ctx *ctx, int index); |
... | ... |
@@ -2458,10 +2458,10 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset) |
2458 | 2458 |
|
2459 | 2459 |
pdf_parseobj(&pdf, obj); |
2460 | 2460 |
if (SCAN_ALGO && obj->numfilters > PDF_FILTER_DTRIGGER) { |
2461 |
- cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters"); |
|
2461 |
+ rc = cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters"); |
|
2462 | 2462 |
alerts++; |
2463 |
- if (!SCAN_ALL) |
|
2464 |
- rc = CL_VIRUS; |
|
2463 |
+ if (SCAN_ALL && rc == CL_VIRUS) |
|
2464 |
+ rc = CL_CLEAN; |
|
2465 | 2465 |
} |
2466 | 2466 |
} |
2467 | 2467 |
|
... | ... |
@@ -2479,8 +2479,8 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset) |
2479 | 2479 |
* a password to decrypt */ |
2480 | 2480 |
cli_append_virus(ctx, "Heuristics.Encrypted.PDF"); |
2481 | 2481 |
alerts++; |
2482 |
- if (!SCAN_ALL) |
|
2483 |
- rc = CL_VIRUS; |
|
2482 |
+ if (SCAN_ALL && rc == CL_VIRUS) |
|
2483 |
+ rc = CL_CLEAN; |
|
2484 | 2484 |
} |
2485 | 2485 |
|
2486 | 2486 |
if (!rc) { |
... | ... |
@@ -2547,8 +2547,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset) |
2547 | 2547 |
if (!rc && SCAN_ALGO && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) { |
2548 | 2548 |
if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) { |
2549 | 2549 |
/* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */ |
2550 |
- cli_append_virus(ctx, "Heuristics.PDF.ObfuscatedNameObject"); |
|
2551 |
- rc = cli_found_possibly_unwanted(ctx); |
|
2550 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.PDF.ObfuscatedNameObject"); |
|
2552 | 2551 |
} |
2553 | 2552 |
} |
2554 | 2553 |
#if 0 |
... | ... |
@@ -555,7 +555,7 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section) |
555 | 555 |
if (cli_debug_flag) { |
556 | 556 |
md5 = hashset[CLI_HASH_MD5]; |
557 | 557 |
if (md5) { |
558 |
- cli_dbgmsg("MDB: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
|
558 |
+ cli_dbgmsg("MDB hashset: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
|
559 | 559 |
exe_section->rsz, md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], |
560 | 560 |
md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]); |
561 | 561 |
} else if (cli_always_gen_section_hash) { |
... | ... |
@@ -589,17 +589,21 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section) |
589 | 589 |
/* Do scans */ |
590 | 590 |
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { |
591 | 591 |
if(foundsize[type] && cli_hm_scan(hashset[type], exe_section->rsz, &virname, mdb_sect, type) == CL_VIRUS) { |
592 |
- cli_append_virus(ctx, virname); |
|
593 |
- ret = CL_VIRUS; |
|
594 |
- if (!SCAN_ALL) { |
|
595 |
- break; |
|
592 |
+ ret = cli_append_virus(ctx, virname); |
|
593 |
+ if (ret != CL_CLEAN) { |
|
594 |
+ if (ret != CL_VIRUS) |
|
595 |
+ break; |
|
596 |
+ else if (!SCAN_ALL) |
|
597 |
+ break; |
|
596 | 598 |
} |
597 | 599 |
} |
598 | 600 |
if(foundwild[type] && cli_hm_scan_wild(hashset[type], &virname, mdb_sect, type) == CL_VIRUS) { |
599 |
- cli_append_virus(ctx, virname); |
|
600 |
- ret = CL_VIRUS; |
|
601 |
- if (!SCAN_ALL) { |
|
602 |
- break; |
|
601 |
+ ret = cli_append_virus(ctx, virname); |
|
602 |
+ if (ret != CL_CLEAN) { |
|
603 |
+ if (ret != CL_VIRUS) |
|
604 |
+ break; |
|
605 |
+ else if (!SCAN_ALL) |
|
606 |
+ break; |
|
603 | 607 |
} |
604 | 608 |
} |
605 | 609 |
} |
... | ... |
@@ -2209,10 +2213,10 @@ static int validate_impname(const char *name, uint32_t length, int dll) |
2209 | 2209 |
|
2210 | 2210 |
static inline int hash_impfns(cli_ctx *ctx, void **hashctx, uint32_t *impsz, struct pe_image_import_descriptor *image, const char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first) |
2211 | 2211 |
{ |
2212 |
- uint32_t thuoff, offset; |
|
2212 |
+ uint32_t thuoff = 0, offset; |
|
2213 | 2213 |
fmap_t *map = *ctx->fmap; |
2214 | 2214 |
size_t dlllen = 0, fsize = map->len; |
2215 |
- int i, j, err, num_fns = 0, ret = CL_SUCCESS; |
|
2215 |
+ int i, j, err = 0, num_fns = 0, ret = CL_SUCCESS; |
|
2216 | 2216 |
const char *buffer; |
2217 | 2217 |
enum CLI_HASH_TYPE type; |
2218 | 2218 |
#if HAVE_JSON |
... | ... |
@@ -2557,17 +2561,23 @@ static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_ |
2557 | 2557 |
/* Do scans */ |
2558 | 2558 |
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { |
2559 | 2559 |
if(cli_hm_scan(hashset[type], impsz, &virname, imp, type) == CL_VIRUS) { |
2560 |
- cli_append_virus(ctx, virname); |
|
2561 |
- ret = CL_VIRUS; |
|
2562 |
- if(!SCAN_ALL) |
|
2563 |
- break; |
|
2560 |
+ ret = cli_append_virus(ctx, virname); |
|
2561 |
+ if (ret != CL_CLEAN) { |
|
2562 |
+ if (ret != CL_VIRUS) |
|
2563 |
+ break; |
|
2564 |
+ else if (!SCAN_ALL) |
|
2565 |
+ break; |
|
2566 |
+ } |
|
2564 | 2567 |
} |
2565 | 2568 |
if(cli_hm_scan_wild(hashset[type], &virname, imp, type) == CL_VIRUS) { |
2566 | 2569 |
cli_append_virus(ctx, virname); |
2567 |
- ret = CL_VIRUS; |
|
2568 |
- if(!SCAN_ALL) |
|
2569 |
- break; |
|
2570 |
- } |
|
2570 |
+ if (ret != CL_CLEAN) { |
|
2571 |
+ if (ret != CL_VIRUS) |
|
2572 |
+ break; |
|
2573 |
+ else if (!SCAN_ALL) |
|
2574 |
+ break; |
|
2575 |
+ } |
|
2576 |
+ } |
|
2571 | 2577 |
} |
2572 | 2578 |
|
2573 | 2579 |
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) |
... | ... |
@@ -2759,8 +2769,8 @@ int cli_scanpe(cli_ctx *ctx) |
2759 | 2759 |
cli_dbgmsg("Can't read new header address\n"); |
2760 | 2760 |
/* truncated header? */ |
2761 | 2761 |
if(DETECT_BROKEN_PE) { |
2762 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2763 |
- return CL_VIRUS; |
|
2762 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2763 |
+ return ret; |
|
2764 | 2764 |
} |
2765 | 2765 |
|
2766 | 2766 |
return CL_CLEAN; |
... | ... |
@@ -2775,7 +2785,7 @@ int cli_scanpe(cli_ctx *ctx) |
2775 | 2775 |
|
2776 | 2776 |
if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) { |
2777 | 2777 |
/* bad information in e_lfanew - probably not a PE file */ |
2778 |
- cli_dbgmsg("Can't read file header\n"); |
|
2778 |
+ cli_dbgmsg("cli_scanpe: Can't read file header\n"); |
|
2779 | 2779 |
return CL_CLEAN; |
2780 | 2780 |
} |
2781 | 2781 |
|
... | ... |
@@ -2908,8 +2918,8 @@ int cli_scanpe(cli_ctx *ctx) |
2908 | 2908 |
pe_add_heuristic_property(ctx, "BadNumberOfSections"); |
2909 | 2909 |
#endif |
2910 | 2910 |
if(DETECT_BROKEN_PE) { |
2911 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2912 |
- return CL_VIRUS; |
|
2911 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2912 |
+ return ret; |
|
2913 | 2913 |
} |
2914 | 2914 |
|
2915 | 2915 |
if(!ctx->corrupted_input) { |
... | ... |
@@ -2945,8 +2955,8 @@ int cli_scanpe(cli_ctx *ctx) |
2945 | 2945 |
#endif |
2946 | 2946 |
cli_dbgmsg("SizeOfOptionalHeader too small\n"); |
2947 | 2947 |
if(DETECT_BROKEN_PE) { |
2948 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2949 |
- return CL_VIRUS; |
|
2948 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2949 |
+ return ret; |
|
2950 | 2950 |
} |
2951 | 2951 |
|
2952 | 2952 |
return CL_CLEAN; |
... | ... |
@@ -2956,8 +2966,8 @@ int cli_scanpe(cli_ctx *ctx) |
2956 | 2956 |
if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) { |
2957 | 2957 |
cli_dbgmsg("Can't read optional file header\n"); |
2958 | 2958 |
if(DETECT_BROKEN_PE) { |
2959 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2960 |
- return CL_VIRUS; |
|
2959 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2960 |
+ return ret; |
|
2961 | 2961 |
} |
2962 | 2962 |
|
2963 | 2963 |
return CL_CLEAN; |
... | ... |
@@ -2974,8 +2984,8 @@ int cli_scanpe(cli_ctx *ctx) |
2974 | 2974 |
cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n"); |
2975 | 2975 |
|
2976 | 2976 |
if(DETECT_BROKEN_PE) { |
2977 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2978 |
- return CL_VIRUS; |
|
2977 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
2978 |
+ return ret; |
|
2979 | 2979 |
} |
2980 | 2980 |
|
2981 | 2981 |
return CL_CLEAN; |
... | ... |
@@ -3044,8 +3054,8 @@ int cli_scanpe(cli_ctx *ctx) |
3044 | 3044 |
if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) { |
3045 | 3045 |
cli_dbgmsg("Can't read optional file header\n"); |
3046 | 3046 |
if(DETECT_BROKEN_PE) { |
3047 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3048 |
- return CL_VIRUS; |
|
3047 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3048 |
+ return ret; |
|
3049 | 3049 |
} |
3050 | 3050 |
|
3051 | 3051 |
return CL_CLEAN; |
... | ... |
@@ -3168,14 +3178,14 @@ int cli_scanpe(cli_ctx *ctx) |
3168 | 3168 |
|
3169 | 3169 |
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) { |
3170 | 3170 |
cli_dbgmsg("Bad virtual alignment\n"); |
3171 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3172 |
- return CL_VIRUS; |
|
3171 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3172 |
+ return ret; |
|
3173 | 3173 |
} |
3174 | 3174 |
|
3175 | 3175 |
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) { |
3176 | 3176 |
cli_dbgmsg("Bad file alignment\n"); |
3177 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3178 |
- return CL_VIRUS; |
|
3177 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3178 |
+ return ret; |
|
3179 | 3179 |
} |
3180 | 3180 |
|
3181 | 3181 |
fsize = map->len; |
... | ... |
@@ -3206,8 +3216,8 @@ int cli_scanpe(cli_ctx *ctx) |
3206 | 3206 |
free(exe_sections); |
3207 | 3207 |
|
3208 | 3208 |
if(DETECT_BROKEN_PE) { |
3209 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3210 |
- return CL_VIRUS; |
|
3209 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3210 |
+ return ret; |
|
3211 | 3211 |
} |
3212 | 3212 |
|
3213 | 3213 |
return CL_CLEAN; |
... | ... |
@@ -3251,8 +3261,8 @@ int cli_scanpe(cli_ctx *ctx) |
3251 | 3251 |
free(exe_sections); |
3252 | 3252 |
|
3253 | 3253 |
if(DETECT_BROKEN_PE) { |
3254 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3255 |
- return CL_VIRUS; |
|
3254 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3255 |
+ return ret; |
|
3256 | 3256 |
} |
3257 | 3257 |
|
3258 | 3258 |
return CL_CLEAN; /* no ninjas to see here! move along! */ |
... | ... |
@@ -3324,10 +3334,10 @@ int cli_scanpe(cli_ctx *ctx) |
3324 | 3324 |
if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */ |
3325 | 3325 |
cli_dbgmsg("VirtualAddress is misaligned\n"); |
3326 | 3326 |
cli_dbgmsg("------------------------------------\n"); |
3327 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3327 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3328 | 3328 |
free(section_hdr); |
3329 | 3329 |
free(exe_sections); |
3330 |
- return CL_VIRUS; |
|
3330 |
+ return ret; |
|
3331 | 3331 |
} |
3332 | 3332 |
|
3333 | 3333 |
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */ |
... | ... |
@@ -3355,8 +3365,8 @@ int cli_scanpe(cli_ctx *ctx) |
3355 | 3355 |
free(section_hdr); |
3356 | 3356 |
free(exe_sections); |
3357 | 3357 |
if(DETECT_BROKEN_PE) { |
3358 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3359 |
- return CL_VIRUS; |
|
3358 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3359 |
+ return ret; |
|
3360 | 3360 |
} |
3361 | 3361 |
|
3362 | 3362 |
return CL_CLEAN; |
... | ... |
@@ -3365,10 +3375,10 @@ int cli_scanpe(cli_ctx *ctx) |
3365 | 3365 |
if(!i) { |
3366 | 3366 |
if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */ |
3367 | 3367 |
cli_dbgmsg("First section is in the wrong place\n"); |
3368 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3368 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3369 | 3369 |
free(section_hdr); |
3370 | 3370 |
free(exe_sections); |
3371 |
- return CL_VIRUS; |
|
3371 |
+ return ret; |
|
3372 | 3372 |
} |
3373 | 3373 |
|
3374 | 3374 |
min = exe_sections[i].rva; |
... | ... |
@@ -3376,10 +3386,10 @@ int cli_scanpe(cli_ctx *ctx) |
3376 | 3376 |
} else { |
3377 | 3377 |
if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */ |
3378 | 3378 |
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n"); |
3379 |
- cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3379 |
+ ret = cli_append_virus(ctx, "Heuristics.Broken.Executable"); |
|
3380 | 3380 |
free(section_hdr); |
3381 | 3381 |
free(exe_sections); |
3382 |
- return CL_VIRUS; |
|
3382 |
+ return ret; |
|
3383 | 3383 |
} |
3384 | 3384 |
|
3385 | 3385 |
if(exe_sections[i].rva < min) |
... | ... |
@@ -3398,8 +3408,8 @@ int cli_scanpe(cli_ctx *ctx) |
3398 | 3398 |
cli_dbgmsg("EntryPoint out of file\n"); |
3399 | 3399 |
free(exe_sections); |
3400 | 3400 |
if(DETECT_BROKEN_PE) { |
3401 |
- cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3402 |
- return CL_VIRUS; |
|
3401 |
+ ret = cli_append_virus(ctx,"Heuristics.Broken.Executable"); |
|
3402 |
+ return ret; |
|
3403 | 3403 |
} |
3404 | 3404 |
|
3405 | 3405 |
return CL_CLEAN; |
... | ... |
@@ -3517,13 +3527,20 @@ int cli_scanpe(cli_ctx *ctx) |
3517 | 3517 |
if(pt) { |
3518 | 3518 |
pt += 15; |
3519 | 3519 |
if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) { |
3520 |
- cli_append_virus(ctx,"Heuristics.W32.Parite.B"); |
|
3521 |
- if (!SCAN_ALL) { |
|
3522 |
- free(exe_sections); |
|
3523 |
- return CL_VIRUS; |
|
3520 |
+ ret = cli_append_virus(ctx,"Heuristics.W32.Parite.B"); |
|
3521 |
+ if (ret != CL_CLEAN) { |
|
3522 |
+ if (ret == CL_VIRUS) { |
|
3523 |
+ if (!SCAN_ALL) { |
|
3524 |
+ free(exe_sections); |
|
3525 |
+ return ret; |
|
3526 |
+ } |
|
3527 |
+ else |
|
3528 |
+ viruses_found++; |
|
3529 |
+ } else { |
|
3530 |
+ free(exe_sections); |
|
3531 |
+ return ret; |
|
3532 |
+ } |
|
3524 | 3533 |
} |
3525 |
- |
|
3526 |
- viruses_found++; |
|
3527 | 3534 |
} |
3528 | 3535 |
} |
3529 | 3536 |
} |
... | ... |
@@ -3635,15 +3652,21 @@ int cli_scanpe(cli_ctx *ctx) |
3635 | 3635 |
break; |
3636 | 3636 |
case KZSLOOP: |
3637 | 3637 |
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) { |
3638 |
- cli_append_virus(ctx,"Heuristics.W32.Kriz"); |
|
3639 |
- if (!SCAN_ALL) { |
|
3640 |
- free(exe_sections); |
|
3641 |
- return CL_VIRUS; |
|
3638 |
+ ret = cli_append_virus(ctx,"Heuristics.W32.Kriz"); |
|
3639 |
+ if (ret != CL_CLEAN) { |
|
3640 |
+ if (ret == CL_VIRUS) { |
|
3641 |
+ if (!SCAN_ALL) { |
|
3642 |
+ free(exe_sections); |
|
3643 |
+ return ret; |
|
3644 |
+ } |
|
3645 |
+ else |
|
3646 |
+ viruses_found++; |
|
3647 |
+ } else { |
|
3648 |
+ free(exe_sections); |
|
3649 |
+ return ret; |
|
3650 |
+ } |
|
3642 | 3651 |
} |
3643 |
- |
|
3644 |
- viruses_found++; |
|
3645 | 3652 |
} |
3646 |
- |
|
3647 | 3653 |
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n"); |
3648 | 3654 |
kzstate++; |
3649 | 3655 |
} |
... | ... |
@@ -3667,13 +3690,20 @@ int cli_scanpe(cli_ctx *ctx) |
3667 | 3667 |
|
3668 | 3668 |
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) { |
3669 | 3669 |
if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) { |
3670 |
- cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A"); |
|
3671 |
- if (!SCAN_ALL) { |
|
3672 |
- free(exe_sections); |
|
3673 |
- return CL_VIRUS; |
|
3670 |
+ ret = cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A"); |
|
3671 |
+ if (ret != CL_CLEAN) { |
|
3672 |
+ if (ret == CL_VIRUS) { |
|
3673 |
+ if (!SCAN_ALL) { |
|
3674 |
+ free(exe_sections); |
|
3675 |
+ return ret; |
|
3676 |
+ } |
|
3677 |
+ else |
|
3678 |
+ viruses_found++; |
|
3679 |
+ } else { |
|
3680 |
+ free(exe_sections); |
|
3681 |
+ return ret; |
|
3682 |
+ } |
|
3674 | 3683 |
} |
3675 |
- |
|
3676 |
- viruses_found++; |
|
3677 | 3684 |
} |
3678 | 3685 |
} |
3679 | 3686 |
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) { |
... | ... |
@@ -3682,13 +3712,20 @@ int cli_scanpe(cli_ctx *ctx) |
3682 | 3682 |
|
3683 | 3683 |
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) { |
3684 | 3684 |
if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) { |
3685 |
- cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B"); |
|
3686 |
- if (!SCAN_ALL) { |
|
3687 |
- free(exe_sections); |
|
3688 |
- return CL_VIRUS; |
|
3685 |
+ ret = cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B"); |
|
3686 |
+ if (ret != CL_CLEAN) { |
|
3687 |
+ if (ret == CL_VIRUS) { |
|
3688 |
+ if (!SCAN_ALL) { |
|
3689 |
+ free(exe_sections); |
|
3690 |
+ return ret; |
|
3691 |
+ } |
|
3692 |
+ else |
|
3693 |
+ viruses_found++; |
|
3694 |
+ } else { |
|
3695 |
+ free(exe_sections); |
|
3696 |
+ return ret; |
|
3697 |
+ } |
|
3689 | 3698 |
} |
3690 |
- |
|
3691 |
- viruses_found++; |
|
3692 | 3699 |
} |
3693 | 3700 |
} |
3694 | 3701 |
} |
... | ... |
@@ -3752,14 +3789,22 @@ int cli_scanpe(cli_ctx *ctx) |
3752 | 3752 |
continue; |
3753 | 3753 |
|
3754 | 3754 |
if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) { |
3755 |
- cli_append_virus(ctx,"Heuristics.W32.Polipos.A"); |
|
3756 |
- if (!SCAN_ALL) { |
|
3757 |
- free(jumps); |
|
3758 |
- free(exe_sections); |
|
3759 |
- return CL_VIRUS; |
|
3755 |
+ ret = cli_append_virus(ctx,"Heuristics.W32.Polipos.A"); |
|
3756 |
+ if (ret != CL_CLEAN) { |
|
3757 |
+ if (ret == CL_VIRUS) { |
|
3758 |
+ if (!SCAN_ALL) { |
|
3759 |
+ free(jumps); |
|
3760 |
+ free(exe_sections); |
|
3761 |
+ return ret; |
|
3762 |
+ } |
|
3763 |
+ else |
|
3764 |
+ viruses_found++; |
|
3765 |
+ } else { |
|
3766 |
+ free(jumps); |
|
3767 |
+ free(exe_sections); |
|
3768 |
+ return ret; |
|
3769 |
+ } |
|
3760 | 3770 |
} |
3761 |
- |
|
3762 |
- viruses_found++; |
|
3763 | 3771 |
} |
3764 | 3772 |
} |
3765 | 3773 |
|
... | ... |
@@ -3775,21 +3820,28 @@ int cli_scanpe(cli_ctx *ctx) |
3775 | 3775 |
ret = CL_CLEAN; |
3776 | 3776 |
|
3777 | 3777 |
if (!stats) { |
3778 |
- ret = CL_EMEM; |
|
3778 |
+ free(exe_sections); |
|
3779 |
+ return CL_EMEM; |
|
3779 | 3780 |
} else { |
3780 | 3781 |
cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats); |
3781 |
- if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) |
|
3782 |
- cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen"); |
|
3783 |
- |
|
3784 |
- free(stats); |
|
3785 |
- } |
|
3786 |
- if (ret != CL_CLEAN) { |
|
3787 |
- if (!(ret == CL_VIRUS && SCAN_ALL)) { |
|
3788 |
- free(exe_sections); |
|
3789 |
- return ret; |
|
3782 |
+ if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) { |
|
3783 |
+ ret = cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen"); |
|
3784 |
+ if (ret != CL_CLEAN) { |
|
3785 |
+ if (ret == CL_VIRUS) { |
|
3786 |
+ if (!SCAN_ALL) { |
|
3787 |
+ free(stats); |
|
3788 |
+ free(exe_sections); |
|
3789 |
+ return ret; |
|
3790 |
+ } |
|
3791 |
+ else |
|
3792 |
+ viruses_found++; |
|
3793 |
+ } else { |
|
3794 |
+ free(stats); |
|
3795 |
+ free(exe_sections); |
|
3796 |
+ return ret; |
|
3797 |
+ } |
|
3798 |
+ } |
|
3790 | 3799 |
} |
3791 |
- |
|
3792 |
- viruses_found++; |
|
3793 | 3800 |
} |
3794 | 3801 |
} |
3795 | 3802 |
} |
... | ... |
@@ -4982,7 +5034,7 @@ int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo) |
4982 | 4982 |
|
4983 | 4983 |
if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) { |
4984 | 4984 |
/* bad information in e_lfanew - probably not a PE file */ |
4985 |
- cli_dbgmsg("Can't read file header\n"); |
|
4985 |
+ cli_dbgmsg("cli_peheader: Can't read file header\n"); |
|
4986 | 4986 |
return -1; |
4987 | 4987 |
} |
4988 | 4988 |
|
... | ... |
@@ -814,32 +814,31 @@ int phishingScan(cli_ctx* ctx,tag_arguments_t* hrefs) |
814 | 814 |
case CL_PHISH_CLEAN: |
815 | 815 |
continue; |
816 | 816 |
case CL_PHISH_NUMERIC_IP: |
817 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP"); |
|
817 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP"); |
|
818 | 818 |
break; |
819 | 819 |
case CL_PHISH_CLOAKED_NULL: |
820 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/ |
|
820 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/ |
|
821 | 821 |
break; |
822 | 822 |
case CL_PHISH_SSL_SPOOF: |
823 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email.SSL-Spoof"); |
|
823 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SSL-Spoof"); |
|
824 | 824 |
break; |
825 | 825 |
case CL_PHISH_CLOAKED_UIU: |
826 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/ |
|
826 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/ |
|
827 | 827 |
break; |
828 | 828 |
case CL_PHISH_HASH0: |
829 |
- cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net"); |
|
829 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net"); |
|
830 | 830 |
break; |
831 | 831 |
case CL_PHISH_HASH1: |
832 |
- cli_append_virus(ctx, "Heuristics.Phishing.URL.Blacklisted"); |
|
832 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.URL.Blacklisted"); |
|
833 | 833 |
break; |
834 | 834 |
case CL_PHISH_HASH2: |
835 |
- cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net"); |
|
835 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net"); |
|
836 | 836 |
break; |
837 | 837 |
case CL_PHISH_NOMATCH: |
838 | 838 |
default: |
839 |
- cli_append_virus(ctx, "Heuristics.Phishing.Email.SpoofedDomain"); |
|
839 |
+ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SpoofedDomain"); |
|
840 | 840 |
break; |
841 | 841 |
} |
842 |
- return cli_found_possibly_unwanted(ctx); |
|
843 | 842 |
} |
844 | 843 |
return CL_CLEAN; |
845 | 844 |
} |
... | ... |
@@ -227,9 +227,9 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx |
227 | 227 |
cli_dbgmsg("RAR: Encrypted files found in archive.\n"); |
228 | 228 |
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
229 | 229 |
if(ret != CL_VIRUS) { |
230 |
- cli_append_virus(ctx, "Heuristics.Encrypted.RAR"); |
|
231 |
- return CL_VIRUS; |
|
232 |
- } |
|
230 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
231 |
+ return CL_VIRUS; |
|
232 |
+ } |
|
233 | 233 |
} |
234 | 234 |
|
235 | 235 |
if (virus_found != 0) |
... | ... |
@@ -269,13 +269,13 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
269 | 269 |
cli_dbgmsg("RAR: Encrypted main header\n"); |
270 | 270 |
if(DETECT_ENCRYPTED) { |
271 | 271 |
if (lseek(desc, 0, SEEK_SET) == -1) { |
272 |
- cli_dbgmsg("RAR: call to lseek() failed\n"); |
|
273 |
- return CL_ESEEK; |
|
274 |
- } |
|
272 |
+ cli_dbgmsg("RAR: call to lseek() failed\n"); |
|
273 |
+ return CL_ESEEK; |
|
274 |
+ } |
|
275 | 275 |
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); |
276 | 276 |
if(ret != CL_VIRUS) |
277 |
- cli_append_virus(ctx, "Heuristics.Encrypted.RAR"); |
|
278 |
- return CL_VIRUS; |
|
277 |
+ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR")) |
|
278 |
+ return CL_VIRUS; |
|
279 | 279 |
} |
280 | 280 |
return CL_CLEAN; |
281 | 281 |
} if(ret == UNRAR_EMEM) { |
... | ... |
@@ -1179,9 +1179,9 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
1179 | 1179 |
cli_jsonbool(ctx->wrkproperty, "HasMacros", 1); |
1180 | 1180 |
#endif |
1181 | 1181 |
if(BLOCK_MACROS && hasmacros) { |
1182 |
- cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros"); |
|
1183 |
- ret = CL_VIRUS; |
|
1184 |
- viruses_found++; |
|
1182 |
+ ret = cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros"); |
|
1183 |
+ if (ret == CL_VIRUS) |
|
1184 |
+ viruses_found++; |
|
1185 | 1185 |
} |
1186 | 1186 |
if (SCAN_ALL && viruses_found) |
1187 | 1187 |
return CL_VIRUS; |
... | ... |
@@ -1609,24 +1609,20 @@ static int cli_scanscrenc(cli_ctx *ctx) |
1609 | 1609 |
|
1610 | 1610 |
static int cli_scanriff(cli_ctx *ctx) |
1611 | 1611 |
{ |
1612 |
- int ret = CL_CLEAN; |
|
1612 |
+ int ret = CL_CLEAN; |
|
1613 | 1613 |
|
1614 |
- if(cli_check_riff_exploit(ctx) == 2) { |
|
1615 |
- ret = CL_VIRUS; |
|
1616 |
- cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002"); |
|
1617 |
- } |
|
1614 |
+ if (cli_check_riff_exploit(ctx) == 2) |
|
1615 |
+ ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002"); |
|
1618 | 1616 |
|
1619 | 1617 |
return ret; |
1620 | 1618 |
} |
1621 | 1619 |
|
1622 | 1620 |
static int cli_scanjpeg(cli_ctx *ctx) |
1623 | 1621 |
{ |
1624 |
- int ret = CL_CLEAN; |
|
1622 |
+ int ret = CL_CLEAN; |
|
1625 | 1623 |
|
1626 |
- if(cli_check_jpeg_exploit(ctx, 0) == 1) { |
|
1627 |
- ret = CL_VIRUS; |
|
1628 |
- cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028"); |
|
1629 |
- } |
|
1624 |
+ if(cli_check_jpeg_exploit(ctx, 0) == 1) |
|
1625 |
+ ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028"); |
|
1630 | 1626 |
|
1631 | 1627 |
return ret; |
1632 | 1628 |
} |
... | ... |
@@ -1872,20 +1868,20 @@ static int cli_scan_structured(cli_ctx *ctx) |
1872 | 1872 |
|
1873 | 1873 |
if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) { |
1874 | 1874 |
cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count); |
1875 |
- cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber"); |
|
1876 |
- if (SCAN_ALL) |
|
1877 |
- viruses_found++; |
|
1878 |
- else |
|
1879 |
- return CL_VIRUS; |
|
1875 |
+ if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber")) |
|
1876 |
+ if (SCAN_ALL) |
|
1877 |
+ viruses_found++; |
|
1878 |
+ else |
|
1879 |
+ return CL_VIRUS; |
|
1880 | 1880 |
} |
1881 | 1881 |
|
1882 | 1882 |
if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) { |
1883 | 1883 |
cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count); |
1884 |
- cli_append_virus(ctx,"Heuristics.Structured.SSN"); |
|
1885 |
- if (SCAN_ALL) |
|
1886 |
- viruses_found++; |
|
1887 |
- else |
|
1888 |
- return CL_VIRUS; |
|
1884 |
+ if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.SSN")) |
|
1885 |
+ if (SCAN_ALL) |
|
1886 |
+ viruses_found++; |
|
1887 |
+ else |
|
1888 |
+ return CL_VIRUS; |
|
1889 | 1889 |
} |
1890 | 1890 |
|
1891 | 1891 |
if (viruses_found) |
... | ... |
@@ -2161,32 +2157,32 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2161 | 2161 |
case CL_TYPE_MHTML: |
2162 | 2162 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) { |
2163 | 2163 |
cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset); |
2164 |
- ret = cli_scanmail(ctx); |
|
2164 |
+ nret = ret = cli_scanmail(ctx); |
|
2165 | 2165 |
} |
2166 | 2166 |
break; |
2167 | 2167 |
|
2168 | 2168 |
case CL_TYPE_XDP: |
2169 | 2169 |
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { |
2170 | 2170 |
cli_dbgmsg("XDP signature found at %u\n", (unsigned int) fpt->offset); |
2171 |
- ret = cli_scanxdp(ctx); |
|
2171 |
+ nret = ret = cli_scanxdp(ctx); |
|
2172 | 2172 |
} |
2173 | 2173 |
break; |
2174 | 2174 |
case CL_TYPE_XML_WORD: |
2175 | 2175 |
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { |
2176 | 2176 |
cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int) fpt->offset); |
2177 |
- ret = cli_scanmsxml(ctx); |
|
2177 |
+ nret = ret = cli_scanmsxml(ctx); |
|
2178 | 2178 |
} |
2179 | 2179 |
break; |
2180 | 2180 |
case CL_TYPE_XML_XL: |
2181 | 2181 |
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { |
2182 | 2182 |
cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int) fpt->offset); |
2183 |
- ret = cli_scanmsxml(ctx); |
|
2183 |
+ nret = ret = cli_scanmsxml(ctx); |
|
2184 | 2184 |
} |
2185 | 2185 |
break; |
2186 | 2186 |
case CL_TYPE_XML_HWP: |
2187 | 2187 |
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) { |
2188 | 2188 |
cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int) fpt->offset); |
2189 |
- ret = cli_scanhwpml(ctx); |
|
2189 |
+ nret = ret = cli_scanhwpml(ctx); |
|
2190 | 2190 |
} |
2191 | 2191 |
break; |
2192 | 2192 |
case CL_TYPE_RARSFX: |
... | ... |
@@ -2441,10 +2437,16 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char * |
2441 | 2441 |
|
2442 | 2442 |
UNUSEDPARAM(type); |
2443 | 2443 |
|
2444 |
- if (retcode == CL_CLEAN && (ctx->found_possibly_unwanted || ctx->num_viruses != 0)) |
|
2444 |
+ if (retcode == CL_CLEAN && ctx->found_possibly_unwanted) { |
|
2445 |
+ cli_virus_found_cb(ctx); |
|
2445 | 2446 |
cb_retcode = CL_VIRUS; |
2446 |
- else |
|
2447 |
- cb_retcode = retcode; |
|
2447 |
+ } |
|
2448 |
+ else { |
|
2449 |
+ if (retcode == CL_CLEAN && ctx->num_viruses != 0) |
|
2450 |
+ cb_retcode = CL_VIRUS; |
|
2451 |
+ else |
|
2452 |
+ cb_retcode = retcode; |
|
2453 |
+ } |
|
2448 | 2454 |
|
2449 | 2455 |
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); |
2450 | 2456 |
if(ctx->engine->cb_post_scan) { |
... | ... |
@@ -2689,6 +2691,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2689 | 2689 |
|
2690 | 2690 |
perf_stop(ctx, PERFT_CACHE); |
2691 | 2691 |
hashed_size = (*ctx->fmap)->len; |
2692 |
+ memcpy((*ctx->fmap)->maphash, hash, 16); |
|
2692 | 2693 |
ctx->hook_lsig_matches = NULL; |
2693 | 2694 |
|
2694 | 2695 |
if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */ |
... | ... |
@@ -90,8 +90,7 @@ int cli_check_mydoom_log(cli_ctx *ctx) |
90 | 90 |
if ((~check) != key) |
91 | 91 |
return CL_CLEAN; |
92 | 92 |
|
93 |
- cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log"); |
|
94 |
- return CL_VIRUS; |
|
93 |
+ return cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log"); |
|
95 | 94 |
} |
96 | 95 |
|
97 | 96 |
static int jpeg_check_photoshop_8bim(cli_ctx *ctx, off_t *off) |
... | ... |
@@ -146,8 +146,7 @@ int cli_parsetiff(cli_ctx *ctx) |
146 | 146 |
if(entry.value + value_size > map->len) { |
147 | 147 |
cli_warnmsg("cli_parsetiff: TFD entry field %u exceeds bounds of TIFF file [%llu > %llu]\n", |
148 | 148 |
i, (long long unsigned)(entry.value + value_size), (long long unsigned)map->len); |
149 |
- cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess"); |
|
150 |
- return CL_VIRUS; |
|
149 |
+ return cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess"); |
|
151 | 150 |
} |
152 | 151 |
} |
153 | 152 |
} |
... | ... |
@@ -556,9 +556,8 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int |
556 | 556 |
|
557 | 557 |
if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) { |
558 | 558 |
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n"); |
559 |
- cli_append_virus(ctx, "Heuristics.Encrypted.Zip"); |
|
560 |
- *ret = CL_VIRUS; |
|
561 |
- if (!SCAN_ALL) { |
|
559 |
+ *ret = cli_append_virus(ctx, "Heuristics.Encrypted.Zip"); |
|
560 |
+ if ((*ret == CL_VIRUS && !SCAN_ALL) || *ret != CL_CLEAN) { |
|
562 | 561 |
fmap_unneed_off(map, loff, SIZEOF_LH); |
563 | 562 |
return 0; |
564 | 563 |
} |
... | ... |
@@ -461,27 +461,27 @@ static void do_phishing_test_allscan(const struct rtest *rtest) |
461 | 461 |
fail_unless(rc == CL_CLEAN,"phishingScan"); |
462 | 462 |
switch(rtest->result) { |
463 | 463 |
case 0: |
464 |
- fail_unless_fmt(ctx.found_possibly_unwanted, |
|
464 |
+ fail_unless_fmt(ctx.num_viruses, |
|
465 | 465 |
"this should be phishing, realURL: %s, displayURL: %s", |
466 | 466 |
rtest->realurl, rtest->displayurl); |
467 | 467 |
break; |
468 | 468 |
case 1: |
469 |
- fail_unless_fmt(!ctx.found_possibly_unwanted, |
|
469 |
+ fail_unless_fmt(!ctx.num_viruses, |
|
470 | 470 |
"this should be whitelisted, realURL: %s, displayURL: %s", |
471 | 471 |
rtest->realurl, rtest->displayurl); |
472 | 472 |
break; |
473 | 473 |
case 2: |
474 |
- fail_unless_fmt(!ctx.found_possibly_unwanted, |
|
474 |
+ fail_unless_fmt(!ctx.num_viruses, |
|
475 | 475 |
"this should be clean, realURL: %s, displayURL: %s", |
476 | 476 |
rtest->realurl, rtest->displayurl); |
477 | 477 |
break; |
478 | 478 |
case 3: |
479 | 479 |
if(!loaded_2) |
480 |
- fail_unless_fmt(!ctx.found_possibly_unwanted, |
|
480 |
+ fail_unless_fmt(!ctx.num_viruses, |
|
481 | 481 |
"this should be clean, realURL: %s, displayURL: %s", |
482 | 482 |
rtest->realurl, rtest->displayurl); |
483 | 483 |
else { |
484 |
- fail_unless_fmt(ctx.found_possibly_unwanted, |
|
484 |
+ fail_unless_fmt(ctx.num_viruses, |
|
485 | 485 |
"this should be blacklisted, realURL: %s, displayURL: %s", |
486 | 486 |
rtest->realurl, rtest->displayurl); |
487 | 487 |
if (*ctx.virname) |