Browse code

Making the GIF parser more tolerant and supporting GIF overlays

Aldo Mazzeo authored on 2017/03/04 08:08:03
Showing 11 changed files
... ...
@@ -538,6 +538,8 @@ libclamav_la_SOURCES = \
538 538
 	hfsplus.h \
539 539
 	swf.c \
540 540
 	swf.h \
541
+	gif.c \
542
+	gif.h \
541 543
 	jpeg.c \
542 544
 	jpeg.h \
543 545
 	png.c \
... ...
@@ -309,8 +309,8 @@ am__libclamav_la_SOURCES_DIST = matcher-ac.c matcher-ac.h matcher-bm.c \
309 309
 	prtn_intxn.h json_api.c json_api.h xz_iface.c xz_iface.h \
310 310
 	sf_base64decode.c sf_base64decode.h hfsplus.c hfsplus.h swf.c \
311 311
 	swf.h jpeg.c jpeg.h png.c png.h iso9660.c iso9660.h arc4.c \
312
-	arc4.h rijndael.c rijndael.h crtmgr.c crtmgr.h asn1.c asn1.h \
313
-	fpu.c fpu.h stats.c stats.h www.c www.h stats_json.c \
312
+	gif.c gif.h arc4.h rijndael.c rijndael.h crtmgr.c crtmgr.h \
313
+	asn1.c asn1.h fpu.c fpu.h stats.c stats.h www.c www.h stats_json.c \
314 314
 	stats_json.h hostid.c hostid.h openioc.c openioc.h msdoc.c \
315 315
 	msdoc.h matcher-pcre.c matcher-pcre.h regex_pcre.c \
316 316
 	regex_pcre.h msxml.c msxml.h msxml_parser.c msxml_parser.h \
... ...
@@ -450,8 +450,8 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
450 450
 	libclamav_la-apm.lo libclamav_la-prtn_intxn.lo \
451 451
 	libclamav_la-json_api.lo libclamav_la-xz_iface.lo \
452 452
 	libclamav_la-sf_base64decode.lo libclamav_la-hfsplus.lo \
453
-	libclamav_la-swf.lo libclamav_la-jpeg.lo libclamav_la-png.lo \
454
-	libclamav_la-iso9660.lo libclamav_la-arc4.lo \
453
+	libclamav_la-swf.lo libclamav_la-gif.lo libclamav_la-jpeg.lo \
454
+	libclamav_la-png.lo libclamav_la-iso9660.lo libclamav_la-arc4.lo \
455 455
 	libclamav_la-rijndael.lo libclamav_la-crtmgr.lo \
456 456
 	libclamav_la-asn1.lo libclamav_la-fpu.lo libclamav_la-stats.lo \
457 457
 	libclamav_la-www.lo libclamav_la-stats_json.lo \
... ...
@@ -1382,7 +1382,7 @@ libclamav_la_SOURCES = matcher-ac.c matcher-ac.h matcher-bm.c \
1382 1382
 	xar.c xar.h xdp.c xdp.h mbr.c mbr.h gpt.c gpt.h apm.c apm.h \
1383 1383
 	prtn_intxn.c prtn_intxn.h json_api.c json_api.h xz_iface.c \
1384 1384
 	xz_iface.h sf_base64decode.c sf_base64decode.h hfsplus.c \
1385
-	hfsplus.h swf.c swf.h jpeg.c jpeg.h png.c png.h iso9660.c \
1385
+	hfsplus.h swf.c swf.h gif.c gif.h jpeg.c jpeg.h png.c png.h iso9660.c \
1386 1386
 	iso9660.h arc4.c arc4.h rijndael.c rijndael.h crtmgr.c \
1387 1387
 	crtmgr.h asn1.c asn1.h fpu.c fpu.h stats.c stats.h www.c www.h \
1388 1388
 	stats_json.c stats_json.h hostid.c hostid.h openioc.c \
... ...
@@ -1731,6 +1731,7 @@ distclean-compile:
1731 1731
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-fp_unsigned_bin_size.Plo@am__quote@
1732 1732
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-fpu.Plo@am__quote@
1733 1733
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-fsg.Plo@am__quote@
1734
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-gif.Plo@am__quote@
1734 1735
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-gpt.Plo@am__quote@
1735 1736
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-hashtab.Plo@am__quote@
1736 1737
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-hfsplus.Plo@am__quote@
... ...
@@ -2793,6 +2794,13 @@ libclamav_la-swf.lo: swf.c
2793 2793
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2794 2794
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-swf.lo `test -f 'swf.c' || echo '$(srcdir)/'`swf.c
2795 2795
 
2796
+libclamav_la-gif.lo: gif.c
2797
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-gif.lo -MD -MP -MF $(DEPDIR)/libclamav_la-gif.Tpo -c -o libclamav_la-gif.lo `test -f 'gif.c' || echo '$(srcdir)/'`gif.c
2798
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-gif.Tpo $(DEPDIR)/libclamav_la-gif.Plo
2799
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gif.c' object='libclamav_la-gif.lo' libtool=yes @AMDEPBACKSLASH@
2800
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2801
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-gif.lo `test -f 'gif.c' || echo '$(srcdir)/'`gif.c
2802
+
2796 2803
 libclamav_la-jpeg.lo: jpeg.c
2797 2804
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-jpeg.lo -MD -MP -MF $(DEPDIR)/libclamav_la-jpeg.Tpo -c -o libclamav_la-jpeg.lo `test -f 'jpeg.c' || echo '$(srcdir)/'`jpeg.c
2798 2805
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-jpeg.Tpo $(DEPDIR)/libclamav_la-jpeg.Plo
... ...
@@ -84,6 +84,7 @@ static const struct ftmap_s {
84 84
     { "CL_TYPE_SIS",          CL_TYPE_SIS          },
85 85
     { "CL_TYPE_SCRENC",       CL_TYPE_SCRENC       },
86 86
     { "CL_TYPE_GRAPHICS",     CL_TYPE_GRAPHICS     },
87
+    { "CL_TYPE_GIF",	    CL_TYPE_GIF         },
87 88
     { "CL_TYPE_RIFF",         CL_TYPE_RIFF         },
88 89
     { "CL_TYPE_BINHEX",       CL_TYPE_BINHEX       },
89 90
     { "CL_TYPE_TNEF",         CL_TYPE_TNEF         },
... ...
@@ -66,6 +66,7 @@ typedef enum cli_file {
66 66
     CL_TYPE_SIS,
67 67
     CL_TYPE_SCRENC,
68 68
     CL_TYPE_GRAPHICS,
69
+    CL_TYPE_GIF,
69 70
     CL_TYPE_RIFF,
70 71
     CL_TYPE_BINHEX,
71 72
     CL_TYPE_TNEF,
... ...
@@ -54,7 +54,7 @@ static const char *ftypes_int[] = {
54 54
     "0:0:466f723a20:Eserv mail:CL_TYPE_ANY:CL_TYPE_MAIL",
55 55
     "0:0:46726f6d20:MBox:CL_TYPE_ANY:CL_TYPE_MAIL",
56 56
     "0:0:46726f6d3a20:Exim mail:CL_TYPE_ANY:CL_TYPE_MAIL",
57
-    "0:0:474946:GIF:CL_TYPE_ANY:CL_TYPE_GRAPHICS",
57
+  "0:0:474946:GIF:CL_TYPE_ANY:CL_TYPE_GIF",
58 58
     "0:0:48692e20546869732069732074686520716d61696c2d73656e64:Qmail bounce:CL_TYPE_ANY:CL_TYPE_MAIL",
59 59
     "0:0:494433:MP3:CL_TYPE_ANY:CL_TYPE_IGNORED",
60 60
     "0:0:49545346:MS CHM:CL_TYPE_ANY:CL_TYPE_MSCHM",
61 61
new file mode 100644
... ...
@@ -0,0 +1,166 @@
0
+/*
1
+*  Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
2
+*  Copyright (C) 2011 Sourcefire, Inc.
3
+*
4
+*  Authors: Tomasz Kojm <tkojm@clamav.net>
5
+*
6
+*  This program is free software; you can redistribute it and/or modify
7
+*  it under the terms of the GNU General Public License version 2 as
8
+*  published by the Free Software Foundation.
9
+*
10
+*  This program is distributed in the hope that it will be useful,
11
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+*  GNU General Public License for more details.
14
+*
15
+*  You should have received a copy of the GNU General Public License
16
+*  along with this program; if not, write to the Free Software
17
+*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
+*  MA 02110-1301, USA.
19
+*/
20
+
21
+#if HAVE_CONFIG_H
22
+#include "clamav-config.h"
23
+#endif
24
+
25
+#include "gif.h"
26
+#include "scanners.h"
27
+#include "clamav.h"
28
+
29
+#ifndef HAVE_ATTRIB_PACKED
30
+#define __attribute__(x)
31
+#endif
32
+#ifdef HAVE_PRAGMA_PACK
33
+#pragma pack(1)
34
+#endif
35
+#ifdef HAVE_PRAGMA_PACK_HPPA
36
+#pragma pack 1
37
+#endif
38
+
39
+struct gif_screen_desc {
40
+    uint16_t width;
41
+    uint16_t height;
42
+    uint8_t flags;
43
+    uint8_t bgcolor;
44
+    uint8_t aspect;
45
+} __attribute__((packed));
46
+
47
+struct gif_graphic_control_ext {
48
+    uint8_t blksize;
49
+    uint8_t flags;
50
+    uint16_t delaytime;
51
+    uint8_t tcoloridx;
52
+    uint8_t blkterm;
53
+} __attribute__((packed));
54
+
55
+struct gif_image_desc {
56
+    uint16_t leftpos;
57
+    uint16_t toppos;
58
+    uint16_t width;
59
+    uint16_t height;
60
+    uint8_t flags;
61
+} __attribute__((packed));
62
+
63
+#ifdef HAVE_PRAGMA_PACK
64
+#pragma pack()
65
+#endif
66
+#ifdef HAVE_PRAGMA_PACK_HPPA
67
+#pragma pack
68
+#endif
69
+
70
+#define EC16(x) le16_to_host(x)
71
+
72
+#define GETDATA(v)                                                  \
73
+    {                                                               \
74
+    if(fmap_readn(map, &v, offset, sizeof(v)) == sizeof(v)) {       \
75
+	    offset += sizeof(v);                                        \
76
+    } else {                                                        \
77
+	    cli_errmsg("cli_parsegif: Can't read file (truncated?)\n"); \
78
+	    return CL_EPARSE;                                           \
79
+    }                                                               \
80
+    }
81
+
82
+int cli_parsegif(cli_ctx *ctx)
83
+{
84
+    fmap_t *map = *ctx->fmap;
85
+    unsigned char v = 0;
86
+    unsigned int offset = 6;
87
+    struct gif_screen_desc screen_desc;
88
+    struct gif_image_desc image_desc;
89
+    int retVal = CL_SUCCESS;
90
+
91
+    cli_dbgmsg("in cli_parsegif()\n");
92
+
93
+    GETDATA(screen_desc);
94
+    cli_dbgmsg("GIF: Screen size %ux%u, gctsize: %u\n", EC16(screen_desc.width), EC16(screen_desc.height), screen_desc.flags & 0x7);
95
+    if (screen_desc.flags & 0x80)
96
+        offset += 3 * (1 << ((screen_desc.flags & 0x7) + 1));
97
+
98
+    while (1) {
99
+        GETDATA(v);
100
+        if (v == 0x21) {
101
+            GETDATA(v);
102
+            if (v == 0xf9) {
103
+                offset += sizeof(struct gif_graphic_control_ext);
104
+            }
105
+            else {
106
+                while (1) {
107
+                    GETDATA(v);
108
+                    if (!v)
109
+                        break;
110
+
111
+                    if (offset + v > map->len)
112
+                    {
113
+                        retVal = CL_EPARSE;
114
+                        goto scan_overlay;
115
+                    }
116
+                    offset += v;
117
+                }
118
+            }
119
+        }
120
+        else if (v == 0x2c) {
121
+            GETDATA(image_desc);
122
+            cli_dbgmsg("GIF: Image size %ux%u, left pos: %u, top pos: %u\n", EC16(image_desc.width), EC16(image_desc.height), EC16(image_desc.leftpos), EC16(image_desc.toppos));
123
+
124
+            offset++;
125
+            if (image_desc.flags & 0x80)
126
+                offset += 3 * (1 << ((image_desc.flags & 0x7) + 1));
127
+
128
+            while (1) {
129
+                GETDATA(v);
130
+                if (!v)
131
+                    break;
132
+
133
+                if (offset + v > map->len)
134
+                {
135
+                    retVal = CL_EPARSE;
136
+                    goto scan_overlay;
137
+                }
138
+                offset += v;
139
+            }
140
+        }
141
+        else if (v == 0x3b) {
142
+            break;
143
+        }
144
+        else {
145
+            // An unknown code: break.
146
+            retVal = CL_EPARSE;
147
+            goto scan_overlay;
148
+        }
149
+    }
150
+
151
+scan_overlay:
152
+    // Some recovery (I saw some "GIF89a;" or things like this)
153
+    if (retVal == CL_EPARSE &&
154
+        offset == (6 + sizeof(screen_desc) + 1))
155
+        offset = 6;
156
+
157
+    // Is there an overlay?
158
+    if (offset < map->len)
159
+    {
160
+        int recRetVal = cli_map_scan(map, offset, map->len - offset, ctx, CL_TYPE_ANY);
161
+        retVal = recRetVal != CL_SUCCESS ? recRetVal : retVal;
162
+    }
163
+
164
+    return retVal;
165
+}
0 166
\ No newline at end of file
1 167
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+/*
1
+ *  Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
2
+ *  Copyright (C) 2011 Sourcefire, Inc.
3
+ *
4
+ *  Authors: Tomasz Kojm <tkojm@clamav.net>
5
+ *
6
+ *  This program is free software; you can redistribute it and/or modify
7
+ *  it under the terms of the GNU General Public License version 2 as
8
+ *  published by the Free Software Foundation.
9
+ *
10
+ *  This program is distributed in the hope that it will be useful,
11
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ *  GNU General Public License for more details.
14
+ *
15
+ *  You should have received a copy of the GNU General Public License
16
+ *  along with this program; if not, write to the Free Software
17
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
+ *  MA 02110-1301, USA.
19
+ */
20
+
21
+#ifndef __GIF_H
22
+#define __GIF_H
23
+
24
+#include "others.h"
25
+
26
+int cli_parsegif(cli_ctx *ctx);
27
+
28
+#endif
... ...
@@ -37,13 +37,11 @@
37 37
 #include "jpeg.h"
38 38
 #include "clamav.h"
39 39
 
40
-#define EC16(x) le16_to_host(x)
41
-
42 40
 #define GETBYTE(v)                                                         \
43 41
     if (fmap_readn(map, &v, offset, sizeof(v)) == sizeof(v)) {             \
44 42
         offset += sizeof(v);                                               \
45 43
     } else {                                                               \
46
-        cli_errmsg("cli_parse(jpeg|gif): Can't read file (corrupted?)\n"); \
44
+	cli_errmsg("cli_parsejpeg: Can't read file (corrupted?)\n");	\
47 45
         return CL_EPARSE;                                                  \
48 46
     }
49 47
 
... ...
@@ -204,99 +202,3 @@ int cli_parsejpeg(cli_ctx *ctx)
204 204
     }
205 205
     return CL_SUCCESS;
206 206
 }
207
-
208
-/* GIF */
209
-
210
-struct gif_screen_desc {
211
-    uint16_t width;
212
-    uint16_t height;
213
-    uint8_t flags;
214
-    uint8_t bgcolor;
215
-    uint8_t aspect;
216
-};
217
-
218
-struct gif_graphic_control_ext {
219
-    uint8_t blksize;
220
-    uint8_t flags;
221
-    uint16_t delaytime;
222
-    uint8_t tcoloridx;
223
-    uint8_t blkterm;
224
-};
225
-
226
-struct gif_image_desc {
227
-    uint16_t leftpos;
228
-    uint16_t toppos;
229
-    uint16_t width;
230
-    uint16_t height;
231
-    uint8_t flags;
232
-};
233
-
234
-int cli_parsegif(cli_ctx *ctx)
235
-{
236
-    fmap_t *map = *ctx->fmap;
237
-    unsigned char magic[6], v;
238
-    unsigned int offset = 0, have_gce = 0;
239
-    struct gif_screen_desc screen_desc;
240
-    struct gif_graphic_control_ext graphic_control_ext;
241
-    struct gif_image_desc image_desc;
242
-
243
-    cli_dbgmsg("in cli_parsegif()\n");
244
-
245
-    if (fmap_readn(map, magic, offset, 6) != 6)
246
-        return CL_SUCCESS; /* Ignore */
247
-
248
-    if (!memcmp(magic, "GIF87a", 6) || !memcmp(magic, "GIF89a", 6))
249
-        offset = 6;
250
-    else
251
-        return CL_SUCCESS; /* Not a GIF file */
252
-
253
-    if (fmap_readn(map, &screen_desc, offset, sizeof(screen_desc)) != sizeof(screen_desc)) {
254
-        cli_warnmsg("cli_parsegif: Can't read Logical Screen Descriptor block\n");
255
-        return CL_EPARSE;
256
-    }
257
-    offset += 7;
258
-
259
-    cli_dbgmsg("GIF: Screen size %ux%u, gctsize: %u\n", EC16(screen_desc.width), EC16(screen_desc.height), screen_desc.flags & 0x7);
260
-    if (screen_desc.flags & 0x80)
261
-        offset += 3 * (1 << ((screen_desc.flags & 0x7) + 1));
262
-
263
-    while (1) {
264
-        GETBYTE(v);
265
-        if (v == 0x21) {
266
-            GETBYTE(v);
267
-            if (v == 0xf9) {
268
-                if (fmap_readn(map, &graphic_control_ext, offset, sizeof(graphic_control_ext)) != sizeof(graphic_control_ext)) {
269
-                    cli_warnmsg("cli_parsegif: Can't read Graphic Control Extension block\n");
270
-                    return CL_EPARSE;
271
-                }
272
-                if (have_gce) {
273
-                    cli_warnmsg("cli_parsegif: Multiple Graphic Control Extension blocks not allowed\n");
274
-                    return CL_EPARSE;
275
-                }
276
-                have_gce = 1;
277
-                offset += sizeof(graphic_control_ext);
278
-                if (graphic_control_ext.blksize != 4 || graphic_control_ext.blkterm) {
279
-                    cli_warnmsg("cli_parsegif: Invalid Graphic Control Extension block\n");
280
-                    return CL_EPARSE;
281
-                }
282
-            } else {
283
-                while (1) {
284
-                    GETBYTE(v);
285
-                    if (!v)
286
-                        break;
287
-                    offset += v;
288
-                }
289
-            }
290
-        } else if (v == 0x2c) {
291
-            if (fmap_readn(map, &image_desc, offset, sizeof(image_desc)) != sizeof(image_desc)) {
292
-                cli_warnmsg("cli_parsegif: Can't read Image Descriptor block\n");
293
-                return CL_EPARSE;
294
-            }
295
-            offset += 9;
296
-            cli_dbgmsg("GIF: Image size %ux%u, left pos: %u, top pos: %u\n", EC16(image_desc.width), EC16(image_desc.height), EC16(image_desc.leftpos), EC16(image_desc.toppos));
297
-            break;
298
-        }
299
-    }
300
-
301
-    return CL_SUCCESS;
302
-}
... ...
@@ -25,6 +25,5 @@
25 25
 #include "others.h"
26 26
 
27 27
 int cli_parsejpeg(cli_ctx *ctx);
28
-int cli_parsegif(cli_ctx *ctx);
29 28
 
30 29
 #endif
... ...
@@ -93,6 +93,7 @@
93 93
 #include "events.h"
94 94
 #include "swf.h"
95 95
 #include "jpeg.h"
96
+#include "gif.h"
96 97
 #include "png.h"
97 98
 #include "iso9660.h"
98 99
 #include "dmg.h"
... ...
@@ -3809,6 +3810,11 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
3809 3809
 
3810 3810
             break;
3811 3811
 
3812
+    case CL_TYPE_GIF:
3813
+        if(SCAN_HEURISTICS)
3814
+            ret = cli_parsegif(ctx);
3815
+        break;
3816
+
3812 3817
         case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */
3813 3818
             if (SCAN_PARSE_PDF && (DCONF_DOC & DOC_CONF_PDF))
3814 3819
                 ret = cli_scanpdf(ctx, 0);
... ...
@@ -333,6 +333,7 @@
333 333
     <ClCompile Include="..\libclamav\filtering.c" />
334 334
     <ClCompile Include="..\libclamav\fmap.c" />
335 335
     <ClCompile Include="..\libclamav\fsg.c" />
336
+    <ClCompile Include="..\libclamav\gif.c" />
336 337
     <ClCompile Include="..\libclamav\gpt.c" />
337 338
     <ClCompile Include="..\libclamav\hashtab.c" />
338 339
     <ClCompile Include="..\libclamav\hfsplus.c" />