Browse code

Phase 1 of reporting hashes of PE sections

Conflicts:
libclamav/stats.h

Shawn Webb authored on 2014/01/22 01:30:27
Showing 9 changed files
... ...
@@ -220,7 +220,15 @@ enum bytecode_mode {
220 220
     CL_BYTECODE_MODE_OFF /* for query only, not settable */
221 221
 };
222 222
 
223
-typedef enum cli_intel_sample_type { WHOLEFILE = 0, PESECTION = 1 } cli_intel_sample_type_t; /* For stats/intel gathering */
223
+struct cli_section_hash {
224
+    unsigned char md5[16];
225
+    size_t len;
226
+};
227
+
228
+typedef struct cli_stats_sections {
229
+    size_t nsections;
230
+    struct cli_section_hash *sections;
231
+} stats_section_t;
224 232
 
225 233
 extern int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long long num);
226 234
 
... ...
@@ -360,13 +368,13 @@ extern void cl_engine_set_clcb_meta(struct cl_engine *engine, clcb_meta callback
360 360
 /* Statistics/intelligence gathering callbacks */
361 361
 extern void cl_engine_set_stats_set_cbdata(struct cl_engine *engine, void *cbdata);
362 362
 
363
-typedef void (*clcb_stats_add_sample)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata);
363
+typedef void (*clcb_stats_add_sample)(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata);
364 364
 extern void cl_engine_set_clcb_stats_add_sample(struct cl_engine *engine, clcb_stats_add_sample callback);
365 365
 
366
-typedef void (*clcb_stats_remove_sample)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata);
366
+typedef void (*clcb_stats_remove_sample)(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
367 367
 extern void cl_engine_set_clcb_stats_remove_sample(struct cl_engine *engine, clcb_stats_remove_sample callback);
368 368
 
369
-typedef void (*clcb_stats_decrement_count)(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata);
369
+typedef void (*clcb_stats_decrement_count)(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
370 370
 extern void cl_engine_set_clcb_stats_decrement_count(struct cl_engine *engine, clcb_stats_decrement_count callback);
371 371
 
372 372
 typedef void (*clcb_stats_submit)(struct cl_engine *engine, void *cbdata);
... ...
@@ -30,18 +30,6 @@ char *hex_encode(char *buf, char *data, size_t len)
30 30
     return p;
31 31
 }
32 32
 
33
-const char *get_sample_type(cli_intel_sample_type_t type)
34
-{
35
-    switch (type) {
36
-        case WHOLEFILE:
37
-            return "whole-file";
38
-        case PESECTION:
39
-            return "PE section";
40
-        default:
41
-            return NULL;
42
-    }
43
-}
44
-
45 33
 char *ensure_bufsize(char *buf, size_t *oldsize, size_t used, size_t additional)
46 34
 {
47 35
     char *p=buf;
... ...
@@ -106,19 +94,6 @@ char *export_stats_to_json(struct cl_engine *engine, cli_intel_t *intel)
106 106
         snprintf(buf+curused, bufsz-curused, "\t\t\t\"hash\": \"%s\",\n", md5);
107 107
         curused += strlen(buf+curused);
108 108
 
109
-        type = get_sample_type(sample->type);
110
-        if (!(type)) {
111
-            free(buf);
112
-            return NULL;
113
-        }
114
-
115
-        buf = ensure_bufsize(buf, &bufsz, curused, sizeof("type") + strlen(type) + 15);
116
-        if (!(buf))
117
-            return NULL;
118
-
119
-        snprintf(buf+curused, bufsz-curused, "\t\t\t\"type\": \"%s\",\n", type);
120
-        curused += strlen(buf+curused);
121
-
122 109
         /* Reuse the md5 variable for serializing the number of hits */
123 110
         snprintf(md5, sizeof(md5), "%u", sample->hits);
124 111
 
... ...
@@ -428,6 +428,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
428 428
     uint8_t shash1[SHA1_HASH_SIZE*2+1];
429 429
     uint8_t shash256[SHA256_HASH_SIZE*2+1];
430 430
     int have_sha1, have_sha256, do_dsig_check = 1;
431
+    stats_section_t sections;
431 432
 
432 433
     if(cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) {
433 434
         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)
522 522
     }
523 523
 #endif
524 524
 
525
-    if(do_dsig_check) {
526
-        switch(cli_checkfp_pe(ctx, shash1)) {
525
+    memset(&sections, 0x00, sizeof(stats_section_t));
526
+    if(do_dsig_check || ctx->engine->cb_stats_add_sample) {
527
+        uint32_t flags = (do_dsig_check ? CL_CHECKFP_PE_FLAG_AUTHENTICODE : 0) | (ctx->engine->cb_stats_add_sample ? CL_CHECKFP_PE_FLAG_STATS : 0);
528
+
529
+        switch(cli_checkfp_pe(ctx, shash1, &sections, flags)) {
527 530
         case CL_CLEAN:
528 531
             cli_dbgmsg("cli_checkfp(pe): PE file whitelisted due to valid embedded digital signature\n");
529 532
             return CL_CLEAN;
... ...
@@ -540,7 +544,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
540 540
         ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, md5, cli_get_last_virus(ctx), ctx->cb_ctx);
541 541
 
542 542
     if (ctx->engine->cb_stats_add_sample)
543
-        ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, WHOLEFILE, ctx->engine->stats_data);
543
+        ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, &sections, ctx->engine->stats_data);
544 544
 
545 545
     return CL_VIRUS;
546 546
 }
... ...
@@ -149,9 +149,9 @@ typedef struct cli_ctx_tag {
149 149
 typedef struct cli_flagged_sample {
150 150
     char **virus_name;
151 151
     char md5[16];
152
-    cli_intel_sample_type_t type;
153 152
     size_t size; /* A size of zero means size is unavailable (why would this ever happen?) */
154 153
     uint32_t hits;
154
+    stats_section_t *sections;
155 155
 
156 156
     struct cli_flagged_sample *prev;
157 157
     struct cli_flagged_sample *next;
... ...
@@ -60,6 +60,7 @@
60 60
 #include "ishield.h"
61 61
 #include "asn1.h"
62 62
 #include "sha1.h"
63
+#include "libclamav/md5.h"
63 64
 
64 65
 #define DCONF ctx->dconf->pe
65 66
 
... ...
@@ -2796,7 +2797,7 @@ static int sort_sects(const void *first, const void *second) {
2796 2796
     return (a->raw - b->raw);
2797 2797
 }
2798 2798
 
2799
-int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2799
+int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uint32_t flags) {
2800 2800
     uint16_t e_magic; /* DOS signature ("MZ") */
2801 2801
     uint16_t nsections;
2802 2802
     uint32_t e_lfanew; /* address of new exe header */
... ...
@@ -2814,6 +2815,14 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2814 2814
     struct pe_image_data_dir *dirs;
2815 2815
     fmap_t *map = *ctx->fmap;
2816 2816
     SHA1Context sha1;
2817
+    cli_md5_ctx md5ctx;
2818
+
2819
+    if (flags & CL_CHECKFP_PE_FLAG_STATS)
2820
+        if (!(hashes))
2821
+            return CL_EFORMAT;
2822
+
2823
+    if (flags == CL_CHECKFP_PE_FLAG_NONE)
2824
+        return 0;
2817 2825
 
2818 2826
     if(!(DCONF & PE_CONF_CATALOG))
2819 2827
         return CL_EFORMAT;
... ...
@@ -2903,6 +2912,15 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2903 2903
 
2904 2904
     hdr_size = PESALIGN(hdr_size, falign); /* Aligned headers virtual size */
2905 2905
 
2906
+    if (flags & CL_CHECKFP_PE_FLAG_STATS) {
2907
+        hashes->nsections = nsections;
2908
+        hashes->sections = cli_calloc(nsections, sizeof(struct cli_section_hash));
2909
+        if (!(hashes->sections)) {
2910
+            free(exe_sections);
2911
+            return CL_EMEM;
2912
+        }
2913
+    }
2914
+
2906 2915
     for(i = 0; i < nsections; i++) {
2907 2916
         exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
2908 2917
         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) {
2928 2928
 
2929 2929
     cli_qsort(exe_sections, nsections, sizeof(*exe_sections), sort_sects);
2930 2930
 
2931
-    SHA1Init(&sha1);
2931
+    if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE)
2932
+        SHA1Init(&sha1);
2932 2933
 
2933
-#define hash_chunk(where, size) \
2934
+#define hash_chunk(where, size, isStatAble, section) \
2934 2935
     do { \
2935 2936
         const uint8_t *hptr; \
2936 2937
         if(!(size)) break; \
... ...
@@ -2938,13 +2957,20 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2938 2938
             free(exe_sections); \
2939 2939
             return CL_EFORMAT; \
2940 2940
         } \
2941
-        SHA1Update(&sha1, hptr, size); \
2941
+        if (flags & CL_CHECKFP_PE_FLAG_AUTHENTICODE) \
2942
+            SHA1Update(&sha1, hptr, size); \
2943
+        if (isStatAble && flags & CL_CHECKFP_PE_FLAG_STATS) { \
2944
+            cli_md5_init(&md5ctx); \
2945
+            cli_md5_update(&md5ctx, hptr, size); \
2946
+            cli_md5_final(hashes->sections[section].md5, &md5ctx); \
2947
+            hashes->sections[section].len = size; \
2948
+        } \
2942 2949
     } while(0)
2943 2950
 
2944 2951
     /* MZ to checksum */
2945 2952
     at = 0;
2946 2953
     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));
2947
-    hash_chunk(0, hlen);
2954
+    hash_chunk(0, hlen, 0, 0);
2948 2955
     at = hlen + 4;
2949 2956
 
2950 2957
     /* Checksum to security */
... ...
@@ -2952,7 +2978,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2952 2952
         hlen = offsetof(struct pe_image_optional_hdr64, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr64, CheckSum) - 4;
2953 2953
     else
2954 2954
         hlen = offsetof(struct pe_image_optional_hdr32, DataDirectory[4]) - offsetof(struct pe_image_optional_hdr32, CheckSum) - 4;
2955
-    hash_chunk(at, hlen);
2955
+    hash_chunk(at, hlen, 0, 0);
2956 2956
     at += hlen + 8;
2957 2957
 
2958 2958
     if(at > hdr_size) {
... ...
@@ -2962,7 +2988,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2962 2962
 
2963 2963
     /* Security to End of header */
2964 2964
     hlen = hdr_size - at;
2965
-    hash_chunk(at, hlen);
2965
+    hash_chunk(at, hlen, 0, 0);
2966 2966
 
2967 2967
     /* Sections */
2968 2968
     at = hdr_size;
... ...
@@ -2970,7 +2996,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2970 2970
         if(!exe_sections[i].rsz)
2971 2971
             continue;
2972 2972
 
2973
-        hash_chunk(exe_sections[i].raw, exe_sections[i].rsz);
2973
+        hash_chunk(exe_sections[i].raw, exe_sections[i].rsz, 1, i);
2974 2974
         at += exe_sections[i].rsz;
2975 2975
     }
2976 2976
 
... ...
@@ -2982,7 +3008,7 @@ int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1) {
2982 2982
         }
2983 2983
 
2984 2984
         hlen -= dirs[4].Size;
2985
-        hash_chunk(at, hlen);
2985
+        hash_chunk(at, hlen, 0, 0);
2986 2986
         at += hlen;
2987 2987
     }
2988 2988
     free(exe_sections);
... ...
@@ -160,8 +160,12 @@ struct cli_pe_hook_data {
160 160
 
161 161
 int cli_scanpe(cli_ctx *ctx);
162 162
 
163
+#define CL_CHECKFP_PE_FLAG_NONE             0x00000000
164
+#define CL_CHECKFP_PE_FLAG_STATS            0x00000001
165
+#define CL_CHECKFP_PE_FLAG_AUTHENTICODE     0x00000002
166
+
163 167
 int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo);
164
-int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1);
168
+int cli_checkfp_pe(cli_ctx *ctx, uint8_t *authsha1, stats_section_t *hashes, uint32_t flags);
165 169
 
166 170
 uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t);
167 171
 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 *);
... ...
@@ -31,10 +31,84 @@
31 31
 #include "libclamav/hostid.h"
32 32
 #include "libclamav/www.h"
33 33
 
34
-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);
34
+#define DEBUG_STATS 1
35
+
36
+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);
35 37
 void free_sample(cli_flagged_sample_t *sample);
36 38
 
37
-void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata)
39
+#if DEBUG_STATS
40
+char *get_hash(unsigned char *md5)
41
+{
42
+    char *hash;
43
+    int i;
44
+
45
+    hash = calloc(1, 33);
46
+    if (!(hash))
47
+        return NULL;
48
+
49
+    for (i=0; i<16; i++)
50
+        sprintf(hash+(i*2), "%02x", md5[i]);
51
+
52
+    return hash;
53
+}
54
+
55
+char *get_sample_names(char **names)
56
+{
57
+    char *ret;
58
+    size_t n, i, sz;
59
+
60
+    sz = 0;
61
+    for (n=0; names[n] != NULL; n++)
62
+        sz += strlen(names[n]);
63
+
64
+    ret = calloc(1, sz + n + 1);
65
+    if (!(ret))
66
+        return NULL;
67
+
68
+    for (i=0; names[i] != NULL; i++)
69
+        sprintf(ret+strlen(ret), "%s%s", (i==0) ? "" : " ", names[i]);
70
+
71
+    return ret;
72
+}
73
+
74
+void print_sample(cli_flagged_sample_t *sample)
75
+{
76
+    char *hash, *names;
77
+    size_t i;
78
+
79
+    if (!(sample))
80
+        return;
81
+
82
+    hash = get_hash(sample->md5);
83
+    if (!(hash))
84
+        return;
85
+
86
+    cli_warnmsg("Sample[%s]:\n", hash);
87
+    cli_warnmsg("    * Size: %zu\n", sample->size);
88
+    cli_warnmsg("    * Hits: %u\n", sample->hits);
89
+
90
+    free(hash);
91
+
92
+    names = get_sample_names(sample->virus_name);
93
+    if ((names))
94
+        cli_warnmsg("    * Names: %s\n", names);
95
+
96
+    if (sample->sections && sample->sections->nsections) {
97
+        for (i=0; i < sample->sections->nsections; i++) {
98
+            hash = get_hash(sample->sections->sections[i].md5);
99
+            if ((hash)) {
100
+                cli_warnmsg("    * Section[%zu] (%zu): %s\n", i, sample->sections->sections[i].len, hash);
101
+                free(hash);
102
+            }
103
+        }
104
+    }
105
+
106
+    if ((names))
107
+        free(names);
108
+}
109
+#endif
110
+
111
+void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata)
38 112
 {
39 113
     cli_intel_t *intel;
40 114
     cli_flagged_sample_t *sample;
... ...
@@ -81,7 +155,7 @@ void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size
81 81
     }
82 82
 #endif
83 83
 
84
-    sample = find_sample(intel, virname, md5, size, type);
84
+    sample = find_sample(intel, virname, md5, size, sections);
85 85
     if (!(sample)) {
86 86
         if (!(intel->samples)) {
87 87
             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
136 136
         sample->virus_name[i+1] = NULL;
137 137
 
138 138
         memcpy(sample->md5, md5, sizeof(sample->md5));
139
-        sample->type = type;
140 139
         sample->size = size;
141 140
         intel->nsamples++;
141
+
142
+        if (sections && sections->nsections && !(sample->sections)) {
143
+            /* Copy the section data that has already been allocated. We don't care if calloc fails; just skip copying if it does. */
144
+            sample->sections = calloc(1, sizeof(stats_section_t));
145
+            if ((sample->sections))
146
+                memcpy(sample->sections, sections, sizeof(stats_section_t));
147
+        }
142 148
     }
143 149
 
144 150
     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)
249 249
 #endif
250 250
 
251 251
     for (sample=myintel.samples; sample != NULL; sample = next) {
252
+#if DEBUG_STATS
253
+        print_sample(sample);
254
+#endif
252 255
         next = sample->next;
253 256
 
254 257
         free_sample(sample);
... ...
@@ -261,7 +344,7 @@ void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
261 261
     }
262 262
 }
263 263
 
264
-void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata)
264
+void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
265 265
 {
266 266
     cli_intel_t *intel;
267 267
     cli_flagged_sample_t *sample;
... ...
@@ -279,19 +362,17 @@ void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, s
279 279
     }
280 280
 #endif
281 281
 
282
-    sample = find_sample(intel, virname, md5, size, type);
283
-    if (!(sample))
284
-        return;
285
-
286
-    if (sample->prev)
287
-        sample->prev->next = sample->next;
288
-    if (sample->next)
289
-        sample->next->prev = sample;
290
-    if (sample == intel->samples)
291
-        intel->samples = sample->next;
282
+    while ((sample = find_sample(intel, virname, md5, size, NULL))) {
283
+        if (sample->prev)
284
+            sample->prev->next = sample->next;
285
+        if (sample->next)
286
+            sample->next->prev = sample->prev;
287
+        if (sample == intel->samples)
288
+            intel->samples = sample->next;
292 289
 
293
-    free_sample(sample);
294
-    intel->nsamples--;
290
+        free_sample(sample);
291
+        intel->nsamples--;
292
+    }
295 293
 
296 294
 #ifdef CL_THREAD_SAFE
297 295
     err = pthread_mutex_unlock(&(intel->mutex));
... ...
@@ -301,7 +382,7 @@ void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, s
301 301
 #endif
302 302
 }
303 303
 
304
-void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata)
304
+void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
305 305
 {
306 306
     cli_intel_t *intel;
307 307
     cli_flagged_sample_t *sample;
... ...
@@ -319,15 +400,15 @@ void clamav_stats_decrement_count(const char *virname, const unsigned char *md5,
319 319
     }
320 320
 #endif
321 321
 
322
-    sample = find_sample(intel, virname, md5, size, type);
322
+    sample = find_sample(intel, virname, md5, size, NULL);
323 323
     if (!(sample))
324 324
         return;
325 325
 
326 326
     if (sample->hits == 1) {
327 327
         if ((intel->engine->cb_stats_remove_sample))
328
-            intel->engine->cb_stats_remove_sample(virname, md5, size, type, intel);
328
+            intel->engine->cb_stats_remove_sample(virname, md5, size, intel);
329 329
         else
330
-            clamav_stats_remove_sample(virname, md5, size, type, intel);
330
+            clamav_stats_remove_sample(virname, md5, size, intel);
331 331
 
332 332
         return;
333 333
     }
... ...
@@ -444,14 +525,13 @@ char *clamav_stats_get_hostid(void *cbdata)
444 444
 }
445 445
 #endif
446 446
 
447
-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)
447
+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)
448 448
 {
449 449
     cli_flagged_sample_t *sample;
450 450
     size_t i;
451 451
 
452 452
     for (sample = intel->samples; sample != NULL; sample = sample->next) {
453
-        if (sample->type != type)
454
-            continue;
453
+        int foundSections = 0;
455 454
 
456 455
         if (sample->size != size)
457 456
             continue;
... ...
@@ -462,9 +542,24 @@ static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname
462 462
         if (!(virname))
463 463
             return sample;
464 464
 
465
-        for (i=0; sample->virus_name[i] != NULL; i++)
466
-            if (!strcmp(sample->virus_name[i], virname))
467
-                return sample;
465
+        if ((sections) && (sample->sections)) {
466
+            if (sections->nsections == sample->sections->nsections) {
467
+                for (i=0; i < sections->nsections; i++)
468
+                    if (sections->sections[i].len == sample->sections->sections[i].len)
469
+                        if (memcmp(sections->sections[i].md5, sample->sections->sections[i].md5, sizeof(stats_section_t)))
470
+                            break;
471
+
472
+                if (i == sections->nsections)
473
+                    foundSections = 1;
474
+            }
475
+        } else {
476
+            foundSections = 1;
477
+        }
478
+
479
+        if (foundSections)
480
+            for (i=0; sample->virus_name[i] != NULL; i++)
481
+                if (!strcmp(sample->virus_name[i], virname))
482
+                    return sample;
468 483
     }
469 484
 
470 485
     return NULL;
... ...
@@ -4,11 +4,11 @@
4 4
 #define STATS_HOST "stats.clamav.dev" /* Change this before release! */
5 5
 #define STATS_PORT "8080"
6 6
 
7
-void clamav_stats_add_sample(const char *virname, const unsigned char *md5, uint64_t size, cli_intel_sample_type_t type, void *cbdata);
7
+void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata);
8 8
 void clamav_stats_submit(struct cl_engine *engine, void *cbdata);
9 9
 void clamav_stats_flush(struct cl_engine *engine, void *cbdata);
10
-void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata);
11
-void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, cli_intel_sample_type_t type, void *cbdata);
10
+void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
11
+void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, void *cbdata);
12 12
 size_t clamav_stats_get_num(void *cbdata);
13 13
 size_t clamav_stats_get_size(void *cbdata);
14 14
 char *clamav_stats_get_hostid(void *cbdata);
... ...
@@ -2873,7 +2873,7 @@ static int dumpcerts(const struct optstruct *opts)
2873 2873
     SHA1Update(&sha1, fmptr, sb.st_size);
2874 2874
     SHA1Final(&sha1, shash1);
2875 2875
 
2876
-    ret = cli_checkfp_pe(&ctx, shash1);
2876
+    ret = cli_checkfp_pe(&ctx, shash1, NULL, CL_CHECKFP_PE_FLAG_AUTHENTICODE);
2877 2877
     
2878 2878
     switch(ret) {
2879 2879
         case CL_CLEAN: