... | ... |
@@ -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); |