... | ... |
@@ -502,7 +502,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc |
502 | 502 |
return ret; |
503 | 503 |
} |
504 | 504 |
|
505 |
-int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info) |
|
505 |
+int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash) |
|
506 | 506 |
{ |
507 | 507 |
unsigned int i, evalcnt; |
508 | 508 |
uint64_t evalids; |
... | ... |
@@ -527,14 +527,17 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac |
527 | 527 |
continue; |
528 | 528 |
} |
529 | 529 |
|
530 |
- if(root->ac_lsigtable[i]->tdb.handlertype) { |
|
531 |
- ctx->recursion++; |
|
532 |
- if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) { |
|
530 |
+ if(hash && root->ac_lsigtable[i]->tdb.handlertype) { |
|
531 |
+ if(memcmp(ctx->handlertype_hash, hash, 16)) { |
|
532 |
+ ctx->recursion++; |
|
533 |
+ memcpy(ctx->handlertype_hash, hash, 16); |
|
534 |
+ if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) { |
|
535 |
+ ctx->recursion--; |
|
536 |
+ return CL_VIRUS; |
|
537 |
+ } |
|
533 | 538 |
ctx->recursion--; |
534 |
- return CL_VIRUS; |
|
539 |
+ continue; |
|
535 | 540 |
} |
536 |
- ctx->recursion--; |
|
537 |
- continue; |
|
538 | 541 |
} |
539 | 542 |
|
540 | 543 |
if(root->ac_lsigtable[i]->tdb.icongrp1 || root->ac_lsigtable[i]->tdb.icongrp2) { |
... | ... |
@@ -695,8 +698,18 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
695 | 695 |
offset += bytes - maxpatlen; |
696 | 696 |
} |
697 | 697 |
|
698 |
+ if(!ftonly && ctx->engine->md5_hdb) { |
|
699 |
+ if(!refhash) { |
|
700 |
+ cli_md5_final(digest, &md5ctx); |
|
701 |
+ refhash = digest; |
|
702 |
+ } |
|
703 |
+ if(cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS) |
|
704 |
+ ret = CL_VIRUS; |
|
705 |
+ } |
|
706 |
+ |
|
698 | 707 |
if(troot) { |
699 |
- ret = cli_lsig_eval(ctx, troot, &tdata, &info); |
|
708 |
+ if(ret != CL_VIRUS) |
|
709 |
+ ret = cli_lsig_eval(ctx, troot, &tdata, &info, refhash); |
|
700 | 710 |
cli_ac_freedata(&tdata); |
701 | 711 |
if(bm_offmode) |
702 | 712 |
cli_bm_freeoff(&toff); |
... | ... |
@@ -704,7 +717,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
704 | 704 |
|
705 | 705 |
if(groot) { |
706 | 706 |
if(ret != CL_VIRUS) |
707 |
- ret = cli_lsig_eval(ctx, groot, &gdata, &info); |
|
707 |
+ ret = cli_lsig_eval(ctx, groot, &gdata, &info, refhash); |
|
708 | 708 |
cli_ac_freedata(&gdata); |
709 | 709 |
} |
710 | 710 |
|
... | ... |
@@ -715,15 +728,6 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
715 | 715 |
if(ret == CL_VIRUS) |
716 | 716 |
return CL_VIRUS; |
717 | 717 |
|
718 |
- if(!ftonly && ctx->engine->md5_hdb) { |
|
719 |
- if(!refhash) { |
|
720 |
- cli_md5_final(digest, &md5ctx); |
|
721 |
- refhash = digest; |
|
722 |
- } |
|
723 |
- if(cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS) |
|
724 |
- return CL_VIRUS; |
|
725 |
- } |
|
726 |
- |
|
727 | 718 |
return (acmode & AC_SCAN_FT) ? type : CL_CLEAN; |
728 | 719 |
} |
729 | 720 |
|
... | ... |
@@ -169,7 +169,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, |
169 | 169 |
|
170 | 170 |
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres); |
171 | 171 |
int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, unsigned char *refhash); |
172 |
-int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info); |
|
172 |
+int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash); |
|
173 | 173 |
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); |
174 | 174 |
|
175 | 175 |
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx); |
... | ... |
@@ -120,6 +120,7 @@ typedef struct cli_ctx_tag { |
120 | 120 |
unsigned int corrupted_input; |
121 | 121 |
cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */ |
122 | 122 |
size_t container_size; |
123 |
+ unsigned char handlertype_hash[16]; |
|
123 | 124 |
struct cli_dconf *dconf; |
124 | 125 |
fmap_t **fmap; |
125 | 126 |
bitset_t* hook_lsig_matches; |
... | ... |
@@ -1112,9 +1112,9 @@ static int cli_scanscript(cli_ctx *ctx) |
1112 | 1112 |
} |
1113 | 1113 |
free(normalized); |
1114 | 1114 |
if(ret != CL_VIRUS) { |
1115 |
- ret = cli_lsig_eval(ctx, troot, &tmdata, NULL); |
|
1115 |
+ ret = cli_lsig_eval(ctx, troot, &tmdata, NULL, NULL); |
|
1116 | 1116 |
if(ret != CL_VIRUS) |
1117 |
- ret = cli_lsig_eval(ctx, groot, &gmdata, NULL); |
|
1117 |
+ ret = cli_lsig_eval(ctx, groot, &gmdata, NULL, NULL); |
|
1118 | 1118 |
} |
1119 | 1119 |
cli_ac_freedata(&tmdata); |
1120 | 1120 |
cli_ac_freedata(&gmdata); |