Browse code

support files compressed with compress.exe

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@535 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2004/05/02 09:51:01
Showing 10 changed files
... ...
@@ -1,10 +1,14 @@
1
+Sun May  2 02:48:04 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav: support files compressed with compress.exe (test/test1.msc)
4
+
1 5
 Sat May  1 21:29:29 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * clamd: stream scanner:
4 8
 	+ scan exactly up to StreamMaxLength (patch by Joe Maimon
5 9
 	  <jmaimon*ttec.com>)
6 10
 	+ fix description leak on ReadTimeout (patch by Maxim Dounin
7
-	  <mdounin@rambler-co.ru>)
11
+	  <mdounin*rambler-co.ru>)
8 12
   * contrib/trashscan: v. 0.12 (Trashware <trashware*gmx.de>)
9 13
   * libclamav: in block-encrypted mode scan a raw encrypted archive before
10 14
 	       marking it as encrypted (requested by Andy Fiddaman
... ...
@@ -32,7 +36,7 @@ Wed Apr 28 15:29:29 BST 2004 (njh)
32 32
 			Send 554 after DATA received, not 550
33 33
 			Don't send rejection notices to rejection notices, we
34 34
 				just end up playing ping-pong (patch by "Andrey
35
-				J.Melnikoff (TEMHOTA)" <temnota@kmv.ru>
35
+				J.Melnikoff (TEMHOTA)" <temnota*kmv.ru>
36 36
 			If CL_DEBUG is defined, don't redirect stdout/stderr
37 37
 			Don't attempt to return an old signature if no
38 38
 				filename has been given. There has never been
... ...
@@ -79,6 +79,8 @@ libclamav_la_SOURCES = \
79 79
 	ole2_extract.h \
80 80
 	vba_extract.c \
81 81
 	vba_extract.h \
82
-	cltypes.h
82
+	cltypes.h \
83
+	msexpand.c \
84
+	msexpand.h
83 85
 
84 86
 lib_LTLIBRARIES = libclamav.la
... ...
@@ -179,7 +179,9 @@ libclamav_la_SOURCES = \
179 179
 	ole2_extract.h \
180 180
 	vba_extract.c \
181 181
 	vba_extract.h \
182
-	cltypes.h
182
+	cltypes.h \
183
+	msexpand.c \
184
+	msexpand.h
183 185
 
184 186
 
185 187
 lib_LTLIBRARIES = libclamav.la
... ...
@@ -194,7 +196,7 @@ am_libclamav_la_OBJECTS = matcher.lo md5.lo others.lo readdb.lo cvd.lo \
194 194
 	dsig.lo str.lo scanners.lo unrarlib.lo zzip-dir.lo zzip-err.lo \
195 195
 	zzip-file.lo zzip-info.lo zzip-io.lo zzip-stat.lo zzip-zip.lo \
196 196
 	strc.lo blob.lo mbox.lo message.lo snprintf.lo strrcpy.lo \
197
-	table.lo text.lo ole2_extract.lo vba_extract.lo
197
+	table.lo text.lo ole2_extract.lo vba_extract.lo msexpand.lo
198 198
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
199 199
 
200 200
 DEFS = @DEFS@
... ...
@@ -207,7 +209,7 @@ am__depfiles_maybe = depfiles
207 207
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/blob.Plo ./$(DEPDIR)/cvd.Plo \
208 208
 @AMDEP_TRUE@	./$(DEPDIR)/dsig.Plo ./$(DEPDIR)/matcher.Plo \
209 209
 @AMDEP_TRUE@	./$(DEPDIR)/mbox.Plo ./$(DEPDIR)/md5.Plo \
210
-@AMDEP_TRUE@	./$(DEPDIR)/message.Plo \
210
+@AMDEP_TRUE@	./$(DEPDIR)/message.Plo ./$(DEPDIR)/msexpand.Plo \
211 211
 @AMDEP_TRUE@	./$(DEPDIR)/ole2_extract.Plo ./$(DEPDIR)/others.Plo \
212 212
 @AMDEP_TRUE@	./$(DEPDIR)/readdb.Plo ./$(DEPDIR)/scanners.Plo \
213 213
 @AMDEP_TRUE@	./$(DEPDIR)/snprintf.Plo ./$(DEPDIR)/str.Plo \
... ...
@@ -288,6 +290,7 @@ distclean-compile:
288 288
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbox.Plo@am__quote@
289 289
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
290 290
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@
291
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msexpand.Plo@am__quote@
291 292
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ole2_extract.Plo@am__quote@
292 293
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Plo@am__quote@
293 294
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdb.Plo@am__quote@
... ...
@@ -47,6 +47,7 @@ extern "C"
47 47
 #define CL_EGZIP	103 /* gzip handler error */
48 48
 #define CL_EBZIP	104 /* bzip2 handler error */
49 49
 #define CL_EOLE2	105 /* OLE2 handler error */
50
+#define CL_EMSCOMP	106 /* compress.exe handler error */
50 51
 #define CL_EACCES	200 /* access denied */
51 52
 #define CL_ENULLARG	300 /* null argument error */
52 53
 
53 54
new file mode 100644
... ...
@@ -0,0 +1,158 @@
0
+/*
1
+ *  msexpand: Microsoft "compress.exe/expand.exe" compatible decompressor
2
+ *
3
+ *  Copyright (c) 2000 Martin Hinner <mhi@penguin.cz>
4
+ *  Algorithm & data structures by M. Winterhoff <100326.2776@compuserve.com>
5
+ *
6
+ *  Corrected and adapted to ClamAV by Tomasz Kojm <tkojm@clamav.net>
7
+ *
8
+ *  This program is free software; you can redistribute it and/or modify
9
+ *  it under the terms of the GNU General Public License as published by
10
+ *  the Free Software Foundation; either version 2, or (at your option)
11
+ *  any later version.
12
+ *
13
+ *  This program is distributed in the hope that it will be useful,
14
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ *  GNU General Public License for more details.
17
+ *
18
+ *  You should have received a copy of the GNU General Public License
19
+ *  along with this program; if not, write to the Free Software
20
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
+ */
22
+
23
+#include <stdio.h>
24
+#include <stdlib.h>
25
+#include <unistd.h>
26
+#include <string.h>
27
+
28
+#if HAVE_CONFIG_H
29
+#include "clamav-config.h"
30
+#endif
31
+#include "cltypes.h"
32
+#include "others.h"
33
+
34
+int cli_msexpand(FILE *in, FILE *out)
35
+{
36
+	int bits, ch, i, j, len, mask;
37
+	unsigned char *buffer;
38
+	uint32_t magic1, magic2, magic3, filesize;
39
+	uint16_t reserved;
40
+
41
+
42
+    if(fread(&magic1, sizeof(magic1), 1, in) != 1) {
43
+	return -1;
44
+    }
45
+
46
+#if WORDS_BIGENDIAN == 1
47
+    if(magic1 == 0x535A4444L)
48
+#else
49
+    if(magic1 == 0x44445A53L)
50
+#endif
51
+    {
52
+	if(fread(&magic2, sizeof(magic2), 1, in) != 1) {
53
+	    return -1;
54
+	}
55
+
56
+	if(fread(&reserved, sizeof(reserved), 1, in) != 1) {
57
+	    return -1;
58
+	}
59
+
60
+	if(fread(&filesize, sizeof(filesize), 1, in) != 1) {
61
+	    return -1;
62
+	}
63
+
64
+#if WORDS_BIGENDIAN == 1
65
+	if(magic2 != 0x88F02733L)
66
+#else
67
+	if(magic2 != 0x3327F088L)
68
+#endif
69
+	{
70
+	    cli_warnmsg("msexpand: Not a MS-compressed file\n");
71
+	    return -1;
72
+	}
73
+
74
+    } else
75
+#if WORDS_BIGENDIAN == 1
76
+    if(magic1 == 0x4B57414AL)
77
+#else
78
+    if(magic1 == 0x4A41574BL)
79
+#endif
80
+    {
81
+	if(fread(&magic2, sizeof(magic2), 1, in) != 1) {
82
+	    return -1;
83
+	}
84
+
85
+	if(fread(&magic3, sizeof(magic3), 1, in) != 1) {
86
+	    return -1;
87
+	}
88
+
89
+	if(fread(&reserved, sizeof(reserved), 1, in) != 1) {
90
+	    return -1;
91
+	}
92
+
93
+#if WORDS_BIGENDIAN == 1
94
+	if(magic2 != 0x88F027D1L || magic3 != 0x03001200L)
95
+#else
96
+	if(magic2 != 0xD127F088L || magic3 != 0x00120003L)
97
+#endif
98
+	{
99
+	    cli_warnmsg("msexpand: Not a MS-compressed file\n");
100
+	    return -1;
101
+	}
102
+
103
+	cli_warnmsg("msexpand: unsupported version 6.22\n");
104
+	return -1;
105
+
106
+    } else {
107
+	cli_warnmsg("msexpand: Not a MS-compressed file\n");
108
+	return -1;
109
+    }
110
+
111
+    if((buffer = (unsigned char *) cli_calloc(4096, sizeof(char))) == NULL) {
112
+	cli_errmsg("msexpand: Can't allocate memory\n");
113
+	return -1;
114
+    }
115
+
116
+    i = 4096 - 16;
117
+
118
+    while (1) {
119
+	if((bits = fgetc(in)) == EOF)
120
+	    break;
121
+
122
+	for(mask = 0x01; mask & 0xFF; mask <<= 1) {
123
+	    if(!(bits & mask)) {
124
+		if((j = fgetc(in)) == EOF)
125
+		    break;
126
+		len = fgetc(in);
127
+		j += (len & 0xF0) << 4;
128
+		len = (len & 15) + 3;
129
+		while(len--) {
130
+		    buffer[i] = buffer[j];
131
+		    if(fwrite(&buffer[i], sizeof(unsigned char), 1, out) != 1) {
132
+			free(buffer);
133
+			return -1;
134
+		    }
135
+		    j++;
136
+		    j %= 4096;
137
+		    i++;
138
+		    i %= 4096;
139
+		}
140
+	    } else {
141
+		if((ch = fgetc(in)) == EOF)
142
+		    break;
143
+
144
+		buffer[i] = ch;
145
+		if(fwrite(&buffer[i], sizeof(unsigned char), 1, out) != 1) {
146
+		    free(buffer);
147
+		    return -1;
148
+		}
149
+		i++;
150
+		i %= 4096;
151
+	    }
152
+	}
153
+    }
154
+
155
+    free(buffer);
156
+    return 0;
157
+}
0 158
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+/*
1
+ *  Copyright (C) 2004 Tomasz Kojm <tkojm@clamav.net>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License as published by
5
+ *  the Free Software Foundation; either version 2 of the License, or
6
+ *  (at your option) any later version.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
+ */
17
+
18
+#ifndef __MSEXPAND_H
19
+#define __MSEXPAND_H
20
+
21
+#include <stdio.h>
22
+
23
+int cli_msexpand(FILE *in, FILE *out);
24
+
25
+#endif
... ...
@@ -120,6 +120,8 @@ const char *cl_strerror(int clerror)
120 120
 	    return "Malformed Zip detected.";
121 121
 	case CL_EGZIP:
122 122
 	    return "GZip module failure.";
123
+	case CL_EMSCOMP:
124
+	    return "MSExpand module failure.";
123 125
 	case CL_EOLE2:
124 126
 	    return "OLE2 module failure.";
125 127
 	case CL_ETMPFILE:
... ...
@@ -42,6 +42,7 @@ int cli_scanrar_inuse = 0;
42 42
 #include "unrarlib.h"
43 43
 #include "ole2_extract.h"
44 44
 #include "vba_extract.h"
45
+#include "msexpand.h"
45 46
 #include "scanners.h"
46 47
 
47 48
 #ifdef HAVE_ZLIB_H
... ...
@@ -76,6 +77,7 @@ static const struct cli_magic_s cli_magic[] = {
76 76
     {0,  "PK\003\004",			4,  "ZIP",		  CL_ZIPFILE},
77 77
     {0,  "\037\213",			2,  "GZip",		  CL_GZFILE},
78 78
     {0,  "BZh",				3,  "BZip",		  CL_BZFILE},
79
+    {0,  "SZDD",			4,  "compress.exe'd",	  CL_MSCFILE},
79 80
 
80 81
     /* Mail */
81 82
 
... ...
@@ -659,6 +661,48 @@ static int cli_scanbzip(int desc, const char **virname, long int *scanned, const
659 659
 }
660 660
 #endif
661 661
 
662
+static int cli_scanmscomp(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev)
663
+{
664
+	int fd, ret = CL_CLEAN;
665
+	FILE *tmp = NULL, *in;
666
+
667
+    cli_dbgmsg("in cli_scanmscomp()\n");
668
+
669
+    if((in = fdopen(dup(desc), "rb")) == NULL) {
670
+	cli_dbgmsg("Can't fdopen() descriptor %d.\n", desc);
671
+	return CL_EMSCOMP;
672
+    }
673
+
674
+    if((tmp = tmpfile()) == NULL) {
675
+	cli_dbgmsg("Can't generate tmpfile().\n");
676
+	fclose(in);
677
+	return CL_ETMPFILE;
678
+    }
679
+
680
+    if(cli_msexpand(in, tmp) == -1) {
681
+	cli_dbgmsg("msexpand failed.\n");
682
+	return CL_EMSCOMP;
683
+    }
684
+
685
+    fclose(in);
686
+    if(fflush(tmp)) {
687
+	cli_dbgmsg("fflush() failed\n");
688
+	fclose(tmp);
689
+	return CL_EFSYNC;
690
+    }
691
+
692
+    fd = fileno(tmp);
693
+    lseek(fd, 0, SEEK_SET);
694
+    if((ret = cli_magic_scandesc(fd, virname, scanned, root, limits, options, reclev)) == CL_VIRUS) {
695
+	cli_dbgmsg("MSCompress -> Found %s virus.\n", *virname);
696
+	fclose(tmp);
697
+	return CL_VIRUS;
698
+    }
699
+
700
+    fclose(tmp);
701
+    return ret;
702
+}
703
+
662 704
 static int cli_scandir(const char *dirname, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev)
663 705
 {
664 706
 	DIR *dd;
... ...
@@ -927,6 +971,11 @@ static int cli_magic_scandesc(int desc, const char **virname, long int *scanned,
927 927
 #endif
928 928
 	    break;
929 929
 
930
+	case CL_MSCFILE:
931
+	    if(SCAN_ARCHIVE)
932
+		ret = cli_scanmscomp(desc, virname, scanned, root, limits, options, reclev);
933
+	    break;
934
+
930 935
 	case CL_MAILFILE:
931 936
 	    if(SCAN_MAIL)
932 937
 		ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
... ...
@@ -28,6 +28,7 @@ typedef enum {
28 28
     CL_ZIPFILE,
29 29
     CL_BZFILE,
30 30
     CL_RARFILE,
31
+    CL_MSCFILE,
31 32
     CL_OLE2FILE
32 33
 } cli_file_t;
33 34
 
34 35
new file mode 100644
35 36
Binary files /dev/null and b/test/test1.msc differ