static int map_sha1(fmap_t *map, const void *data, unsigned int len, uint8_t sha1[SHA1_HASH_SIZE]) { if(!fmap_need_ptr_once(map, data, len)) { cli_dbgmsg("map_sha1: failed to read hash data\n"); return 1; } return (cl_sha1(data, len, sha1, NULL) == NULL); }
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) { char md5[33]; unsigned int i; const char *virname=NULL; fmap_t *map; const char *ptr; uint8_t shash1[SHA1_HASH_SIZE*2+1]; uint8_t shash256[SHA256_HASH_SIZE*2+1]; int have_sha1, have_sha256, do_dsig_check = 1; stats_section_t sections; if(cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s), size: %d\n", virname, (int)size); return CL_CLEAN; } else if(cli_hm_scan_wild(digest, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s), size: *\n", virname); return CL_CLEAN; } if(cli_debug_flag || ctx->engine->cb_hash) { for(i = 0; i < 16; i++) sprintf(md5 + i * 2, "%02x", digest[i]); md5[32] = 0; cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, cli_get_last_virus(ctx) ? cli_get_last_virus(ctx) : "Name"); } if(cli_get_last_virus(ctx)) do_dsig_check = strncmp("W32S.", cli_get_last_virus(ctx), 5); map = *ctx->fmap; have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size) || cli_hm_have_wild(ctx->engine->hm_fp, CLI_HASH_SHA1) || (cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, 1) && do_dsig_check); have_sha256 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA256, size) || cli_hm_have_wild(ctx->engine->hm_fp, CLI_HASH_SHA256); if(have_sha1 || have_sha256) { if((ptr = fmap_need_off_once(map, 0, size))) { if(have_sha1) { cl_sha1(ptr, size, &shash1[SHA1_HASH_SIZE], NULL); if(cli_hm_scan(&shash1[SHA1_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(sha1): Found false positive detection (fp sig: %s)\n", virname); return CL_CLEAN; } if(cli_hm_scan_wild(&shash1[SHA1_HASH_SIZE], &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(sha1): Found false positive detection (fp sig: %s)\n", virname); return CL_CLEAN; } if(do_dsig_check && cli_hm_scan(&shash1[SHA1_HASH_SIZE], 1, &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(sha1): Found false positive detection via catalog file\n"); return CL_CLEAN; } } if(have_sha256) { cl_sha256(ptr, size, &shash256[SHA256_HASH_SIZE], NULL); if(cli_hm_scan(&shash256[SHA256_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA256) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(sha256): Found false positive detection (fp sig: %s)\n", virname); return CL_CLEAN; } if(cli_hm_scan_wild(&shash256[SHA256_HASH_SIZE], &virname, ctx->engine->hm_fp, CLI_HASH_SHA256) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(sha256): Found false positive detection (fp sig: %s)\n", virname); return CL_CLEAN; } } } } #ifdef HAVE__INTERNAL__SHA_COLLECT if((ctx->options & CL_SCAN_INTERNAL_COLLECT_SHA) && ctx->sha_collect>0) { if((ptr = fmap_need_off_once(map, 0, size))) { if(!have_sha256) cl_sha256(ptr, size, shash256+SHA256_HASH_SIZE, NULL); for(i=0; i<SHA256_HASH_SIZE; i++) sprintf((char *)shash256+i*2, "%02x", shash256[SHA256_HASH_SIZE+i]); if(!have_sha1) cl_sha1(ptr, size, shash1+SHA1_HASH_SIZE); for(i=0; i<SHA1_HASH_SIZE; i++) sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]); cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, cli_get_last_virus(ctx), ctx->entry_filename); } else cli_errmsg("can't compute sha\n!"); ctx->sha_collect = -1; } #endif memset(§ions, 0x00, sizeof(stats_section_t)); if(do_dsig_check || ctx->engine->cb_stats_add_sample) { uint32_t flags = (do_dsig_check ? CL_CHECKFP_PE_FLAG_AUTHENTICODE : 0); if (!(ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_PE_STATS) && !(ctx->engine->dconf->stats & (DCONF_STATS_DISABLED | DCONF_STATS_PE_SECTION_DISABLED))) flags |= CL_CHECKFP_PE_FLAG_STATS; switch(cli_checkfp_pe(ctx, shash1, §ions, flags)) { case CL_CLEAN: cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid embedded digital signature\n"); return CL_CLEAN; case CL_VIRUS: if(cli_hm_scan(shash1, 2, &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS) { cli_dbgmsg("cli_checkfp(pe): PE file whitelisted by catalog file\n"); return CL_CLEAN; } } } if (ctx->engine->cb_hash) ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, cli_get_last_virus(ctx), ctx->cb_ctx); if (ctx->engine->cb_stats_add_sample) ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, §ions, ctx->engine->stats_data); if (sections.sections) free(sections.sections); return CL_VIRUS; }