Browse code

scanners to fmap - hackish peheader to fmap lacks review + elf + macho

aCaB authored on 2009/09/01 20:49:36
Showing 11 changed files
... ...
@@ -143,10 +143,10 @@ cli_file_t cli_filetype(const unsigned char *buf, size_t buflen, const struct cl
143 143
 
144 144
 int is_tar(unsigned char *buf, unsigned int nbytes);
145 145
 
146
-cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
146
+cli_file_t cli_filetype2(struct F_MAP *map, const struct cl_engine *engine)
147 147
 {
148
-	unsigned char buff[MAGIC_BUFFER_SIZE + 1], *decoded;
149
-	int bread, sret;
148
+	unsigned char *buff, *decoded;
149
+	int bread = MIN(map->len, MAGIC_BUFFER_SIZE), sret;
150 150
 	cli_file_t ret = CL_TYPE_BINARY_DATA;
151 151
 	struct cli_matcher *root;
152 152
 	struct cli_ac_data mdata;
... ...
@@ -157,11 +157,9 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
157 157
 	return CL_TYPE_ERROR;
158 158
     }
159 159
 
160
-    memset(buff, 0, sizeof(buff));
161
-    bread = cli_readn(desc, buff, MAGIC_BUFFER_SIZE);
162
-    if(bread == -1)
160
+    buff = fmap_need_off_once(map, 0, bread);
161
+    if(!buff)
163 162
 	return CL_TYPE_ERROR;
164
-    buff[bread] = 0;
165 163
 
166 164
     ret = cli_filetype(buff, bread, engine);
167 165
 
... ...
@@ -25,6 +25,7 @@
25 25
 
26 26
 #include "clamav.h"
27 27
 #include "cltypes.h"
28
+#include "fmap.h"
28 29
 
29 30
 #define MAGIC_BUFFER_SIZE 1024
30 31
 #define CL_TYPENO 500
... ...
@@ -105,7 +106,7 @@ struct cli_matched_type {
105 105
 cli_file_t cli_ftcode(const char *name);
106 106
 void cli_ftfree(const struct cl_engine *engine);
107 107
 cli_file_t cli_filetype(const unsigned char *buf, size_t buflen, const struct cl_engine *engine);
108
-cli_file_t cli_filetype2(int desc, const struct cl_engine *engine);
108
+cli_file_t cli_filetype2(struct F_MAP *map, const struct cl_engine *engine);
109 109
 int cli_addtypesigs(struct cl_engine *engine);
110 110
 
111 111
 #endif
... ...
@@ -830,7 +830,7 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
830 830
     return CL_SUCCESS;
831 831
 }
832 832
 
833
-int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int fd)
833
+int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, struct F_MAP *map)
834 834
 {
835 835
 	int ret;
836 836
 	unsigned int i;
... ...
@@ -838,20 +838,16 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
838 838
 	struct cli_target_info info;
839 839
 	struct stat sb;
840 840
 
841
-    if(fd != -1) {
841
+    if(map) {
842 842
 	memset(&info, 0, sizeof(info));
843
-	if(fstat(fd, &sb) == -1) {
844
-	    cli_errmsg("cli_ac_caloff: fstat(%d) failed\n", fd);
845
-	    return CL_ESTAT;
846
-	}
847
-	info.fsize = sb.st_size;
843
+	info.fsize = map->len;
848 844
     }
849 845
 
850 846
     for(i = 0; i < root->ac_reloff_num; i++) {
851 847
 	patt = root->ac_reloff[i];
852
-	if(fd == -1) {
848
+	if(!map) {
853 849
 	    data->offset[patt->offset_min] = CLI_OFF_NONE;
854
-	} else if((ret = cli_caloff(NULL, &info, fd, root->type, patt->offdata, &data->offset[patt->offset_min], &data->offset[patt->offset_max]))) {
850
+	} else if((ret = cli_caloff(NULL, &info, map, root->type, patt->offdata, &data->offset[patt->offset_min], &data->offset[patt->offset_max]))) {
855 851
 	    cli_errmsg("cli_ac_caloff: Can't calculate relative offset in signature for %s\n", patt->virname);
856 852
 	    if(info.exeinfo.section)
857 853
 		free(info.exeinfo.section);
... ...
@@ -860,7 +856,7 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
860 860
 	    data->offset[patt->offset_min] = CLI_OFF_NONE;
861 861
 	}
862 862
     }
863
-    if(fd != -1 && info.exeinfo.section)
863
+    if(map && info.exeinfo.section)
864 864
 	free(info.exeinfo.section);
865 865
 
866 866
     return CL_SUCCESS;
... ...
@@ -25,6 +25,7 @@
25 25
 
26 26
 #include "filetypes.h"
27 27
 #include "cltypes.h"
28
+#include "fmap.h"
28 29
 
29 30
 #define AC_CH_MAXDIST 32
30 31
 
... ...
@@ -86,7 +87,7 @@ void cli_ac_freedata(struct cli_ac_data *data);
86 86
 int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx);
87 87
 int cli_ac_buildtrie(struct cli_matcher *root);
88 88
 int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth);
89
-int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int fd);
89
+int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, struct F_MAP *map);
90 90
 void cli_ac_free(struct cli_matcher *root);
91 91
 int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, const uint32_t *lsigid, unsigned int options);
92 92
 
... ...
@@ -51,7 +51,7 @@ int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const
51 51
 	return CL_EMALFDB;
52 52
     }
53 53
 
54
-    if((ret = cli_caloff(offset, NULL, -1, root->type, pattern->offdata, &pattern->offset_min, &pattern->offset_max))) {
54
+    if((ret = cli_caloff(offset, NULL, NULL, root->type, pattern->offdata, &pattern->offset_min, &pattern->offset_max))) {
55 55
 	cli_errmsg("cli_bm_addpatt: Can't calculate offset for signature %s\n", pattern->virname);
56 56
 	return ret;
57 57
     }
... ...
@@ -156,7 +156,7 @@ void cli_bm_free(struct cli_matcher *root)
156 156
     }
157 157
 }
158 158
 
159
-int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd)
159
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, struct F_MAP *map)
160 160
 {
161 161
 	uint32_t i, j, off, off_min, off_max;
162 162
 	uint8_t found, pchain, shift;
... ...
@@ -229,7 +229,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
229 229
 		if(found && p->length + p->prefix_length == j) {
230 230
 		    if(p->offset_min != CLI_OFF_ANY) {
231 231
 			if(p->offdata[0] != CLI_OFF_ABSOLUTE) {
232
-			    ret = cli_caloff(NULL, &info, fd, root->type, p->offdata, &off_min, &off_max);
232
+			    ret = cli_caloff(NULL, &info, map, root->type, p->offdata, &off_min, &off_max);
233 233
 			    if(ret != CL_SUCCESS) {
234 234
 				cli_errmsg("cli_bm_scanbuff: Can't calculate relative offset in signature for %s\n", p->virname);
235 235
 				if(info.exeinfo.section)
... ...
@@ -24,6 +24,7 @@
24 24
 #include "matcher.h"
25 25
 #include "filetypes.h"
26 26
 #include "cltypes.h"
27
+#include "fmap.h"
27 28
 
28 29
 struct cli_bm_patt {
29 30
     unsigned char *pattern, *prefix;
... ...
@@ -37,7 +38,7 @@ struct cli_bm_patt {
37 37
 
38 38
 int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const char *offset);
39 39
 int cli_bm_init(struct cli_matcher *root);
40
-int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd);
40
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, struct F_MAP *map);
41 41
 void cli_bm_free(struct cli_matcher *root);
42 42
 
43 43
 #endif
... ...
@@ -45,6 +45,7 @@
45 45
 #include "cltypes.h"
46 46
 #include "default.h"
47 47
 #include "macho.h"
48
+#include "fmap.h"
48 49
 
49 50
 int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata)
50 51
 {
... ...
@@ -76,7 +77,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
76 76
 	if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
77 77
 	    return ret;
78 78
 
79
-	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, -1)) != CL_VIRUS)
79
+	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, NULL)) != CL_VIRUS)
80 80
 	    ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, troot, acdata ? (acdata[0]) : (&mdata), offset, ftype, NULL, AC_SCAN_VIR, NULL);
81 81
 
82 82
 	if(!acdata)
... ...
@@ -89,7 +90,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
89 89
     if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
90 90
 	return ret;
91 91
 
92
-    if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, -1)) != CL_VIRUS)
92
+    if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, NULL)) != CL_VIRUS)
93 93
 	ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, groot, acdata ? (acdata[1]) : (&mdata), offset, ftype, NULL, AC_SCAN_VIR, NULL);
94 94
 
95 95
     if(!acdata)
... ...
@@ -104,9 +105,9 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
104 104
  * offdata[2]: max shift
105 105
  * offdata[3]: section number
106 106
  */
107
-int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max)
107
+int cli_caloff(const char *offstr, struct cli_target_info *info, struct F_MAP *map, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max)
108 108
 {
109
-	int (*einfo)(int, struct cli_exe_info *) = NULL;
109
+	int (*einfo)(struct F_MAP *, struct cli_exe_info *) = NULL;
110 110
 	char offcpy[65];
111 111
 	unsigned int n, val;
112 112
 	char *pt;
... ...
@@ -206,14 +207,8 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
206 206
 	}
207 207
 
208 208
 	if((offdata[0] == CLI_OFF_EOF_MINUS)) {
209
-	    if(!info->fsize) {
210
-		if(fstat(fd, &sb) == -1) {
211
-		    cli_errmsg("cli_caloff: fstat(%d) failed\n", fd);
212
-		    return CL_ESTAT;
213
-		}
214
-		info->fsize = sb.st_size;
215
-	    }
216
-
209
+	    if(!info->fsize)
210
+		info->fsize = map->len;
217 211
 	} else if(!info->status) {
218 212
 	    if(target == 1)
219 213
 		einfo = cli_peheader;
... ...
@@ -227,20 +222,12 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigne
227 227
 		return CL_EMALFDB;
228 228
 	    }
229 229
 
230
-	    if((pos = lseek(fd, 0, SEEK_CUR)) == -1) {
231
-		cli_errmsg("cli_caloff: lseek(%d) failed\n", fd);
232
-		return CL_ESEEK;
233
-	    }
234
-
235
-	    lseek(fd, 0, SEEK_SET);
236
-	    if(einfo(fd, &info->exeinfo)) {
230
+	    if(einfo(map, &info->exeinfo)) {
237 231
 		/* einfo *may* fail */
238
-		lseek(fd, pos, SEEK_SET);
239 232
 		info->status = -1;
240 233
 		*offset_min = *offset_max = 0;
241 234
 		return CL_SUCCESS;
242 235
 	    }
243
-	    lseek(fd, pos, SEEK_SET);
244 236
 	    info->status = 1;
245 237
 	}
246 238
 
... ...
@@ -303,7 +290,7 @@ int cli_checkfp(int fd, cli_ctx *ctx)
303 303
 	    return 0;
304 304
 	}
305 305
 
306
-	if(cli_bm_scanbuff(digest, 16, &virname, ctx->engine->md5_fp, 0, -1) == CL_VIRUS) {
306
+	if(cli_bm_scanbuff(digest, 16, &virname, ctx->engine->md5_fp, 0, NULL) == CL_VIRUS) {
307 307
 	    cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname);
308 308
 	    free(digest);
309 309
 	    lseek(fd, pos, SEEK_SET);
... ...
@@ -318,185 +305,15 @@ int cli_checkfp(int fd, cli_ctx *ctx)
318 318
 
319 319
 int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode)
320 320
 {
321
- 	unsigned char *buffer, *buff, *endbl, *upt;
322
-	int ret = CL_CLEAN, type = CL_CLEAN, bytes;
323
-	unsigned int i, evalcnt;
324
-	uint32_t buffersize, length, maxpatlen, shift = 0, offset = 0;
325
-	uint64_t evalids;
326
-	struct cli_ac_data gdata, tdata;
327
-	cli_md5_ctx md5ctx;
328
-	unsigned char digest[16];
329
-	struct cli_matcher *groot = NULL, *troot = NULL;
330
-
331
-
332
-    if(!ctx->engine) {
333
-	cli_errmsg("cli_scandesc: engine == NULL\n");
334
-	return CL_ENULLARG;
335
-    }
336
-
337
-    if(!ftonly)
338
-	groot = ctx->engine->root[0]; /* generic signatures */
339
-
340
-    if(ftype) {
341
-	for(i = 1; i < CLI_MTARGETS; i++) {
342
-	    if(cli_mtargets[i].target == ftype) {
343
-		troot = ctx->engine->root[i];
344
-		break;
345
-	    }
346
-	}
347
-    }
348
-
349
-    if(ftonly) {
350
-	if(!troot)
351
-	    return CL_CLEAN;
352
-
353
-	maxpatlen = troot->maxpatlen;
354
-    } else {
355
-	if(troot)
356
-	    maxpatlen = MAX(troot->maxpatlen, groot->maxpatlen);
357
-	else
358
-	    maxpatlen = groot->maxpatlen;
359
-    }
360
-
361
-    /* prepare the buffer */
362
-    buffersize = maxpatlen + SCANBUFF;
363
-    if(!(buffer = (unsigned char *) cli_calloc(buffersize, sizeof(unsigned char)))) {
364
-	cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%u)\n", buffersize);
365
-	return CL_EMEM;
366
-    }
367
-
368
-    if(!ftonly)
369
-	if((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(groot, &gdata, desc)))
370
-	    return ret;
371
-
372
-    if(troot) {
373
-	if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(troot, &tdata, desc))) {
374
-	    if(!ftonly)
375
-		cli_ac_freedata(&gdata);
376
-	    return ret;
377
-	}
378
-    }
379
-
380
-    if(!ftonly && ctx->engine->md5_hdb)
381
-	cli_md5_init(&md5ctx);
382
-
383
-    buff = buffer;
384
-    buff += maxpatlen; /* pointer to read data block */
385
-    endbl = buff + SCANBUFF - maxpatlen; /* pointer to the last block
386
-					  * length of maxpatlen
387
-					  */
388
-
389
-    upt = buff;
390
-    while((bytes = cli_readn(desc, buff + shift, SCANBUFF - shift)) > 0) {
391
-
392
-	if(ctx->scanned)
393
-	    *ctx->scanned += bytes / CL_COUNT_PRECISION;
394
-
395
-	length = shift + bytes;
396
-	if(upt == buffer)
397
-	    length += maxpatlen;
398
-
399
-	if(troot) {
400
-	    if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, desc)) != CL_VIRUS)
401
-		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, ftoffset, acmode, NULL);
402
-
403
-	    if(ret == CL_VIRUS) {
404
-		free(buffer);
405
-		if(!ftonly)
406
-		    cli_ac_freedata(&gdata);
407
-		cli_ac_freedata(&tdata);
408
-
409
-		if(cli_checkfp(desc, ctx))
410
-		    return CL_CLEAN;
411
-		else
412
-		    return CL_VIRUS;
413
-	    }
414
-	}
415
-
416
-	if(!ftonly) {
417
-	    if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, desc)) != CL_VIRUS)
418
-		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, ftoffset, acmode, NULL);
419
-
420
-	    if(ret == CL_VIRUS) {
421
-		free(buffer);
422
-		cli_ac_freedata(&gdata);
423
-		if(troot)
424
-		    cli_ac_freedata(&tdata);
425
-		if(cli_checkfp(desc, ctx))
426
-		    return CL_CLEAN;
427
-		else
428
-		    return CL_VIRUS;
429
-
430
-	    } else if((acmode & AC_SCAN_FT) && ret >= CL_TYPENO) {
431
-		if(ret > type)
432
-		    type = ret;
433
-	    }
434
-
435
-	    if(ctx->engine->md5_hdb)
436
-		cli_md5_update(&md5ctx, buff + shift, bytes);
437
-	}
438
-
439
-	if(bytes + shift == SCANBUFF) {
440
-	    memmove(buffer, endbl, maxpatlen);
441
-	    offset += SCANBUFF;
442
-
443
-	    if(upt == buff) {
444
-		upt = buffer;
445
-		offset -= maxpatlen;
446
-	    }
447
-
448
-	    shift = 0;
449
-
450
-	} else {
451
-	    shift += bytes;
452
-	}
453
-    }
454
-
455
-    free(buffer);
456
-
457
-    if(troot) {
458
-	for(i = 0; i < troot->ac_lsigs; i++) {
459
-	    evalcnt = 0;
460
-	    evalids = 0;
461
-	    if(cli_ac_chklsig(troot->ac_lsigtable[i]->logic, troot->ac_lsigtable[i]->logic + strlen(troot->ac_lsigtable[i]->logic), tdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) {
462
-		if(ctx->virname)
463
-		    *ctx->virname = troot->ac_lsigtable[i]->virname;
464
-		ret = CL_VIRUS;
465
-		break;
466
-	    }
467
-	}
468
-	cli_ac_freedata(&tdata);
469
-    }
470
-
471
-    if(groot) {
472
-	if(ret != CL_VIRUS) for(i = 0; i < groot->ac_lsigs; i++) {
473
-	    evalcnt = 0;
474
-	    evalids = 0;
475
-	    if(cli_ac_chklsig(groot->ac_lsigtable[i]->logic, groot->ac_lsigtable[i]->logic + strlen(groot->ac_lsigtable[i]->logic), gdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) {
476
-		if(ctx->virname)
477
-		    *ctx->virname = groot->ac_lsigtable[i]->virname;
478
-		ret = CL_VIRUS;
479
-		break;
480
-	    }
481
-	}
482
-	cli_ac_freedata(&gdata);
483
-    }
484
-
485
-    if(ret == CL_VIRUS) {
486
-	lseek(desc, 0, SEEK_SET);
487
-	if(cli_checkfp(desc, ctx))
488
-	    return CL_CLEAN;
489
-	else
490
-	    return CL_VIRUS;
491
-    }
321
+    int ret = CL_EMEM;
322
+    struct F_MAP *map = *ctx->fmap;
492 323
 
493
-    if(!ftonly && ctx->engine->md5_hdb) {
494
-	cli_md5_final(digest, &md5ctx);
495
-	if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, -1) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS))
496
-	    return CL_VIRUS;
324
+    if(!(*ctx->fmap = fmap(desc, 0, 0))) {
325
+	ret = cli_fmap_scandesc(ctx, ftype, ftonly, ftoffset, acmode);
326
+	fmunmap(map);
497 327
     }
498
-
499
-    return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
328
+    *ctx->fmap = map;
329
+    return ret;
500 330
 }
501 331
 
502 332
 
... ...
@@ -543,11 +360,11 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
543 543
     }
544 544
 
545 545
     if(!ftonly)
546
-	if((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(groot, &gdata, map->fd)))
546
+	if((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(groot, &gdata, map)))
547 547
 	    return ret;
548 548
 
549 549
     if(troot) {
550
-	if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(troot, &tdata, map->fd))) {
550
+	if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(troot, &tdata, map))) {
551 551
 	    if(!ftonly)
552 552
 		cli_ac_freedata(&gdata);
553 553
 	    return ret;
... ...
@@ -566,7 +383,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
566 566
 	    *ctx->scanned += bytes / CL_COUNT_PRECISION;
567 567
 
568 568
 	if(troot) {
569
-	    if(troot->ac_only || (ret = cli_bm_scanbuff(buff, bytes, ctx->virname, troot, offset, map->fd)) != CL_VIRUS)
569
+	    if(troot->ac_only || (ret = cli_bm_scanbuff(buff, bytes, ctx->virname, troot, offset, map)) != CL_VIRUS)
570 570
 		ret = cli_ac_scanbuff(buff, bytes, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, ftoffset, acmode, NULL);
571 571
 
572 572
 	    if(ret == CL_VIRUS) {
... ...
@@ -582,7 +399,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
582 582
 	}
583 583
 
584 584
 	if(!ftonly) {
585
-	    if(groot->ac_only || (ret = cli_bm_scanbuff(buff, bytes, ctx->virname, groot, offset, map->fd)) != CL_VIRUS)
585
+	    if(groot->ac_only || (ret = cli_bm_scanbuff(buff, bytes, ctx->virname, groot, offset, map)) != CL_VIRUS)
586 586
 		ret = cli_ac_scanbuff(buff, bytes, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, ftoffset, acmode, NULL);
587 587
 
588 588
 	    if(ret == CL_VIRUS) {
... ...
@@ -645,7 +462,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
645 645
 
646 646
     if(!ftonly && ctx->engine->md5_hdb) {
647 647
 	cli_md5_final(digest, &md5ctx);
648
-	if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, -1) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, -1) != CL_VIRUS))
648
+	if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, NULL) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, NULL) != CL_VIRUS))
649 649
 	    return CL_VIRUS;
650 650
     }
651 651
 
... ...
@@ -33,7 +33,7 @@
33 33
 #include "matcher-ac.h"
34 34
 #include "matcher-bm.h"
35 35
 #include "hashtab.h"
36
-
36
+#include "fmap.h"
37 37
 #include "mpool.h"
38 38
 
39 39
 #define CLI_MATCH_WILDCARD	0xff00
... ...
@@ -142,7 +142,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
142 142
 int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode);
143 143
 int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode);
144 144
 
145
-int cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
145
+int cli_caloff(const char *offstr, struct cli_target_info *info, struct F_MAP *map, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
146 146
 
147 147
 int cli_checkfp(int fd, cli_ctx *ctx);
148 148
 
... ...
@@ -38,7 +38,6 @@
38 38
 #include "cltypes.h"
39 39
 #include "clamav.h"
40 40
 #include "others.h"
41
-#include "fmap.h"
42 41
 #include "pe.h"
43 42
 #include "petite.h"
44 43
 #include "fsg.h"
... ...
@@ -985,7 +984,6 @@ int cli_scanpe(cli_ctx *ctx)
985 985
 
986 986
     CLI_UNPTEMP("DISASM",(exe_sections,0));
987 987
     disasmbuf((unsigned char*)epbuff, epsize, ndesc);
988
-    lseek(ndesc, 0, SEEK_SET);
989 988
     ret = cli_scandesc(ndesc, ctx, CL_TYPE_PE_DISASM, 1, NULL, AC_SCAN_VIR);
990 989
     close(ndesc);
991 990
     CLI_TMPUNLK();
... ...
@@ -2153,7 +2151,7 @@ int cli_scanpe(cli_ctx *ctx)
2153 2153
     return CL_CLEAN;
2154 2154
 }
2155 2155
 
2156
-int cli_peheader(int desc, struct cli_exe_info *peinfo)
2156
+int cli_peheader(struct F_MAP *map, struct cli_exe_info *peinfo)
2157 2157
 {
2158 2158
 	uint16_t e_magic; /* DOS signature ("MZ") */
2159 2159
 	uint32_t e_lfanew; /* address of new exe header */
... ...
@@ -2171,19 +2169,14 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2171 2171
 	unsigned int err, pe_plus = 0;
2172 2172
 	uint32_t valign, falign, hdr_size;
2173 2173
 	size_t fsize;
2174
+	ssize_t at;
2174 2175
 
2175 2176
     cli_dbgmsg("in cli_peheader\n");
2176 2177
 
2177
-    if(fstat(desc, &sb) == -1) {
2178
-	cli_dbgmsg("fstat failed\n");
2179
-	return -1;
2180
-    }
2181
-
2182
-    fsize = sb.st_size - peinfo->offset;
2183
-
2184
-    if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
2178
+    fsize = map->len - peinfo->offset;
2179
+    if(fmap_readn(map, &e_magic, peinfo->offset, sizeof(e_magic)) != sizeof(e_magic)) {
2185 2180
 	cli_dbgmsg("Can't read DOS signature\n");
2186
-	return -1;
2181
+	return CL_CLEAN;
2187 2182
     }
2188 2183
 
2189 2184
     if(EC16(e_magic) != IMAGE_DOS_SIGNATURE && EC16(e_magic) != IMAGE_DOS_SIGNATURE_OLD) {
... ...
@@ -2191,10 +2184,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2191 2191
 	return -1;
2192 2192
     }
2193 2193
 
2194
-    lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
2195
-
2196
-    if(cli_readn(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
2197
-	cli_dbgmsg("Can't read new header address\n");
2194
+    if(fmap_readn(map, &e_lfanew, peinfo->offset + 58 + sizeof(e_magic), sizeof(e_lfanew)) != sizeof(e_lfanew)) {
2198 2195
 	/* truncated header? */
2199 2196
 	return -1;
2200 2197
     }
... ...
@@ -2205,13 +2195,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2205 2205
 	return -1;
2206 2206
     }
2207 2207
 
2208
-    if(lseek(desc, peinfo->offset + e_lfanew, SEEK_SET) < 0) {
2209
-	/* probably not a PE file */
2210
-	cli_dbgmsg("Can't lseek to e_lfanew\n");
2211
-	return -1;
2212
-    }
2213
-
2214
-    if(cli_readn(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
2208
+    if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
2215 2209
 	/* bad information in e_lfanew - probably not a PE file */
2216 2210
 	cli_dbgmsg("Can't read file header\n");
2217 2211
 	return -1;
... ...
@@ -2229,26 +2213,29 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2229 2229
 	return -1;
2230 2230
     }
2231 2231
 
2232
-    if(cli_readn(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
2232
+    at = peinfo->offset + e_lfanew + sizeof(struct pe_image_file_hdr);
2233
+    if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
2233 2234
         cli_dbgmsg("Can't read optional file header\n");
2234 2235
 	return -1;
2235 2236
     }
2237
+    at += sizeof(struct pe_image_optional_hdr32);
2236 2238
 
2237 2239
     if(EC16(optional_hdr64.Magic)==PE32P_SIGNATURE) { /* PE+ */
2238 2240
         if(EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr64)) {
2239 2241
 	    cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
2240 2242
 	    return -1;
2241 2243
 	}
2242
-        if(cli_readn(desc, &optional_hdr32 + 1, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
2244
+	if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
2243 2245
 	    cli_dbgmsg("Can't read optional file header\n");
2244 2246
 	    return -1;
2245 2247
 	}
2248
+	at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
2246 2249
 	hdr_size = EC32(optional_hdr64.SizeOfHeaders);
2247 2250
 	pe_plus=1;
2248 2251
     } else { /* PE */
2249 2252
 	if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
2250 2253
 	    /* Seek to the end of the long header */
2251
-	    lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR);
2254
+	    at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
2252 2255
 	}
2253 2256
 	hdr_size = EC32(optional_hdr32.SizeOfHeaders);
2254 2257
     }
... ...
@@ -2274,7 +2261,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2274 2274
 	return -1;
2275 2275
     }
2276 2276
 
2277
-    if(cli_readn(desc, section_hdr, peinfo->nsections * sizeof(struct pe_image_section_hdr)) != peinfo->nsections * sizeof(struct pe_image_section_hdr)) {
2277
+    if(fmap_readn(map, section_hdr, at, peinfo->nsections * sizeof(struct pe_image_section_hdr)) != peinfo->nsections * sizeof(struct pe_image_section_hdr)) {
2278 2278
         cli_dbgmsg("Can't read section header\n");
2279 2279
 	cli_dbgmsg("Possibly broken PE file\n");
2280 2280
 	free(section_hdr);
... ...
@@ -2282,6 +2269,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2282 2282
 	peinfo->section = NULL;
2283 2283
 	return -1;
2284 2284
     }
2285
+    at += sizeof(struct pe_image_section_hdr)*peinfo->nsections;
2285 2286
 
2286 2287
     for(i = 0; falign!=0x200 && i<peinfo->nsections; i++) {
2287 2288
 	/* file alignment fallback mode - blah */
... ...
@@ -25,6 +25,7 @@
25 25
 #include "execs.h"
26 26
 #include "others.h"
27 27
 #include "cltypes.h"
28
+#include "fmap.h"
28 29
 
29 30
 struct pe_image_file_hdr {
30 31
     uint32_t Magic;
... ...
@@ -130,6 +131,6 @@ struct pe_image_section_hdr {
130 130
 
131 131
 int cli_scanpe(cli_ctx *ctx);
132 132
 
133
-int cli_peheader(int desc, struct cli_exe_info *peinfo);
133
+int cli_peheader(struct F_MAP *map, struct cli_exe_info *peinfo);
134 134
 
135 135
 #endif
... ...
@@ -1791,7 +1791,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
1791 1791
 			    memset(&peinfo, 0, sizeof(struct cli_exe_info));
1792 1792
 			    peinfo.offset = fpt->offset;
1793 1793
 			    lseek(map->fd, fpt->offset, SEEK_SET);
1794
-			    if(cli_peheader(map->fd, &peinfo) == 0) {
1794
+			    if(cli_peheader(map, &peinfo) == 0) {
1795 1795
 				cli_dbgmsg("*** Detected embedded PE file at %u ***\n", (unsigned int) fpt->offset);
1796 1796
 				if(peinfo.section)
1797 1797
 				    free(peinfo.section);
... ...
@@ -1904,8 +1904,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
1904 1904
 	return ret;
1905 1905
     }
1906 1906
 
1907
-    lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
1908
-    type = cli_filetype2(desc, ctx->engine); /* FIXMEFMAP: port to fmap */
1907
+    type = cli_filetype2(*ctx->fmap, ctx->engine); /* FIXMEFMAP: port to fmap */
1909 1908
     if(type == CL_TYPE_ERROR) {
1910 1909
 	cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n");
1911 1910
 	fmunmap(*ctx->fmap);