Phase 1 of reporting hashes of PE sections

Conflicts:
	libclamav/stats.h
This commit is contained in:
Shawn Webb 2014-01-21 11:30:27 -05:00
parent 06bd94f0fd
commit 3c29ca0b10
9 changed files with 186 additions and 74 deletions

View file

@ -220,7 +220,15 @@ enum bytecode_mode {
CL_BYTECODE_MODE_OFF /* for query only, not settable */ CL_BYTECODE_MODE_OFF /* for query only, not settable */
}; };
typedef enum cli_intel_sample_type { WHOLEFILE = 0, PESECTION = 1 } cli_intel_sample_type_t; /* For stats/intel gathering */ struct cli_section_hash {
unsigned char md5[16];
size_t len;
};
typedef struct cli_stats_sections {
size_t nsections;
struct cli_section_hash *sections;
} stats_section_t;
extern int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long long num); extern int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long long num);
@ -360,13 +368,13 @@ extern void cl_engine_set_clcb_meta(struct cl_engine *engine, clcb_meta callback
/* Statistics/intelligence gathering callbacks */ /* Statistics/intelligence gathering callbacks */
extern void cl_engine_set_stats_set_cbdata(struct cl_engine *engine, void *cbdata); extern void cl_engine_set_stats_set_cbdata(struct cl_engine *engine, void *cbdata);
typedef void (*clcb_stats_add_sample)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata); typedef void (*clcb_stats_add_sample)(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata);
extern void cl_engine_set_clcb_stats_add_sample(struct cl_engine *engine, clcb_stats_add_sample callback); extern void cl_engine_set_clcb_stats_add_sample(struct cl_engine *engine, clcb_stats_add_sample callback);
typedef void (*clcb_stats_remove_sample)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata); typedef void (*clcb_stats_remove_sample)(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
extern void cl_engine_set_clcb_stats_remove_sample(struct cl_engine *engine, clcb_stats_remove_sample callback); extern void cl_engine_set_clcb_stats_remove_sample(struct cl_engine *engine, clcb_stats_remove_sample callback);
typedef void (*clcb_stats_decrement_count)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata); typedef void (*clcb_stats_decrement_count)(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
extern void cl_engine_set_clcb_stats_decrement_count(struct cl_engine *engine, clcb_stats_decrement_count callback); extern void cl_engine_set_clcb_stats_decrement_count(struct cl_engine *engine, clcb_stats_decrement_count callback);
typedef void (*clcb_stats_submit)(struct cl_engine *engine, void *cbdata); typedef void (*clcb_stats_submit)(struct cl_engine *engine, void *cbdata);

View file

@ -30,18 +30,6 @@ char *hex_encode(char *buf, char *data, size_t len)
return p; return p;
} }
const char *get_sample_type(cli_intel_sample_type_t type)
{
switch (type) {
case WHOLEFILE:
return "whole-file";
case PESECTION:
return "PE section";
default:
return NULL;
}
}
char *ensure_bufsize(char *buf, size_t *oldsize, size_t used, size_t additional) char *ensure_bufsize(char *buf, size_t *oldsize, size_t used, size_t additional)
{ {
char *p=buf; char *p=buf;
@ -106,19 +94,6 @@ char *export_stats_to_json(struct cl_engine *engine, cli_intel_t *intel)
snprintf(buf+curused, bufsz-curused, "\t\t\t\"hash\": \"%s\",\n", md5); snprintf(buf+curused, bufsz-curused, "\t\t\t\"hash\": \"%s\",\n", md5);
curused += strlen(buf+curused); curused += strlen(buf+curused);
type = get_sample_type(sample->type);
if (!(type)) {
free(buf);
return NULL;
}
buf = ensure_bufsize(buf, &bufsz, curused, sizeof("type") + strlen(type) + 15);
if (!(buf))
return NULL;
snprintf(buf+curused, bufsz-curused, "\t\t\t\"type\": \"%s\",\n", type);
curused += strlen(buf+curused);
/* Reuse the md5 variable for serializing the number of hits */ /* Reuse the md5 variable for serializing the number of hits */
snprintf(md5, sizeof(md5), "%u", sample->hits); snprintf(md5, sizeof(md5), "%u", sample->hits);

View file

@ -428,6 +428,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
uint8_t shash1[SHA1_HASH_SIZE*2+1]; uint8_t shash1[SHA1_HASH_SIZE*2+1];
uint8_t shash256[SHA256_HASH_SIZE*2+1]; uint8_t shash256[SHA256_HASH_SIZE*2+1];
int have_sha1, have_sha256, do_dsig_check = 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) { 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); cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s), size: %d\n", virname, (int)size);
@ -522,8 +523,11 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
} }
#endif #endif
if(do_dsig_check) { memset(&sections, 0x00, sizeof(stats_section_t));
switch(cli_checkfp_pe(ctx, shash1)) { if(do_dsig_check || ctx->engine->cb_stats_add_sample) {
uint32_t flags = (do_dsig_check ? CL_CHECKFP_PE_FLAG_AUTHENTICODE : 0) | (ctx->engine->cb_stats_add_sample ? CL_CHECKFP_PE_FLAG_STATS : 0);
switch(cli_checkfp_pe(ctx, shash1, &sections, flags)) {
case CL_CLEAN: case CL_CLEAN:
cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid embedded digital signature\n"); cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid embedded digital signature\n");
return CL_CLEAN; return CL_CLEAN;
@ -540,7 +544,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, md5, cli_get_last_virus(ctx), ctx->cb_ctx); ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, md5, cli_get_last_virus(ctx), ctx->cb_ctx);
if (ctx->engine->cb_stats_add_sample) if (ctx->engine->cb_stats_add_sample)
ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, WHOLEFILE, ctx->engine->stats_data); ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, &sections, ctx->engine->stats_data);
return CL_VIRUS; return CL_VIRUS;
} }

View file

@ -149,9 +149,9 @@ typedef struct cli_ctx_tag {
typedef struct cli_flagged_sample { typedef struct cli_flagged_sample {
char **virus_name; char **virus_name;
char md5[16]; char md5[16];
cli_intel_sample_type_t type;
size_t size; /* A size of zero means size is unavailable (why would this ever happen?) */ size_t size; /* A size of zero means size is unavailable (why would this ever happen?) */
uint32_t hits; uint32_t hits;
stats_section_t *sections;
struct cli_flagged_sample *prev; struct cli_flagged_sample *prev;
struct cli_flagged_sample *next; struct cli_flagged_sample *next;

View file

@ -60,6 +60,7 @@
#include "ishield.h" #include "ishield.h"
#include "asn1.h" #include "asn1.h"
#include "sha1.h" #include "sha1.h"
#include "libclamav/md5.h"
#define DCONF ctx->dconf->pe #define DCONF ctx->dconf->pe
@ -2796,7 +2797,7 @@ static int sort_sects(const void *first, const void *second) {
return (a->raw - b->raw); return (a->raw - b->raw);
} }
int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) { int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uint32_t flags) {
uint16_t e_magic; /* DOS signature ("MZ") */ uint16_t e_magic; /* DOS signature ("MZ") */
uint16_t nsections; uint16_t nsections;
uint32_t e_lfanew; /* address of new exe header */ uint32_t e_lfanew; /* address of new exe header */
@ -2814,6 +2815,14 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
struct pe_image_data_dir *dirs; struct pe_image_data_dir *dirs;
fmap_t *map = *ctx->fmap; fmap_t *map = *ctx->fmap;
SHA1Context sha1; SHA1Context sha1;
cli_md5_ctx md5ctx;
if (flags & CL_CHECKFP_PE_FLAG_STATS)
if (!(hashes))
return CL_EFORMAT;
if (flags == CL_CHECKFP_PE_FLAG_NONE)
return 0;
if(!(DCONF & PE_CONF_CATALOG)) if(!(DCONF & PE_CONF_CATALOG))
return CL_EFORMAT; return CL_EFORMAT;
@ -2903,6 +2912,15 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
hdr_size = PESALIGN(hdr_size, falign); /* Aligned headers virtual size */ hdr_size = PESALIGN(hdr_size, falign); /* Aligned headers virtual size */
if (flags & CL_CHECKFP_PE_FLAG_STATS) {
hashes->nsections = nsections;
hashes->sections = cli_calloc(nsections, sizeof(struct cli_section_hash));
if (!(hashes->sections)) {
free(exe_sections);
return CL_EMEM;
}
}
for(i = 0; i < nsections; i++) { for(i = 0; i < nsections; i++) {
exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign); exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign); exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
@ -2928,9 +2946,10 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
cli_qsort(exe_sections, nsections, sizeof(*exe_sections), sort_sects); cli_qsort(exe_sections, nsections, sizeof(*exe_sections), sort_sects);
SHA1Init(&sha1); if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE)
SHA1Init(&sha1);
#define hash_chunk(where, size) \ #define hash_chunk(where, size, isStatAble, section) \
do { \ do { \
const uint8_t *hptr; \ const uint8_t *hptr; \
if(!(size)) break; \ if(!(size)) break; \
@ -2938,13 +2957,20 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
free(exe_sections); \ free(exe_sections); \
return CL_EFORMAT; \ return CL_EFORMAT; \
} \ } \
SHA1Update(&sha1, hptr, size); \ if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) \
SHA1Update(&sha1, hptr, size); \
if (isStatAble && flags & CL_CHECKFP_PE_FLAG_STATS) { \
cli_md5_init(&md5ctx); \
cli_md5_update(&md5ctx, hptr, size); \
cli_md5_final(hashes->sections[section].md5, &md5ctx); \
hashes->sections[section].len = size; \
} \
} while(0) } while(0)
/* MZ to checksum */ /* MZ to checksum */
at = 0; at = 0;
hlen = e_lfanew + sizeof(struct pe_image_file_hdr) + (pe_plus ? offsetof(struct pe_image_optional_hdr64, CheckSum) : offsetof(struct pe_image_optional_hdr32, CheckSum)); hlen = e_lfanew + sizeof(struct pe_image_file_hdr) + (pe_plus ? offsetof(struct pe_image_optional_hdr64, CheckSum) : offsetof(struct pe_image_optional_hdr32, CheckSum));
hash_chunk(0, hlen); hash_chunk(0, hlen, 0, 0);
at = hlen + 4; at = hlen + 4;
/* Checksum to security */ /* Checksum to security */
@ -2952,7 +2978,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4; hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4;
else else
hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4; hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4;
hash_chunk(at, hlen); hash_chunk(at, hlen, 0, 0);
at += hlen + 8; at += hlen + 8;
if(at > hdr_size) { if(at > hdr_size) {
@ -2962,7 +2988,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
/* Security to End of header */ /* Security to End of header */
hlen = hdr_size - at; hlen = hdr_size - at;
hash_chunk(at, hlen); hash_chunk(at, hlen, 0, 0);
/* Sections */ /* Sections */
at = hdr_size; at = hdr_size;
@ -2970,7 +2996,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
if(!exe_sections[i].rsz) if(!exe_sections[i].rsz)
continue; continue;
hash_chunk(exe_sections[i].raw, exe_sections[i].rsz); hash_chunk(exe_sections[i].raw, exe_sections[i].rsz, 1, i);
at += exe_sections[i].rsz; at += exe_sections[i].rsz;
} }
@ -2982,7 +3008,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
} }
hlen -= dirs[4].Size; hlen -= dirs[4].Size;
hash_chunk(at, hlen); hash_chunk(at, hlen, 0, 0);
at += hlen; at += hlen;
} }
free(exe_sections); free(exe_sections);

View file

@ -160,8 +160,12 @@ struct cli_pe_hook_data {
int cli_scanpe(cli_ctx *ctx); int cli_scanpe(cli_ctx *ctx);
#define CL_CHECKFP_PE_FLAG_NONE 0x00000000
#define CL_CHECKFP_PE_FLAG_STATS 0x00000001
#define CL_CHECKFP_PE_FLAG_AUTHENTICODE 0x00000002
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo); int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo);
int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1); int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uint32_t flags);
uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t); uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t);
void findres(uint32_t, uint32_t, uint32_t, fmap_t *map, struct cli_exe_section *, uint16_t, uint32_t, int (*)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *); void findres(uint32_t, uint32_t, uint32_t, fmap_t *map, struct cli_exe_section *, uint16_t, uint32_t, int (*)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *);

View file

@ -31,10 +31,84 @@
#include "libclamav/hostid.h" #include "libclamav/hostid.h"
#include "libclamav/www.h" #include "libclamav/www.h"
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type); #define DEBUG_STATS 1
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections);
void free_sample(cli_flagged_sample_t *sample); void free_sample(cli_flagged_sample_t *sample);
void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata) #if DEBUG_STATS
char *get_hash(unsigned char *md5)
{
char *hash;
int i;
hash = calloc(1, 33);
if (!(hash))
return NULL;
for (i=0; i<16; i++)
sprintf(hash+(i*2), "%02x", md5[i]);
return hash;
}
char *get_sample_names(char **names)
{
char *ret;
size_t n, i, sz;
sz = 0;
for (n=0; names[n] != NULL; n++)
sz += strlen(names[n]);
ret = calloc(1, sz + n + 1);
if (!(ret))
return NULL;
for (i=0; names[i] != NULL; i++)
sprintf(ret+strlen(ret), "%s%s", (i==0) ? "" : " ", names[i]);
return ret;
}
void print_sample(cli_flagged_sample_t *sample)
{
char *hash, *names;
size_t i;
if (!(sample))
return;
hash = get_hash(sample->md5);
if (!(hash))
return;
cli_warnmsg("Sample[%s]:\n", hash);
cli_warnmsg(" * Size: %zu\n", sample->size);
cli_warnmsg(" * Hits: %u\n", sample->hits);
free(hash);
names = get_sample_names(sample->virus_name);
if ((names))
cli_warnmsg(" * Names: %s\n", names);
if (sample->sections && sample->sections->nsections) {
for (i=0; i < sample->sections->nsections; i++) {
hash = get_hash(sample->sections->sections[i].md5);
if ((hash)) {
cli_warnmsg(" * Section[%zu] (%zu): %s\n", i, sample->sections->sections[i].len, hash);
free(hash);
}
}
}
if ((names))
free(names);
}
#endif
void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata)
{ {
cli_intel_t *intel; cli_intel_t *intel;
cli_flagged_sample_t *sample; cli_flagged_sample_t *sample;
@ -81,7 +155,7 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
} }
#endif #endif
sample = find_sample(intel, virname, md5, size, type); sample = find_sample(intel, virname, md5, size, sections);
if (!(sample)) { if (!(sample)) {
if (!(intel->samples)) { if (!(intel->samples)) {
sample = intel->samples = calloc(1, sizeof(cli_flagged_sample_t)); sample = intel->samples = calloc(1, sizeof(cli_flagged_sample_t));
@ -136,9 +210,15 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
sample->virus_name[i+1] = NULL; sample->virus_name[i+1] = NULL;
memcpy(sample->md5, md5, sizeof(sample->md5)); memcpy(sample->md5, md5, sizeof(sample->md5));
sample->type = type;
sample->size = size; sample->size = size;
intel->nsamples++; intel->nsamples++;
if (sections && sections->nsections && !(sample->sections)) {
/* Copy the section data that has already been allocated. We don't care if calloc fails; just skip copying if it does. */
sample->sections = calloc(1, sizeof(stats_section_t));
if ((sample->sections))
memcpy(sample->sections, sections, sizeof(stats_section_t));
}
} }
cli_warnmsg("Added %s to the stats cache\n", (virname != NULL) ? virname: "[unknown]"); cli_warnmsg("Added %s to the stats cache\n", (virname != NULL) ? virname: "[unknown]");
@ -249,6 +329,9 @@ void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
#endif #endif
for (sample=myintel.samples; sample != NULL; sample = next) { for (sample=myintel.samples; sample != NULL; sample = next) {
#if DEBUG_STATS
print_sample(sample);
#endif
next = sample->next; next = sample->next;
free_sample(sample); free_sample(sample);
@ -261,7 +344,7 @@ void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
} }
} }
void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata) void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
{ {
cli_intel_t *intel; cli_intel_t *intel;
cli_flagged_sample_t *sample; cli_flagged_sample_t *sample;
@ -279,19 +362,17 @@ void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, s
} }
#endif #endif
sample = find_sample(intel, virname, md5, size, type); while ((sample = find_sample(intel, virname, md5, size, NULL))) {
if (!(sample)) if (sample->prev)
return; sample->prev->next = sample->next;
if (sample->next)
sample->next->prev = sample->prev;
if (sample == intel->samples)
intel->samples = sample->next;
if (sample->prev) free_sample(sample);
sample->prev->next = sample->next; intel->nsamples--;
if (sample->next) }
sample->next->prev = sample;
if (sample == intel->samples)
intel->samples = sample->next;
free_sample(sample);
intel->nsamples--;
#ifdef CL_THREAD_SAFE #ifdef CL_THREAD_SAFE
err = pthread_mutex_unlock(&(intel->mutex)); err = pthread_mutex_unlock(&(intel->mutex));
@ -301,7 +382,7 @@ void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, s
#endif #endif
} }
void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata) void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
{ {
cli_intel_t *intel; cli_intel_t *intel;
cli_flagged_sample_t *sample; cli_flagged_sample_t *sample;
@ -319,15 +400,15 @@ void clamav_stats_decrement_count(const char *virname, const unsigned char *md5,
} }
#endif #endif
sample = find_sample(intel, virname, md5, size, type); sample = find_sample(intel, virname, md5, size, NULL);
if (!(sample)) if (!(sample))
return; return;
if (sample->hits == 1) { if (sample->hits == 1) {
if ((intel->engine->cb_stats_remove_sample)) if ((intel->engine->cb_stats_remove_sample))
intel->engine->cb_stats_remove_sample(virname, md5, size, type, intel); intel->engine->cb_stats_remove_sample(virname, md5, size, intel);
else else
clamav_stats_remove_sample(virname, md5, size, type, intel); clamav_stats_remove_sample(virname, md5, size, intel);
return; return;
} }
@ -444,14 +525,13 @@ char *clamav_stats_get_hostid(void *cbdata)
} }
#endif #endif
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type) static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections)
{ {
cli_flagged_sample_t *sample; cli_flagged_sample_t *sample;
size_t i; size_t i;
for (sample = intel->samples; sample != NULL; sample = sample->next) { for (sample = intel->samples; sample != NULL; sample = sample->next) {
if (sample->type != type) int foundSections = 0;
continue;
if (sample->size != size) if (sample->size != size)
continue; continue;
@ -462,9 +542,24 @@ static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname
if (!(virname)) if (!(virname))
return sample; return sample;
for (i=0; sample->virus_name[i] != NULL; i++) if ((sections) && (sample->sections)) {
if (!strcmp(sample->virus_name[i], virname)) if (sections->nsections == sample->sections->nsections) {
return sample; for (i=0; i < sections->nsections; i++)
if (sections->sections[i].len == sample->sections->sections[i].len)
if (memcmp(sections->sections[i].md5, sample->sections->sections[i].md5, sizeof(stats_section_t)))
break;
if (i == sections->nsections)
foundSections = 1;
}
} else {
foundSections = 1;
}
if (foundSections)
for (i=0; sample->virus_name[i] != NULL; i++)
if (!strcmp(sample->virus_name[i], virname))
return sample;
} }
return NULL; return NULL;

View file

@ -4,11 +4,11 @@
#define STATS_HOST "stats.clamav.dev" /* Change this before release! */ #define STATS_HOST "stats.clamav.dev" /* Change this before release! */
#define STATS_PORT "8080" #define STATS_PORT "8080"
void clamav_stats_add_sample(const char *virname, const unsigned char *md5, uint64_t size, cli_intel_sample_type_t type, void *cbdata); void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata);
void clamav_stats_submit(struct cl_engine *engine, void *cbdata); void clamav_stats_submit(struct cl_engine *engine, void *cbdata);
void clamav_stats_flush(struct cl_engine *engine, void *cbdata); void clamav_stats_flush(struct cl_engine *engine, void *cbdata);
void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata); void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata); void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
size_t clamav_stats_get_num(void *cbdata); size_t clamav_stats_get_num(void *cbdata);
size_t clamav_stats_get_size(void *cbdata); size_t clamav_stats_get_size(void *cbdata);
char *clamav_stats_get_hostid(void *cbdata); char *clamav_stats_get_hostid(void *cbdata);

View file

@ -2873,7 +2873,7 @@ static int dumpcerts(const struct optstruct *opts)
SHA1Update(&sha1, fmptr, sb.st_size); SHA1Update(&sha1, fmptr, sb.st_size);
SHA1Final(&sha1, shash1); SHA1Final(&sha1, shash1);
ret = cli_checkfp_pe(&ctx, shash1); ret = cli_checkfp_pe(&ctx, shash1, NULL, CL_CHECKFP_PE_FLAG_AUTHENTICODE);
switch(ret) { switch(ret) {
case CL_CLEAN: case CL_CLEAN: