Browse code

inital support for SIS files

git-svn: trunk@1785

Tomasz Kojm authored on 2005/12/15 11:02:29
Showing 8 changed files
... ...
@@ -1,3 +1,8 @@
1
+Thu Dec 15 02:52:01 CET 2005 (tk)
2
+---------------------------------
3
+  * libclamav/sis.[ch]: new files
4
+  * libclamav: inital support for SIS files (Symbian OS packages)
5
+
1 6
 Mon Dec 12 19:34:00 CET 2005 (tk)
2 7
 ---------------------------------
3 8
   * libclamav: add support for CL_SCAN_ALGO (to control algorithmic detection)
... ...
@@ -143,7 +143,9 @@ libclamav_la_SOURCES = \
143 143
 	spin.h \
144 144
 	elf.c \
145 145
 	elf.h \
146
-	execs.h
146
+	execs.h \
147
+	sis.c \
148
+	sis.h
147 149
 
148 150
 
149 151
 lib_LTLIBRARIES = libclamav.la
... ...
@@ -86,7 +86,7 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \
86 86
 	chmunpack.lo rebuildpe.lo petite.lo fsg.lo line.lo untar.lo \
87 87
 	special.lo binhex.lo is_tar.lo tnef.lo unrar15.lo unrarvm.lo \
88 88
 	unrar.lo unrarfilter.lo unrarppm.lo unrar20.lo unrarcmd.lo \
89
-	pdf.lo spin.lo elf.lo
89
+	pdf.lo spin.lo elf.lo sis.lo
90 90
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
91 91
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
92 92
 depcomp = $(SHELL) $(top_srcdir)/depcomp
... ...
@@ -337,7 +337,9 @@ libclamav_la_SOURCES = \
337 337
 	spin.h \
338 338
 	elf.c \
339 339
 	elf.h \
340
-	execs.h
340
+	execs.h \
341
+	sis.c \
342
+	sis.h
341 343
 
342 344
 lib_LTLIBRARIES = libclamav.la
343 345
 all: all-am
... ...
@@ -439,6 +441,7 @@ distclean-compile:
439 439
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readdb.Plo@am__quote@
440 440
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rebuildpe.Plo@am__quote@
441 441
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanners.Plo@am__quote@
442
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sis.Plo@am__quote@
442 443
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Plo@am__quote@
443 444
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/special.Plo@am__quote@
444 445
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spin.Plo@am__quote@
... ...
@@ -63,6 +63,7 @@ static const struct cli_magic_s cli_magic[] = {
63 63
     {0,	    "SZDD",			4,  "compress.exe'd",	CL_TYPE_MSSZDD},
64 64
     {0,	    "MSCF",			4,  "MS CAB",		CL_TYPE_MSCAB},
65 65
     {0,	    "ITSF",			4,  "MS CHM",           CL_TYPE_MSCHM},
66
+    {8,	    "\x19\x04\x00\x10",		4,  "SIS",		CL_TYPE_SIS},
66 67
     {0,     "#@~^",			4,  "SCRENC",		CL_TYPE_SCRENC},
67 68
     {0,     "(This file must be converted with BinHex 4.0)",
68 69
 				       45, "BinHex",		CL_TYPE_BINHEX},
... ...
@@ -39,6 +39,7 @@ typedef enum {
39 39
     CL_TYPE_MSOLE2,
40 40
     CL_TYPE_MSCAB,
41 41
     CL_TYPE_MSCHM,
42
+    CL_TYPE_SIS,
42 43
     CL_TYPE_SCRENC,
43 44
     CL_TYPE_GRAPHICS,
44 45
     CL_TYPE_RIFF,
... ...
@@ -63,6 +63,7 @@ extern int cli_mbox(const char *dir, int desc, unsigned int options); /* FIXME *
63 63
 #include "untar.h"
64 64
 #include "special.h"
65 65
 #include "binhex.h"
66
+#include "sis.h"
66 67
 
67 68
 #ifdef HAVE_ZLIB_H
68 69
 #include <zlib.h>
... ...
@@ -1622,6 +1623,10 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
1622 1622
 		ret = cli_scanelf(desc, virname, scanned, engine, limits, options, arec, mrec);
1623 1623
 	    break;
1624 1624
 
1625
+	case CL_TYPE_SIS:
1626
+		ret = cli_scansis(desc, virname, scanned, engine, limits, options, arec, mrec);
1627
+	    break;
1628
+
1625 1629
 	case CL_TYPE_DATA:
1626 1630
 	    /* it could be a false positive and a standard DOS .COM file */
1627 1631
 	    {
1628 1632
new file mode 100644
... ...
@@ -0,0 +1,199 @@
0
+/*
1
+ *  Copyright (C) 2005 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
+#if HAVE_CONFIG_H
19
+#include "clamav-config.h"
20
+#endif
21
+
22
+#include <stdio.h>
23
+#include <string.h>
24
+#include <sys/types.h>
25
+#include <sys/stat.h>
26
+#include <fcntl.h>
27
+#include <sys/stat.h>
28
+#include <unistd.h>
29
+#include <time.h>
30
+
31
+#include "cltypes.h"
32
+#include "clamav.h"
33
+#include "others.h"
34
+#include "sis.h"
35
+
36
+#if WORDS_BIGENDIAN == 0
37
+#define EC16(v)	(v)
38
+#define EC32(v) (v)
39
+#else
40
+static inline uint16_t EC16(uint16_t v)
41
+{
42
+    return ((v >> 8) + (v << 8));
43
+}
44
+
45
+static inline uint32_t EC32(uint32_t v)
46
+{
47
+    return ((v >> 24) | ((v & 0x00FF0000) >> 8) | ((v & 0x0000FF00) << 8) | (v << 24));
48
+}
49
+#endif
50
+
51
+extern short cli_leavetemps_flag;
52
+
53
+static char *langcodes[] = {
54
+    "",   "EN", "FR", "GE", "SP", "IT", "SW", "DA", "NO", "FI", "AM",
55
+    "SF", "SG", "PO", "TU", "IC", "RU", "HU", "DU", "BL", "AU", "BG",
56
+    "AS", "NZ", "IF", "CS", "SK", "PL", "SL", "TC", "HK", "ZH", "JA",
57
+    "TH", "AF", "SQ", "AH", "AR", "HY", "TL", "BE", "BN", "BG", "MY",
58
+    "CA", "HR", "CE", "IE", "SF", "ET", "FA", "CF", "GD", "KA", "EL",
59
+    "CG", "GU", "HE", "HI", "IN", "GA", "SZ", "KN", "KK", "KM", "KO",
60
+    "LO", "LV", "LT", "MK", "MS", "ML", "MR", "MO", "MN", "NN", "BP",
61
+    "PA", "RO", "SR", "SI", "SO", "OS", "LS", "SH", "FS", "TA", "TE",
62
+    "BO", "TI", "CT", "TK", "UK", "UR", "",   "VI", "CY", "ZU"
63
+};
64
+
65
+int cli_scansis(int desc, const char **virname, long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec)
66
+{
67
+	struct sis_file_hdr file_hdr;
68
+	struct sis_file_hdr6 file_hdr6;
69
+	uint8_t release = 0;
70
+	uint16_t opts, nlangs, *langrecs;
71
+	char *langs;
72
+	int i;
73
+
74
+
75
+    if(read(desc, &file_hdr, sizeof(struct sis_file_hdr)) != sizeof(struct sis_file_hdr)) {
76
+	cli_dbgmsg("SIS: Can't read file header\n"); /* Not a SIS file? */
77
+	return CL_CLEAN;
78
+    }
79
+
80
+    if(EC32(file_hdr.uid3) != 0x10000419) {
81
+	cli_dbgmsg("SIS: Not a SIS file\n");
82
+	return CL_CLEAN;
83
+    }
84
+
85
+    switch(EC32(file_hdr.uid2)) {
86
+	case 0x1000006d:
87
+	    cli_dbgmsg("SIS: EPOC release 3, 4 or 5\n");
88
+	    release = 3;
89
+	    break;
90
+	case 0x10003a12:
91
+	    cli_dbgmsg("SIS: EPOC release 6\n");
92
+	    release = 6;
93
+	    break;
94
+	default:
95
+	    cli_warnmsg("SIS: Unknown value of UID 2 (EPOC release)\n");
96
+    }
97
+
98
+    /* TODO: Verify checksums (uid4 and checksum) */
99
+
100
+    /* Languages */
101
+    nlangs = EC16(file_hdr.nlangs);
102
+    cli_dbgmsg("SIS: Number of languages: %d\n", nlangs);
103
+    cli_dbgmsg("SIS: Offset of languages records: %d\n", EC32(file_hdr.plangs));
104
+
105
+    if(nlangs && nlangs < 100) {
106
+	if(lseek(desc, EC32(file_hdr.plangs), SEEK_SET) < 0) {
107
+	    cli_errmsg("SIS: No language records\n");
108
+	    return CL_EFORMAT;
109
+	}
110
+
111
+	langrecs = (uint16_t *) cli_malloc(nlangs * 2);
112
+
113
+	if(read(desc, langrecs, nlangs * 2) != nlangs * 2) {
114
+	    cli_errmsg("SIS: Can't read language records\n");
115
+	    free(langrecs);
116
+	    return CL_EFORMAT;
117
+	}
118
+
119
+	langs = (char *) cli_calloc(nlangs * 3 + 1, sizeof(char));
120
+	for(i = 0; i < nlangs; i++) {
121
+	    strncat(langs, langcodes[EC16(langrecs[i]) % 98], 2);
122
+	    if(i != nlangs - 1)
123
+		strncat(langs, " ", 1);
124
+	}
125
+	cli_dbgmsg("SIS: Supported languages: %s\n", langs);
126
+	free(langrecs);
127
+	free(langs);
128
+    }
129
+
130
+    if(EC16(file_hdr.ilang))
131
+	cli_dbgmsg("SIS: Installation language: %d\n", EC16(file_hdr.ilang));
132
+
133
+    /* Files */
134
+    cli_dbgmsg("SIS: Number of files: %d\n", EC16(file_hdr.nfiles));
135
+    cli_dbgmsg("SIS: Offset of files records: %d\n", EC32(file_hdr.pfiles));
136
+
137
+
138
+    /* Requisites */
139
+    cli_dbgmsg("SIS: Number of requisites: %d\n", EC16(file_hdr.nreqs));
140
+    cli_dbgmsg("SIS: Offset of requisites records: %d\n", EC32(file_hdr.preqs));
141
+
142
+
143
+    /* Options flags */
144
+    opts = EC16(file_hdr.options);
145
+    cli_dbgmsg("SIS: Options:\n");
146
+    if(opts & 0x0001)
147
+	cli_dbgmsg("SIS:    * File is in Unicode format\n");
148
+    if(opts & 0x0002)
149
+	cli_dbgmsg("SIS:    * File is distributable\n");
150
+    if(opts & 0x0008)
151
+	cli_dbgmsg("SIS:    * Packed files are not compressed\n");
152
+    else
153
+	cli_dbgmsg("SIS:    * Packed files are compressed\n");
154
+    if(opts & 0x0010)
155
+	cli_dbgmsg("SIS:    * File installation shuts down all applications\n");
156
+
157
+    /* Type flags */
158
+    switch(EC16(file_hdr.type)) {
159
+	case 0x0000:
160
+	    cli_dbgmsg("SIS: Type: Contains an application\n");
161
+	    break;
162
+	case 0x0001:
163
+	    cli_dbgmsg("SIS: Type: Contains a shared/system component\n");
164
+	    break;
165
+	case 0x0002:
166
+	    cli_dbgmsg("SIS: Type: Contains an optional (selectable) component\n");
167
+	    break;
168
+	case 0x0003:
169
+	    cli_dbgmsg("SIS: Type: Configures an existing application or service\n");
170
+	    break;
171
+	case 0x0004:
172
+	    cli_dbgmsg("SIS: Type: Patches an existing component\n");
173
+	    break;
174
+	case 0x0005:
175
+	    cli_dbgmsg("SIS: Type: Upgrades an existing component\n");
176
+	    break;
177
+	default:
178
+	    cli_warnmsg("SIS: Unknown value of type\n");
179
+    } 
180
+
181
+    cli_dbgmsg("SIS: Major version: %d\n", EC16(file_hdr.majorver));
182
+    cli_dbgmsg("SIS: Minor version: %d\n", EC16(file_hdr.minorver));
183
+
184
+    if(release == 6) {
185
+
186
+	lseek(desc, sizeof(struct sis_file_hdr), SEEK_SET);
187
+
188
+	if(read(desc, &file_hdr6, sizeof(struct sis_file_hdr6)) != sizeof(struct sis_file_hdr6)) {
189
+	    cli_dbgmsg("SIS: Can't read additional data of EPOC 6 file header\n"); /* Not a SIS file? */
190
+	    return CL_EFORMAT;
191
+	}
192
+
193
+	cli_dbgmsg("SIS: Maximum space required: %d\n", EC32(file_hdr6.maxispace));
194
+    }
195
+
196
+
197
+    return CL_CLEAN;
198
+}
0 199
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+/*
1
+ *  Copyright (C) 2005 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 __SIS_H
19
+#define __SIS_H
20
+
21
+#include "clamav.h"
22
+
23
+struct sis_file_hdr {
24
+    uint32_t uid1;
25
+    uint32_t uid2;
26
+    uint32_t uid3;
27
+    uint32_t uid4;
28
+    uint16_t checksum;
29
+    uint16_t nlangs;
30
+    uint16_t nfiles;
31
+    uint16_t nreqs;
32
+    uint16_t ilang;
33
+    uint16_t ifiles;
34
+    uint16_t idrive;
35
+    uint16_t ncaps;
36
+    uint32_t iver;
37
+    uint16_t options;
38
+    uint16_t type;
39
+    uint16_t majorver;
40
+    uint16_t minorver;
41
+    uint16_t variant;
42
+    uint32_t plangs;
43
+    uint32_t pfiles;
44
+    uint32_t preqs;
45
+    uint32_t pcerts;
46
+    uint32_t pname;
47
+};
48
+
49
+struct sis_file_hdr6 {
50
+    uint32_t psig;
51
+    uint32_t pcaps;
52
+    uint32_t ispace;
53
+    uint32_t maxispace;
54
+    uint32_t reserved[4];
55
+};
56
+
57
+int cli_scansis(int desc, const char **virname, long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec);
58
+
59
+#endif