Browse code

add support for new signature format

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

Tomasz Kojm authored on 2004/09/18 08:29:44
Showing 14 changed files
... ...
@@ -1,8 +1,13 @@
1
+Sat Sep 18 01:13:21 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav: add support for new signature format (*.ndb; not yet documented)
4
+  * sigtool: support ndb files
5
+
1 6
 Fri Sep 17 16:42:06 BST 2004 (njh)
2 7
 ----------------------------------
3 8
   * clamav-milter:	Fix problem in the template file handling where sendmail
4 9
 				variables did't work after clamav variables.
5
-				Thanks to "Sergey Y. Afonin" <asy@kraft-s.ru>
10
+				Thanks to "Sergey Y. Afonin" <asy*kraft-s.ru>
6 11
 				for pointing this out
7 12
 
8 13
 Fri Sep 17 14:47:53 BST 2004 (njh)
... ...
@@ -97,15 +97,20 @@ static const struct cli_magic_s cli_magic[] = {
97 97
     {0,  "\320\317\021\340\241\261\032\341",
98 98
 	                    8, "OLE2 container",  CL_TYPE_MSOLE2},
99 99
 
100
+    /* Graphics (may contain exploits against MS systems) */
101
+
102
+    {0,  "GIF",				 3, "GIF",	    CL_TYPE_GRAPHICS},
103
+    {0,  "BM",				 2, "BMP",          CL_TYPE_GRAPHICS},
104
+    {0,  "\377\330\377",		 4, "JPEG",         CL_TYPE_GRAPHICS},
105
+    {6,  "JFIF",			 4, "JPEG",         CL_TYPE_GRAPHICS},
106
+    {6,  "Exif",			 4, "JPEG",         CL_TYPE_GRAPHICS},
107
+    {0,  "\x89PNG",			 4, "PNG",          CL_TYPE_GRAPHICS},
108
+
100 109
     /* Ignored types */
101 110
 
102 111
     {0,  "\000\000\001\263",             4, "MPEG video stream",  CL_TYPE_DATA},
103 112
     {0,  "\000\000\001\272",             4, "MPEG sys stream",    CL_TYPE_DATA},
104 113
     {0,  "RIFF",                         4, "RIFF",		  CL_TYPE_DATA},
105
-    {0,  "GIF",				 3, "GIF",		  CL_TYPE_DATA},
106
-    {0,  "\x89PNG",			 4, "PNG",                CL_TYPE_DATA},
107
-    {0,  "\377\330\377",		 4, "JPEG",               CL_TYPE_DATA},
108
-    {0,  "BM",				 2, "BMP",                CL_TYPE_DATA},
109 114
     {0,  "OggS",                         4, "Ogg Stream",         CL_TYPE_DATA},
110 115
     {0,  "ID3",				 3, "MP3",		  CL_TYPE_DATA},
111 116
     {0,  "\377\373\220",		 3, "MP3",		  CL_TYPE_DATA},
... ...
@@ -38,6 +38,7 @@ typedef enum {
38 38
     CL_TYPE_MSCAB,
39 39
     CL_TYPE_MSCHM,
40 40
     CL_TYPE_SCRENC,
41
+    CL_TYPE_GRAPHICS,
41 42
 
42 43
     /* bigger numbers have higher priority (in o-t-f detection) */
43 44
     CL_TYPE_HTML, /* on the fly */
... ...
@@ -196,7 +196,7 @@ static void cli_freepatt(struct cli_ac_patt *list)
196 196
     while(handler) {
197 197
 	free(handler->pattern);
198 198
 	free(handler->virname);
199
-	if(handler->offset)
199
+	if(handler->offset && (!handler->sigid || handler->partno == 1))
200 200
 	    free(handler->offset);
201 201
 	if(handler->alt) {
202 202
 	    free(handler->altn);
... ...
@@ -264,11 +264,11 @@ static int inline cli_findpos(const char *buffer, int offset, int length, const
264 264
     return 1;
265 265
 }
266 266
 
267
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, struct cli_voffset *voffset)
267
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd)
268 268
 {
269 269
 	struct cli_ac_node *current;
270 270
 	struct cli_ac_patt *pt;
271
-	int position, type = CL_CLEAN, dist;
271
+	int position, type = CL_CLEAN, dist, t;
272 272
         unsigned int i;
273 273
 
274 274
 
... ...
@@ -291,9 +291,19 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
291 291
 	    pt = current->list;
292 292
 	    while(pt) {
293 293
 		if(cli_findpos(buffer, position, length, pt)) {
294
+		    if((pt->offset || pt->target) && (!pt->sigid || pt->partno == 1)) {
295
+			if(ftype == CL_TYPE_UNKNOWN_TEXT)
296
+			    t = type;
297
+			else
298
+			    t = ftype;
299
+			if(!cli_validatesig(pt->target, t, pt->offset, offset + position, fd, pt->virname)) {
300
+			    pt = pt->next;
301
+			    continue;
302
+			}
303
+		    }
304
+
294 305
 		    if(pt->sigid) { /* it's a partial signature */
295 306
 			if(partcnt[pt->sigid] + 1 == pt->partno) {
296
-
297 307
 			    dist = 1;
298 308
 			    if(pt->maxdist)
299 309
 				if(offset + i - partoff[pt->sigid] > pt->maxdist)
... ...
@@ -23,7 +23,7 @@
23 23
 #include "matcher.h"
24 24
 
25 25
 int cli_ac_addpatt(struct cl_node *root, struct cli_ac_patt *pattern);
26
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, struct cli_voffset *voffset);
26
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd);
27 27
 int cli_ac_buildtrie(struct cl_node *root);
28 28
 void cli_ac_free(struct cl_node *root);
29 29
 
... ...
@@ -120,7 +120,7 @@ void cli_bm_free(struct cl_node *root)
120 120
     }
121 121
 }
122 122
 
123
-int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned long int offset, struct cli_voffset *voffset)
123
+int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned long int offset, unsigned short ftype, int fd)
124 124
 {
125 125
 	int i, j, shift, off, found = 0;
126 126
 	uint16_t idx;
... ...
@@ -166,10 +166,13 @@ int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virnam
166 166
 		}
167 167
 
168 168
 		if(found && p->length == j) {
169
-		    if(voffset) {
170
-			voffset->offstr = p->offset;
171
-			voffset->fileoff = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
172
-                        voffset->target = p->target;
169
+
170
+		    if(p->target || p->offset) {
171
+			    int off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
172
+			if(!cli_validatesig(p->target, ftype, p->offset, off, fd, p->virname)) {
173
+			    p = p->next;
174
+			    continue;
175
+			}
173 176
 		    }
174 177
 
175 178
 		    if(virname)
... ...
@@ -24,7 +24,7 @@
24 24
 
25 25
 int cli_bm_addpatt(struct cl_node *root, struct cli_bm_patt *pattern);
26 26
 int cli_bm_init(struct cl_node *root);
27
-int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned long int offset, struct cli_voffset *voffset);
27
+int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned long int offset, unsigned short ftype, int fd);
28 28
 void cli_bm_free(struct cl_node *root);
29 29
 
30 30
 #endif
... ...
@@ -21,6 +21,10 @@
21 21
 #endif
22 22
 
23 23
 #include <string.h>
24
+#include <ctype.h>
25
+#include <sys/types.h>
26
+#include <sys/stat.h>
27
+#include <unistd.h>
24 28
 
25 29
 #include "clamav.h"
26 30
 #include "others.h"
... ...
@@ -29,14 +33,15 @@
29 29
 #include "md5.h"
30 30
 #include "filetypes.h"
31 31
 #include "matcher.h"
32
+#include "pe.h"
32 33
 
33 34
 #define MD5_BLOCKSIZE 4096
34 35
 
35
-#define TARGET_TABLE_SIZE 5
36
-static int targettab[TARGET_TABLE_SIZE] = { 0, CL_TYPE_MSEXE, CL_TYPE_MSOLE2, CL_TYPE_HTML, CL_TYPE_MAIL };
36
+#define TARGET_TABLE_SIZE 6
37
+static int targettab[TARGET_TABLE_SIZE] = { 0, CL_TYPE_MSEXE, CL_TYPE_MSOLE2, CL_TYPE_HTML, CL_TYPE_MAIL, CL_TYPE_GRAPHICS };
37 38
 
38 39
 
39
-int cl_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root)
40
+int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned short ftype)
40 41
 {
41 42
 	int ret, *partcnt;
42 43
 	unsigned long int *partoff;
... ...
@@ -53,14 +58,19 @@ int cl_scanbuff(const char *buffer, unsigned int length, const char **virname, c
53 53
 	return CL_EMEM;
54 54
     }
55 55
 
56
-    if((ret = cli_bm_scanbuff(buffer, length, virname, root, 0, NULL)) != CL_VIRUS)
57
-	ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff, NULL);
56
+    if((ret = cli_bm_scanbuff(buffer, length, virname, root, 0, ftype, -1)) != CL_VIRUS)
57
+	ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff, ftype, -1);
58 58
 
59 59
     free(partcnt);
60 60
     free(partoff);
61 61
     return ret;
62 62
 }
63 63
 
64
+int cl_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root)
65
+{
66
+    return cli_scanbuff(buffer, length, virname, root, 0);
67
+}
68
+
64 69
 static struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl_node *root)
65 70
 {
66 71
 	struct cli_md5_node *pt;
... ...
@@ -79,6 +89,92 @@ static struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl
79 79
     return NULL;
80 80
 }
81 81
 
82
+static long int cli_caloff(const char *offstr, int fd)
83
+{
84
+	struct cli_pe_info peinfo;
85
+	long int offset = -1;
86
+	int n;
87
+
88
+
89
+    if(isdigit(offstr[0])) {
90
+	return atoi(offstr);
91
+    } if(!strncmp(offstr, "EP+", 3)) {
92
+	if((n = lseek(fd, 0, SEEK_CUR)) == -1) {
93
+	    cli_dbgmsg("Invalid descriptor\n");
94
+	    return -1;
95
+	}
96
+	lseek(fd, 0, SEEK_SET);
97
+	if(cli_peheader(fd, &peinfo))
98
+	    return -1;
99
+	free(peinfo.section);
100
+	lseek(fd, n, SEEK_SET);
101
+	return peinfo.ep + atoi(offstr + 3);
102
+    } else if(offstr[0] == 'S') {
103
+	if((n = lseek(fd, 0, SEEK_CUR)) == -1) {
104
+	    cli_dbgmsg("Invalid descriptor\n");
105
+	    return -1;
106
+	}
107
+	lseek(fd, 0, SEEK_SET);
108
+	if(cli_peheader(fd, &peinfo))
109
+	    return -1;
110
+	lseek(fd, n, SEEK_SET);
111
+
112
+	if(sscanf(offstr, "S%d+%ld", &n, &offset) != 2)
113
+	    return -1;
114
+
115
+	if(n >= peinfo.nsections) {
116
+	    free(peinfo.section);
117
+	    return -1;
118
+	}
119
+
120
+	offset += peinfo.section[n].raw;
121
+	free(peinfo.section);
122
+	return offset;
123
+    } else if(!strncmp(offstr, "EOF-", 4)) {
124
+	    struct stat sb;
125
+
126
+	if(fstat(fd, &sb) == -1)
127
+	    return -1;
128
+
129
+	return sb.st_size - atoi(offstr + 4);
130
+    }
131
+
132
+    return -1;
133
+}
134
+
135
+int cli_validatesig(unsigned short target, unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname)
136
+{
137
+
138
+    if(target) {
139
+	if(target >= TARGET_TABLE_SIZE) {
140
+	    cli_errmsg("Bad target in signature (%s)\n", virname);
141
+	    return 0;
142
+	} else if(ftype) {
143
+	    if(targettab[target] != ftype) {
144
+		cli_dbgmsg("Type: %d, expected: %d (%s)\n", ftype, targettab[target], virname);
145
+		return 0;
146
+	    }
147
+	} 
148
+
149
+    }
150
+
151
+    if(offstr && desc != -1) {
152
+	    long int off = cli_caloff(offstr, desc);
153
+
154
+	if(off == -1) {
155
+	    cli_dbgmsg("Bad offset in signature (%s)\n", virname);
156
+	    return 0;
157
+	}
158
+
159
+	if(fileoff != off) {
160
+	    cli_dbgmsg("Virus offset: %d, expected: %d (%s)\n", fileoff, off, virname);
161
+	    return 0;
162
+	}
163
+    }
164
+
165
+    return 1;
166
+}
167
+
82 168
 int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype)
83 169
 {
84 170
  	char *buffer, *buff, *endbl, *pt;
... ...
@@ -87,7 +183,6 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
87 87
 	struct MD5Context ctx;
88 88
 	unsigned char digest[16];
89 89
 	struct cli_md5_node *md5_node;
90
-	struct cli_voffset voffset;
91 90
 
92 91
 
93 92
     if(!root) {
... ...
@@ -109,7 +204,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
109 109
     }
110 110
 
111 111
     if((partoff = (unsigned long int *) cli_calloc(root->ac_partsigs + 1, sizeof(unsigned long int))) == NULL) {
112
-	cli_dbgmsg("cli_scanbuff(): unable to cli_calloc(%d, %d)\n", root->ac_partsigs + 1, sizeof(unsigned long int));
112
+	cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%d, %d)\n", root->ac_partsigs + 1, sizeof(unsigned long int));
113 113
 	free(buffer);
114 114
 	free(partcnt);
115 115
 	return CL_EMEM;
... ...
@@ -118,7 +213,6 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
118 118
     if(root->md5_hlist)
119 119
 	MD5Init(&ctx);
120 120
 
121
-    memset(&voffset, 0, sizeof(struct cli_voffset));
122 121
 
123 122
     buff = buffer;
124 123
     buff += root->maxpatlen; /* pointer to read data block */
... ...
@@ -136,28 +230,12 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
136 136
 	if(bytes < SCANBUFF)
137 137
 	    length -= SCANBUFF - bytes;
138 138
 
139
-	if(cli_bm_scanbuff(pt, length, virname, root, offset, &voffset) == CL_VIRUS ||
140
-	   (ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, &voffset)) == CL_VIRUS) {
139
+	if(cli_bm_scanbuff(pt, length, virname, root, offset, ftype, desc) == CL_VIRUS ||
140
+	   (ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, ftype, desc)) == CL_VIRUS) {
141 141
 	    free(buffer);
142 142
 	    free(partcnt);
143 143
 	    free(partoff);
144 144
 
145
-	    if(voffset.target) {
146
-		if(voffset.target >= TARGET_TABLE_SIZE) {
147
-		    cli_errmsg("Bad target (%d) in signature for %s\n", voffset.target, *virname);
148
-		} else if(ftype && ftype != CL_TYPE_UNKNOWN_TEXT) {
149
-		    if(targettab[voffset.target] != ftype) {
150
-			cli_dbgmsg("Expected target type (%d) for %s != %d\n", voffset.target, *virname, ftype);
151
-			return CL_CLEAN;
152
-		    }
153
-		} else if(type) {
154
-		    if(targettab[voffset.target] != type) {
155
-			cli_dbgmsg("Expected target type (%d) for %s != %d\n", voffset.target, *virname, type);
156
-			return CL_CLEAN;
157
-		    }
158
-		}
159
-	    }
160
-
161 145
 	    return CL_VIRUS;
162 146
 
163 147
 	} else if(otfrec && ret >= CL_TYPENO) {
... ...
@@ -23,10 +23,8 @@
23 23
 
24 24
 int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype);
25 25
 
26
-struct cli_voffset {
27
-    const char *offstr;
28
-    unsigned long int fileoff;
29
-    unsigned short target;
30
-};
26
+int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned short ftype);
27
+
28
+int cli_validatesig(unsigned short target, unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname);
31 29
 
32 30
 #endif
... ...
@@ -1182,7 +1182,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
1182 1182
     return CL_CLEAN;
1183 1183
 }
1184 1184
 
1185
-int cli_peheader(int desc, struct cli_pe_info **peinfo)
1185
+int cli_peheader(int desc, struct cli_pe_info *peinfo)
1186 1186
 {
1187 1187
 	uint16_t e_magic; /* DOS signature ("MZ") */
1188 1188
 	uint32_t e_lfanew; /* address of new exe header */
... ...
@@ -1190,7 +1190,6 @@ int cli_peheader(int desc, struct cli_pe_info **peinfo)
1190 1190
 	struct pe_image_optional_hdr optional_hdr;
1191 1191
 	struct pe_image_section_hdr *section_hdr;
1192 1192
 	struct stat sb;
1193
-	struct cli_pe_info *info;
1194 1193
 	int i;
1195 1194
 
1196 1195
 
... ...
@@ -1242,71 +1241,57 @@ int cli_peheader(int desc, struct cli_pe_info **peinfo)
1242 1242
 	return -1;
1243 1243
     }
1244 1244
 
1245
-    if(!(info = cli_calloc(1, sizeof(struct cli_pe_info)))) {
1246
-	cli_dbgmsg("Can't alloc memory\n");
1247
-	return -1;
1248
-    }
1249
-
1250
-    info->nsections = EC16(file_hdr.NumberOfSections);
1245
+    peinfo->nsections = EC16(file_hdr.NumberOfSections);
1251 1246
 
1252 1247
     if(read(desc, &optional_hdr, sizeof(struct pe_image_optional_hdr)) != sizeof(struct pe_image_optional_hdr)) {
1253 1248
 	cli_dbgmsg("Can't optional file header\n");
1254
-	free(info);
1255 1249
 	return -1;
1256 1250
     }
1257 1251
 
1258
-    info->section = (struct SECTION *) cli_calloc(info->nsections, sizeof(struct SECTION));
1252
+    peinfo->section = (struct SECTION *) cli_calloc(peinfo->nsections, sizeof(struct SECTION));
1259 1253
 
1260
-    if(!info->section) {
1254
+    if(!peinfo->section) {
1261 1255
 	cli_dbgmsg("Can't allocate memory for section headers\n");
1262
-	free(info);
1263 1256
 	return -1;
1264 1257
     }
1265 1258
 
1266 1259
     if(fstat(desc, &sb) == -1) {
1267 1260
 	cli_dbgmsg("fstat failed\n");
1268
-	free(info->section);
1269
-	free(info);
1261
+	free(peinfo->section);
1270 1262
 	return -1;
1271 1263
     }
1272 1264
 
1273
-    section_hdr = (struct pe_image_section_hdr *) cli_calloc(info->nsections, sizeof(struct pe_image_section_hdr));
1265
+    section_hdr = (struct pe_image_section_hdr *) cli_calloc(peinfo->nsections, sizeof(struct pe_image_section_hdr));
1274 1266
 
1275 1267
     if(!section_hdr) {
1276 1268
 	cli_dbgmsg("Can't allocate memory for section headers\n");
1277
-	free(info->section);
1278
-	free(info);
1269
+	free(peinfo->section);
1279 1270
 	return -1;
1280 1271
     }
1281 1272
 
1282
-    for(i = 0; i < info->nsections; i++) {
1273
+    for(i = 0; i < peinfo->nsections; i++) {
1283 1274
 
1284 1275
 	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
1285 1276
 	    cli_dbgmsg("Can't read section header\n");
1286 1277
 	    cli_dbgmsg("Possibly broken PE file\n");
1287 1278
 	    free(section_hdr);
1288
-	    free(info->section);
1289
-	    free(info);
1279
+	    free(peinfo->section);
1290 1280
 	    return -1;
1291 1281
 	}
1292 1282
 
1293
-	info->section[i].rva = EC32(section_hdr[i].VirtualAddress);
1294
-	info->section[i].vsz = EC32(section_hdr[i].VirtualSize);
1295
-	info->section[i].raw = EC32(section_hdr[i].PointerToRawData);
1296
-	info->section[i].rsz = EC32(section_hdr[i].SizeOfRawData);
1297
-
1283
+	peinfo->section[i].rva = EC32(section_hdr[i].VirtualAddress);
1284
+	peinfo->section[i].vsz = EC32(section_hdr[i].VirtualSize);
1285
+	peinfo->section[i].raw = EC32(section_hdr[i].PointerToRawData);
1286
+	peinfo->section[i].rsz = EC32(section_hdr[i].SizeOfRawData);
1298 1287
     }
1299 1288
 
1300
-    if((info->ep = cli_rawaddr(EC32(optional_hdr.AddressOfEntryPoint), section_hdr, info->nsections)) == -1) {
1289
+    if((peinfo->ep = cli_rawaddr(EC32(optional_hdr.AddressOfEntryPoint), section_hdr, peinfo->nsections)) == -1) {
1301 1290
 	cli_dbgmsg("Possibly broken PE file\n");
1302 1291
 	free(section_hdr);
1303
-	free(info->section);
1304
-	free(info);
1292
+	free(peinfo->section);
1305 1293
 	return -1;
1306 1294
     }
1307 1295
 
1308 1296
     free(section_hdr);
1309
-    *peinfo = info;
1310
-
1311 1297
     return 0;
1312 1298
 }
... ...
@@ -102,6 +102,6 @@ struct cli_pe_info {
102 102
 
103 103
 int cli_scanpe(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, int *arec, int *mrec);
104 104
 
105
-int cli_peheader(int desc, struct cli_pe_info **peinfo);
105
+int cli_peheader(int desc, struct cli_pe_info *peinfo);
106 106
 
107 107
 #endif
... ...
@@ -513,6 +513,9 @@ static int cli_loadndb(FILE *fd, struct cl_node **root, unsigned int *signo)
513 513
 	    free(virname);
514 514
 	    ret = CL_EMALFDB;
515 515
 	    break;
516
+	} else if(!strcmp(offset, "*")) {
517
+	    free(offset);
518
+	    offset = NULL;
516 519
 	}
517 520
 
518 521
 	if(!(sig = cli_strtok(buffer, 3, ":"))) {
... ...
@@ -852,7 +852,7 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int *
852 852
 	    if(!data) {
853 853
 		cli_dbgmsg("VBADir: WARNING: VBA project '%s' decompressed to NULL\n", vba_project->name[i]);
854 854
 	    } else {
855
-		if(cl_scanbuff(data, data_len, virname, root) == CL_VIRUS) {
855
+		if(cli_scanbuff(data, data_len, virname, root, CL_TYPE_MSOLE2) == CL_VIRUS) {
856 856
 		    free(data);
857 857
 		    ret = CL_VIRUS;
858 858
 		    break;
... ...
@@ -893,7 +893,7 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int *
893 893
 		if(!data) {
894 894
 			cli_dbgmsg("VBADir: WARNING: WM project '%s' macro %d decrypted to NULL\n", vba_project->name[i], i);
895 895
 		} else {
896
-			if(cl_scanbuff(data, vba_project->length[i], virname, root) == CL_VIRUS) {
896
+			if(cli_scanbuff(data, vba_project->length[i], virname, root, CL_TYPE_MSOLE2) == CL_VIRUS) {
897 897
 				free(data);
898 898
 				ret = CL_VIRUS;
899 899
 				break;
... ...
@@ -226,17 +226,13 @@ int build(struct optstruct *opt)
226 226
 	struct tm *brokent;
227 227
 	struct cl_cvd *oldcvd = NULL;
228 228
 
229
-    /* build a tar.gz archive
230
-     * we need: COPYING and {main.db, main.hdb, daily.db, daily.hdb}+
231
-     * in current working directory
232
-     */
233 229
 
234 230
     if(stat("COPYING", &foo) == -1) {
235 231
 	mprintf("COPYING file not found in current working directory.\n");
236 232
 	exit(1);
237 233
     }
238 234
 
239
-    if(stat("main.db", &foo) == -1 && stat("daily.db", &foo) == -1 && stat("main.hdb", &foo) == -1 && stat("daily.hdb", &foo)) {
235
+    if(stat("main.db", &foo) == -1 && stat("daily.db", &foo) == -1 && stat("main.hdb", &foo) == -1 && stat("daily.hdb", &foo) == -1 && stat("main.ndb", &foo) == -1 && stat("daily.ndb", &foo) == -1) {
240 236
 	mprintf("Virus database not found in current working directory.\n");
241 237
 	exit(1);
242 238
     }
... ...
@@ -256,7 +252,7 @@ int build(struct optstruct *opt)
256 256
 	mprintf("WARNING: There are no signatures in the database(s).\n");
257 257
     } else {
258 258
 	mprintf("Signatures: %d\n", no);
259
-	realno = countlines("main.db") + countlines("daily.db") + countlines("main.hdb") + countlines("daily.hdb");
259
+	realno = countlines("main.db") + countlines("daily.db") + countlines("main.hdb") + countlines("daily.hdb") + countlines("main.ndb") + countlines("daily.ndb");
260 260
 	if(realno != no) {
261 261
 	    mprintf("!Signatures in database: %d. Loaded: %d.\n", realno, no);
262 262
 	    mprintf("Please check the current directory and remove unnecessary databases\n");
... ...
@@ -273,7 +269,7 @@ int build(struct optstruct *opt)
273 273
 	    exit(1);
274 274
 	case 0:
275 275
 	    {
276
-		char *args[] = { "tar", "-cvf", NULL, "COPYING", "main.db", "daily.db", "Notes", "viruses.db3", "main.hdb", "daily.hdb", NULL };
276
+		char *args[] = { "tar", "-cvf", NULL, "COPYING", "main.db", "daily.db", "Notes", "viruses.db3", "main.hdb", "daily.hdb", "main.ndb", "daily.ndb", NULL };
277 277
 		args[2] = tarfile;
278 278
 		execv("/bin/tar", args);
279 279
 		mprintf("!Can't execute tar\n");
... ...
@@ -663,7 +659,7 @@ int listdb(const char *filename)
663 663
 	    mprintf("%s\n", start);
664 664
 	}
665 665
 
666
-    } else if(cli_strbcasestr(filename, ".hdb") || cli_strbcasestr(filename, ".hdb2")) {
666
+    } else if(cli_strbcasestr(filename, ".hdb")) {
667 667
 
668 668
 	while(fgets(buffer, FILEBUFF, fd)) {
669 669
 	    line++;
... ...
@@ -684,6 +680,26 @@ int listdb(const char *filename)
684 684
 	    free(start);
685 685
 	}
686 686
 
687
+    } else if(cli_strbcasestr(filename, ".ndb")) {
688
+
689
+	while(fgets(buffer, FILEBUFF, fd)) {
690
+	    line++;
691
+	    cli_chomp(buffer);
692
+	    start = cli_strtok(buffer, 0, ":");
693
+
694
+	    if(!start) {
695
+		mprintf("!listdb(): Malformed pattern line %d (file %s).\n", line, filename);
696
+		fclose(fd);
697
+		free(buffer);
698
+		return -1;
699
+	    }
700
+
701
+	    if((pt = strstr(start, " (Clam)")))
702
+		*pt = 0;
703
+
704
+	    mprintf("%s\n", start);
705
+	    free(start);
706
+	}
687 707
     }
688 708
 
689 709
     fclose(fd);
... ...
@@ -712,7 +728,7 @@ int listdir(const char *dirname)
712 712
 	    (cli_strbcasestr(dent->d_name, ".db")  ||
713 713
 	     cli_strbcasestr(dent->d_name, ".db2") ||
714 714
 	     cli_strbcasestr(dent->d_name, ".hdb") ||
715
-	     cli_strbcasestr(dent->d_name, ".hdb2") ||
715
+	     cli_strbcasestr(dent->d_name, ".ndb") ||
716 716
 	     cli_strbcasestr(dent->d_name, ".cvd"))) {
717 717
 
718 718
 		dbfile = (char *) mcalloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char));