Browse code

initial support for new signature format

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

Tomasz Kojm authored on 2004/09/14 10:33:32
Showing 12 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Sep 14 03:30:12 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav: initial support for new signature format
4
+
1 5
 Mon Sep 13 21:57:12 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * libclamav/matcher-bm.c: minor optimization
... ...
@@ -89,17 +89,20 @@ extern "C"
89 89
 
90 90
 
91 91
 struct cli_bm_patt {
92
-    char *pattern;
93
-    char *virname;
94
-    int length; 
92
+    char *pattern, *virname, *offset;
93
+    const char *viralias;
94
+    unsigned int length;
95
+    unsigned short target;
95 96
     struct cli_bm_patt *next;
96 97
 };
97 98
 
98 99
 struct cli_ac_patt {
99 100
     short int *pattern;
100 101
     unsigned int length, mindist, maxdist;
101
-    char *virname;
102
-    unsigned short int sigid, parts, partno, type, alt, *altn;
102
+    char *virname, *offset;
103
+    const char *viralias;
104
+    unsigned short int sigid, parts, partno, alt, *altn;
105
+    unsigned short type, target;
103 106
     char **altc;
104 107
     struct cli_ac_patt *next;
105 108
 };
... ...
@@ -176,7 +176,7 @@ int cli_addtypesigs(struct cl_node *root)
176 176
 	int i, ret;
177 177
 
178 178
     for(i = 0; cli_smagic[i].sig; i++) {
179
-	if((ret = cli_parse_add(root, cli_smagic[i].descr, cli_smagic[i].sig, cli_smagic[i].type))) {
179
+	if((ret = cli_parse_add(root, cli_smagic[i].descr, cli_smagic[i].sig, cli_smagic[i].type, NULL, 0))) {
180 180
 	    cli_errmsg("cli_addtypesigs(): Problem adding signature for %s\n", cli_smagic[i].descr);
181 181
 	    return ret;
182 182
 	}
... ...
@@ -32,6 +32,7 @@
32 32
 
33 33
 #include "clamav.h"
34 34
 #include "others.h"
35
+#include "matcher.h"
35 36
 #include "matcher-ac.h"
36 37
 #include "unrarlib.h"
37 38
 #include "defaults.h"
... ...
@@ -195,6 +196,8 @@ static void cli_freepatt(struct cli_ac_patt *list)
195 195
     while(handler) {
196 196
 	free(handler->pattern);
197 197
 	free(handler->virname);
198
+	if(handler->offset)
199
+	    free(handler->offset);
198 200
 	if(handler->alt) {
199 201
 	    free(handler->altn);
200 202
 	    for(i = 0; i < handler->alt; i++)
... ...
@@ -261,7 +264,7 @@ static int inline cli_findpos(const char *buffer, int offset, int length, const
261 261
     return 1;
262 262
 }
263 263
 
264
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, int typerec, unsigned long int offset, unsigned long int *partoff)
264
+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)
265 265
 {
266 266
 	struct cli_ac_node *current;
267 267
 	struct cli_ac_patt *pt;
... ...
@@ -305,7 +308,7 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
305 305
 
306 306
 				if(++partcnt[pt->sigid] == pt->parts) { /* the last one */
307 307
 				    if(pt->type) {
308
-					if(typerec) {
308
+					if(otfrec) {
309 309
 					    if(pt->type > type) {
310 310
 						cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
311 311
 						type = pt->type;
... ...
@@ -323,7 +326,7 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
323 323
 
324 324
 		    } else { /* old type signature */
325 325
 			if(pt->type) {
326
-			    if(typerec) {
326
+			    if(otfrec) {
327 327
 				if(pt->type > type) {
328 328
 				    cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
329 329
 
... ...
@@ -346,5 +349,5 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
346 346
 	}
347 347
     }
348 348
 
349
-    return typerec ? type : CL_CLEAN;
349
+    return otfrec ? type : CL_CLEAN;
350 350
 }
... ...
@@ -20,9 +20,10 @@
20 20
 #define __MATCHER_AC_H
21 21
 
22 22
 #include "clamav.h"
23
+#include "matcher.h"
23 24
 
24 25
 int cli_ac_addpatt(struct cl_node *root, struct cli_ac_patt *pattern);
25
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt, int typerec, unsigned long int offset, unsigned long int *partoff);
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 27
 int cli_ac_buildtrie(struct cl_node *root);
27 28
 void cli_ac_free(struct cl_node *root);
28 29
 
... ...
@@ -20,6 +20,7 @@
20 20
 #include "memory.h"
21 21
 #include "others.h"
22 22
 #include "cltypes.h"
23
+#include "matcher.h"
23 24
 
24 25
 #define BM_MIN_LENGTH	10
25 26
 #define BM_TEST_OFFSET	5
... ...
@@ -108,6 +109,8 @@ void cli_bm_free(struct cl_node *root)
108 108
 		b1 = b1->next;
109 109
 		if(b2->virname)
110 110
 		    free(b2->virname);
111
+		if(b2->offset)
112
+		    free(b2->offset);
111 113
 		if(b2->pattern)
112 114
 		    free(b2->pattern);
113 115
 		free(b2);
... ...
@@ -117,7 +120,7 @@ void cli_bm_free(struct cl_node *root)
117 117
     }
118 118
 }
119 119
 
120
-int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root)
120
+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)
121 121
 {
122 122
 	int i, j, shift, off, found = 0;
123 123
 	uint16_t idx;
... ...
@@ -163,6 +166,12 @@ int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virnam
163 163
 		}
164 164
 
165 165
 		if(found && p->length == j) {
166
+		    if(voffset) {
167
+			voffset->offstr = p->offset;
168
+			voffset->fileoff = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
169
+                        voffset->target = p->target;
170
+		    }
171
+
166 172
 		    if(virname)
167 173
 			*virname = p->virname;
168 174
 
... ...
@@ -20,10 +20,11 @@
20 20
 #define __MATCHER_BM_H
21 21
 
22 22
 #include "clamav.h"
23
+#include "matcher.h"
23 24
 
24 25
 int cli_bm_addpatt(struct cl_node *root, struct cli_bm_patt *pattern);
25 26
 int cli_bm_init(struct cl_node *root);
26
-int cli_bm_scanbuff(const char *buffer, unsigned int length, const char **virname, const 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 28
 void cli_bm_free(struct cl_node *root);
28 29
 
29 30
 #endif
... ...
@@ -28,9 +28,13 @@
28 28
 #include "matcher-bm.h"
29 29
 #include "md5.h"
30 30
 #include "filetypes.h"
31
+#include "matcher.h"
31 32
 
32 33
 #define MD5_BLOCKSIZE 4096
33 34
 
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 };
37
+
34 38
 
35 39
 int cl_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root)
36 40
 {
... ...
@@ -49,8 +53,8 @@ int cl_scanbuff(const char *buffer, unsigned int length, const char **virname, c
49 49
 	return CL_EMEM;
50 50
     }
51 51
 
52
-    if((ret = cli_bm_scanbuff(buffer, length, virname, root)) != CL_VIRUS)
53
-	ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff);
52
+    if((ret = cli_bm_scanbuff(buffer, length, virname, root, 0, NULL)) != CL_VIRUS)
53
+	ret = cli_ac_scanbuff(buffer, length, virname, root, partcnt, 0, 0, partoff, NULL);
54 54
 
55 55
     free(partcnt);
56 56
     free(partoff);
... ...
@@ -75,7 +79,7 @@ static struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl
75 75
     return NULL;
76 76
 }
77 77
 
78
-int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, int typerec)
78
+int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype)
79 79
 {
80 80
  	char *buffer, *buff, *endbl, *pt;
81 81
 	int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN;
... ...
@@ -83,6 +87,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
83 83
 	struct MD5Context ctx;
84 84
 	unsigned char digest[16];
85 85
 	struct cli_md5_node *md5_node;
86
+	struct cli_voffset voffset;
86 87
 
87 88
 
88 89
     if(!root) {
... ...
@@ -129,14 +134,31 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
129 129
 	if(bytes < SCANBUFF)
130 130
 	    length -= SCANBUFF - bytes;
131 131
 
132
-	if(cli_bm_scanbuff(pt, length, virname, root) == CL_VIRUS ||
133
-	   (ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, typerec, offset, partoff)) == CL_VIRUS) {
132
+	if(cli_bm_scanbuff(pt, length, virname, root, offset, &voffset) == CL_VIRUS ||
133
+	   (ret = cli_ac_scanbuff(pt, length, virname, root, partcnt, otfrec, offset, partoff, &voffset)) == CL_VIRUS) {
134 134
 	    free(buffer);
135 135
 	    free(partcnt);
136 136
 	    free(partoff);
137
+
138
+	    if(voffset.target) {
139
+		if(voffset.target >= TARGET_TABLE_SIZE) {
140
+		    cli_errmsg("Bad target (%d) in signature for %s\n", voffset.target, virname);
141
+		} else if(ftype && ftype != CL_TYPE_UNKNOWN_TEXT) {
142
+		    if(targettab[voffset.target] != ftype) {
143
+			cli_dbgmsg("Expected target type (%d) for %s != %d\n", voffset.target, virname, ftype);
144
+			return CL_CLEAN;
145
+		    }
146
+		} else if(type) {
147
+		    if(targettab[voffset.target] != type) {
148
+			cli_dbgmsg("Expected target type (%d) for %s != %d\n", voffset.target, virname, type);
149
+			return CL_CLEAN;
150
+		    }
151
+		}
152
+	    }
153
+
137 154
 	    return CL_VIRUS;
138 155
 
139
-	} else if(typerec && ret >= CL_TYPENO) {
156
+	} else if(otfrec && ret >= CL_TYPENO) {
140 157
 	    if(ret >= type)
141 158
 		type = ret;
142 159
 	}
... ...
@@ -177,7 +199,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
177 177
 	}
178 178
     }
179 179
 
180
-    return typerec ? type : CL_CLEAN;
180
+    return otfrec ? type : CL_CLEAN;
181 181
 }
182 182
 
183 183
 int cl_build(struct cl_node *root)
... ...
@@ -21,6 +21,12 @@
21 21
 
22 22
 #include "clamav.h"
23 23
 
24
-int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, int typerec);
24
+int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, short otfrec, unsigned short ftype);
25
+
26
+struct cli_voffset {
27
+    const char *offstr;
28
+    unsigned long int fileoff;
29
+    unsigned short target;
30
+};
25 31
 
26 32
 #endif
... ...
@@ -41,7 +41,7 @@
41 41
 
42 42
 /* TODO: clean up the code */
43 43
 
44
-static int cli_addsig(struct cl_node *root, const char *virname, const char *hexsig, int sigid, int parts, int partno, int type, unsigned int mindist, unsigned int maxdist)
44
+static int cli_ac_addsig(struct cl_node *root, const char *virname, const char *hexsig, int sigid, int parts, int partno, unsigned short type, unsigned int mindist, unsigned int maxdist, char *offset, unsigned short target)
45 45
 {
46 46
 	struct cli_ac_patt *new;
47 47
 	char *pt, *hex;
... ...
@@ -57,6 +57,8 @@ static int cli_addsig(struct cl_node *root, const char *virname, const char *hex
57 57
     new->partno = partno;
58 58
     new->mindist = mindist;
59 59
     new->maxdist = maxdist;
60
+    new->target = target;
61
+    new->offset = offset;
60 62
 
61 63
     if(strchr(hexsig, '(')) {
62 64
 	    char *hexcpy, *hexnew, *start, *h, *c;
... ...
@@ -223,7 +225,7 @@ static int cli_addsig(struct cl_node *root, const char *virname, const char *hex
223 223
     return 0;
224 224
 }
225 225
 
226
-int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig, int type)
226
+int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig, unsigned short type, char *offset, unsigned short target)
227 227
 {
228 228
 	struct cli_bm_patt *bm_new;
229 229
 	char *pt, *hexcpy, *start, *n;
... ...
@@ -254,7 +256,7 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
254 254
 		*pt++ = 0;
255 255
 	    }
256 256
 
257
-	    if((ret = cli_addsig(root, virname, start, root->ac_partsigs, parts, i, type, mindist, maxdist))) {
257
+	    if((ret = cli_ac_addsig(root, virname, start, root->ac_partsigs, parts, i, type, mindist, maxdist, offset, target))) {
258 258
 		cli_errmsg("cli_parse_add(): Problem adding signature.\n");
259 259
 		error = 1;
260 260
 		break;
... ...
@@ -281,7 +283,7 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
281 281
 		    break;
282 282
 		}
283 283
 	    } else {
284
-		if((n = cli_strtok(pt, 0, "-")) != NULL) {
284
+		if((n = cli_strtok(pt, 0, "-"))) {
285 285
 		    if((mindist = atoi(n)) < 0) {
286 286
 			error = 1;
287 287
 			free(n);
... ...
@@ -290,7 +292,7 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
290 290
 		    free(n);
291 291
 		}
292 292
 
293
-		if((n = cli_strtok(pt, 1, "-")) != NULL) {
293
+		if((n = cli_strtok(pt, 1, "-"))) {
294 294
 		    if((maxdist = atoi(n)) < 0) {
295 295
 			error = 1;
296 296
 			free(n);
... ...
@@ -322,7 +324,7 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
322 322
 		return CL_EMALFDB;
323 323
 	    }
324 324
 
325
-	    if((ret = cli_addsig(root, virname, pt, root->ac_partsigs, parts, i, type, 0, 0))) {
325
+	    if((ret = cli_ac_addsig(root, virname, pt, root->ac_partsigs, parts, i, type, 0, 0, offset, target))) {
326 326
 		cli_errmsg("cli_parse_add(): Problem adding signature.\n");
327 327
 		free(pt);
328 328
 		return ret;
... ...
@@ -332,7 +334,7 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
332 332
 	}
333 333
 
334 334
     } else if(strpbrk(hexsig, "?(") || type) {
335
-	if((ret = cli_addsig(root, virname, hexsig, 0, 0, 0, type, 0, 0))) {
335
+	if((ret = cli_ac_addsig(root, virname, hexsig, 0, 0, 0, type, 0, 0, offset, target))) {
336 336
 	    cli_errmsg("cli_parse_add(): Problem adding signature\n");
337 337
 	    return ret;
338 338
 	}
... ...
@@ -368,6 +370,9 @@ int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig,
368 368
 
369 369
 	strncpy(bm_new->virname, virname, virlen);
370 370
 
371
+	bm_new->offset = offset;
372
+	bm_new->target = target;
373
+
371 374
 	if(bm_new->length > root->maxpatlen)
372 375
 	    root->maxpatlen = bm_new->length;
373 376
 
... ...
@@ -430,11 +435,104 @@ static int cli_loaddb(FILE *fd, struct cl_node **root, unsigned int *signo)
430 430
 
431 431
 	if(*pt == '=') continue;
432 432
 
433
-	if((ret = cli_parse_add(*root, start, pt, 0))) {
433
+	if((ret = cli_parse_add(*root, start, pt, 0, NULL, 0))) {
434
+	    cli_errmsg("Problem parsing signature at line %d\n", line);
435
+	    ret = CL_EMALFDB;
436
+	    break;
437
+	}
438
+    }
439
+
440
+    if(!line) {
441
+	cli_errmsg("Empty database file\n");
442
+	cl_free(*root);
443
+	return CL_EMALFDB;
444
+    }
445
+
446
+    if(ret) {
447
+	cli_errmsg("Problem parsing database at line %d\n", line);
448
+	cl_free(*root);
449
+	return ret;
450
+    }
451
+
452
+    if(signo)
453
+	*signo += line;
454
+
455
+    return 0;
456
+}
457
+
458
+static int cli_loadndb(FILE *fd, struct cl_node **root, unsigned int *signo)
459
+{
460
+	char buffer[FILEBUFF], *sig, *virname, *offset, *pt;
461
+	int line = 0, ret = 0;
462
+	unsigned short target;
463
+
464
+
465
+    if(!*root) {
466
+	cli_dbgmsg("Initializing main node\n");
467
+	*root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
468
+	if(!*root)
469
+	    return CL_EMEM;
470
+    }
471
+
472
+    if(!(*root)->ac_root) {
473
+	cli_dbgmsg("Initializing trie\n");
474
+	(*root)->ac_root =  (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node));
475
+	if(!(*root)->ac_root) {
476
+	    free(*root);
477
+	    cli_errmsg("Can't initialise AC pattern matcher\n");
478
+	    return CL_EMEM;
479
+	}
480
+    }
481
+
482
+    if(!(*root)->bm_shift) {
483
+	cli_dbgmsg("Initializing BM tables\n");
484
+	if((ret = cli_bm_init(*root))) {
485
+	    cli_errmsg("Can't initialise BM pattern matcher\n");
486
+	    return ret;
487
+	}
488
+    }
489
+
490
+    while(fgets(buffer, FILEBUFF, fd)) {
491
+	line++;
492
+	cli_chomp(buffer);
493
+
494
+	if(!(virname = cli_strtok(buffer, 0, ":"))) {
495
+	    ret = CL_EMALFDB;
496
+	    break;
497
+	}
498
+
499
+	if(!(pt = cli_strtok(buffer, 1, ":")) || !isdigit(*pt)) {
500
+	    free(virname);
501
+	    ret = CL_EMALFDB;
502
+	    break;
503
+	}
504
+	target = (unsigned short) atoi(pt);
505
+	free(pt);
506
+
507
+	if(!(offset = cli_strtok(buffer, 2, ":"))) {
508
+	    free(virname);
509
+	    ret = CL_EMALFDB;
510
+	    break;
511
+	}
512
+
513
+	if(!(sig = cli_strtok(buffer, 3, ":"))) {
514
+	    free(virname);
515
+	    free(offset);
516
+	    ret = CL_EMALFDB;
517
+	    break;
518
+	}
519
+
520
+	if((ret = cli_parse_add(*root, virname, sig, 0, offset, target))) {
434 521
 	    cli_errmsg("Problem parsing signature at line %d\n", line);
522
+	    free(virname);
523
+	    free(offset);
524
+	    free(sig);
435 525
 	    ret = CL_EMALFDB;
436 526
 	    break;
437 527
 	}
528
+
529
+	free(virname);
530
+	free(sig);
438 531
     }
439 532
 
440 533
     if(!line) {
... ...
@@ -444,6 +542,7 @@ static int cli_loaddb(FILE *fd, struct cl_node **root, unsigned int *signo)
444 444
     }
445 445
 
446 446
     if(ret) {
447
+	cli_errmsg("Problem parsing database at line %d\n", line);
447 448
 	cl_free(*root);
448 449
 	return ret;
449 450
     }
... ...
@@ -531,6 +630,7 @@ static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo)
531 531
     }
532 532
 
533 533
     if(ret) {
534
+	cli_errmsg("Problem parsing database at line %d\n", line);
534 535
 	cl_free(*root);
535 536
 	return ret;
536 537
     }
... ...
@@ -563,6 +663,9 @@ int cl_loaddb(const char *filename, struct cl_node **root, unsigned int *signo)
563 563
     } else if(cli_strbcasestr(filename, ".hdb")) {
564 564
 	ret = cli_loadhdb(fd, root, signo);
565 565
 
566
+    } else if(cli_strbcasestr(filename, ".ndb")) {
567
+	ret = cli_loadndb(fd, root, signo);
568
+
566 569
     } else {
567 570
 	cli_dbgmsg("cl_loaddb: unknown extension - assuming old database format\n");
568 571
 	ret = cli_loaddb(fd, root, signo);
... ...
@@ -600,6 +703,7 @@ int cl_loaddbdir(const char *dirname, struct cl_node **root, unsigned int *signo
600 600
 	     cli_strbcasestr(dent->d_name, ".db2") ||
601 601
 	     cli_strbcasestr(dent->d_name, ".db3") ||
602 602
 	     cli_strbcasestr(dent->d_name, ".hdb") ||
603
+	     cli_strbcasestr(dent->d_name, ".ndb") ||
603 604
 	     cli_strbcasestr(dent->d_name, ".cvd"))) {
604 605
 
605 606
 		dbfile = (char *) cli_calloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char));
... ...
@@ -663,6 +767,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
663 663
 	    cli_strbcasestr(dent->d_name, ".db2")  || 
664 664
 	    cli_strbcasestr(dent->d_name, ".db3")  || 
665 665
 	    cli_strbcasestr(dent->d_name, ".hdb")  || 
666
+	    cli_strbcasestr(dent->d_name, ".ndb")  || 
666 667
 	    cli_strbcasestr(dent->d_name, ".cvd"))) {
667 668
 
668 669
 		dbstat->no++;
... ...
@@ -710,6 +815,7 @@ int cl_statchkdir(const struct cl_stat *dbstat)
710 710
 	    cli_strbcasestr(dent->d_name, ".db2")  || 
711 711
 	    cli_strbcasestr(dent->d_name, ".db3")  || 
712 712
 	    cli_strbcasestr(dent->d_name, ".hdb")  || 
713
+	    cli_strbcasestr(dent->d_name, ".ndb")  || 
713 714
 	    cli_strbcasestr(dent->d_name, ".cvd"))) {
714 715
 
715 716
                 fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2, sizeof(char));
... ...
@@ -19,6 +19,6 @@
19 19
 #ifndef __READDB_H
20 20
 #define __READDB_H
21 21
 
22
-int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig, int type);
22
+int cli_parse_add(struct cl_node *root, const char *virname, const char *hexsig, unsigned short type, char *offset, unsigned short target);
23 23
 
24 24
 #endif
... ...
@@ -134,7 +134,7 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const
134 134
 	    files++;
135 135
 	    cli_dbgmsg("RAR: Encrypted files found in archive.\n");
136 136
 	    lseek(desc, 0, SEEK_SET);
137
-	    if(cli_scandesc(desc, virname, scanned, root, 0) != CL_VIRUS)
137
+	    if(cli_scandesc(desc, virname, scanned, root, 0, 0) != CL_VIRUS)
138 138
 		*virname = "Encrypted.RAR";
139 139
 	    ret = CL_VIRUS;
140 140
 	    break;
... ...
@@ -325,7 +325,7 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const
325 325
 	    files++;
326 326
 	    cli_dbgmsg("Zip: Encrypted files found in archive.\n");
327 327
 	    lseek(desc, 0, SEEK_SET);
328
-	    if(cli_scandesc(desc, virname, scanned, root, 0) != CL_VIRUS)
328
+	    if(cli_scandesc(desc, virname, scanned, root, 0, 0) != CL_VIRUS)
329 329
 		*virname = "Encrypted.Zip";
330 330
 	    ret = CL_VIRUS;
331 331
 	    break;
... ...
@@ -705,7 +705,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
705 705
     snprintf(fullname, 1024, "%s/comment.html", tempname);
706 706
     fd = open(fullname, O_RDONLY);
707 707
     if (fd >= 0) {
708
-        ret = cli_scandesc(fd, virname, scanned, root, 0);
708
+        ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML);
709 709
 	close(fd);
710 710
     }
711 711
 
... ...
@@ -713,7 +713,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
713 713
 	snprintf(fullname, 1024, "%s/nocomment.html", tempname);
714 714
 	fd = open(fullname, O_RDONLY);
715 715
 	if (fd >= 0) {
716
-	    ret = cli_scandesc(fd, virname, scanned, root, 0);
716
+	    ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML);
717 717
 	    close(fd);
718 718
 	}
719 719
     }
... ...
@@ -722,7 +722,7 @@ static int cli_scanhtml(int desc, const char **virname, long int *scanned, const
722 722
 	snprintf(fullname, 1024, "%s/script.html", tempname);
723 723
 	fd = open(fullname, O_RDONLY);
724 724
 	if (fd >= 0) {
725
-	    ret = cli_scandesc(fd, virname, scanned, root, 0);
725
+	    ret = cli_scandesc(fd, virname, scanned, root, 0, CL_TYPE_HTML);
726 726
 	    close(fd);
727 727
 	}
728 728
     }
... ...
@@ -1138,8 +1138,8 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
1138 1138
     }
1139 1139
 
1140 1140
     if(!options) { /* raw mode (stdin, etc.) */
1141
-	cli_dbgmsg("Raw mode: no support for archives.\n");
1142
-	if((ret = cli_scandesc(desc, virname, scanned, root, 0) == CL_VIRUS))
1141
+	cli_dbgmsg("Raw mode: No support for special files\n");
1142
+	if((ret = cli_scandesc(desc, virname, scanned, root, 0, 0) == CL_VIRUS))
1143 1143
 	    cli_dbgmsg("%s found in descriptor %d\n", *virname, desc);
1144 1144
 	return ret;
1145 1145
     }
... ...
@@ -1255,7 +1255,7 @@ int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const
1255 1255
 	type == CL_TYPE_UNKNOWN_TEXT ? (typerec = 1) : (typerec = 0);
1256 1256
 	lseek(desc, 0, SEEK_SET);
1257 1257
 
1258
-	if((nret = cli_scandesc(desc, virname, scanned, root, typerec)) == CL_VIRUS) {
1258
+	if((nret = cli_scandesc(desc, virname, scanned, root, typerec, type)) == CL_VIRUS) {
1259 1259
 	    cli_dbgmsg("%s found in descriptor %d.\n", *virname, desc);
1260 1260
 	    return CL_VIRUS;
1261 1261