From 6038397ea6451e0d25223cc41bae9653f7cab164 Mon Sep 17 00:00:00 2001 From: Tomasz Kojm Date: Wed, 20 Feb 2008 22:04:48 +0000 Subject: [PATCH] filetype detection improvements git-svn: trunk@3662 --- ChangeLog | 14 +++ libclamav/blob.c | 2 +- libclamav/filetypes.c | 9 +- libclamav/filetypes.h | 8 +- libclamav/filetypes_int.h | 202 +++++++++++++++++++------------------- libclamav/matcher-ac.c | 75 ++++++++------ libclamav/matcher-ac.h | 9 +- libclamav/matcher.c | 14 +-- libclamav/matcher.h | 2 +- libclamav/nsis/nulsft.c | 2 +- libclamav/readdb.c | 91 ++++++++++------- libclamav/readdb.h | 5 +- libclamav/regex_list.c | 3 +- libclamav/scanners.c | 21 ++-- sigtool/sigtool.c | 2 +- 15 files changed, 260 insertions(+), 199 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8359a3aad..4f96280dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Wed Feb 20 22:03:07 CET 2008 (tk) +--------------------------------- + * libclamav: filetype detection improvements: + - allow manual selection of matching method for each filetype signature + - A-C filetype magic sigs can be limited to specific file formats + - allow ndb-like offsets inside A-C filetype sigs + - filetype sigs can be limited to specific f-levels + - optimize filetype sigs handling inside cli_ac_scanbuff() + - MAGIC_BUFFER_SIZE increased to 1024 bytes + - A-C filetype sigs for CL_TYPE_IGNORED are guaranteed to work and take + precedence within MAGIC_BUFFER_SIZE file space (shouldn't be used + outside it) + - rename daily.ft to daily.ftm (to avoid problems with older snapshots) + Wed Feb 20 16:49:13 EET 2008 (edwin) ------------------------------------ * libclamav/htmlnorm.c: generate only nocomment.html (always contains script too) and notags.html (bb #851) diff --git a/libclamav/blob.c b/libclamav/blob.c index 199b266bd..4bd142398 100644 --- a/libclamav/blob.c +++ b/libclamav/blob.c @@ -713,7 +713,7 @@ fileblobScan(const fileblob *fb) ftype = cli_filetype2(fd, fb->ctx->engine); if(ftype >= CL_TYPE_TEXT_ASCII && ftype <= CL_TYPE_TEXT_UTF16BE) { lseek(fd, 0, SEEK_SET); - rc = cli_scandesc(fd, fb->ctx, 0, CL_TYPE_MAIL, 0, NULL); + rc = cli_scandesc(fd, fb->ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR); } } diff --git a/libclamav/filetypes.c b/libclamav/filetypes.c index 88461f565..6c593b246 100644 --- a/libclamav/filetypes.c +++ b/libclamav/filetypes.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Sourcefire, Inc. + * Copyright (C) 2007 - 2008 Sourcefire, Inc. * Author: Tomasz Kojm * * Copyright (C) 2002 - 2005 Tomasz Kojm @@ -53,6 +53,7 @@ static const struct ftmap_s { { "CL_TYPE_TEXT_UTF16BE", CL_TYPE_TEXT_UTF16BE }, { "CL_TYPE_BINARY_DATA", CL_TYPE_BINARY_DATA }, { "CL_TYPE_IGNORED", CL_TYPE_IGNORED }, + { "CL_TYPE_ANY", 0 }, /* for ft-sigs */ { "CL_TYPE_MSEXE", CL_TYPE_MSEXE }, { "CL_TYPE_ELF", CL_TYPE_ELF }, { "CL_TYPE_POSIX_TAR", CL_TYPE_POSIX_TAR }, @@ -166,7 +167,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine) if(cli_ac_initdata(&mdata, root->ac_partsigs, AC_DEFAULT_TRACKLEN)) return ret; - sret = cli_ac_scanbuff(smallbuff, bread, NULL, engine->root[0], &mdata, 1, 0, 0, -1, NULL); + sret = cli_ac_scanbuff(smallbuff, bread, NULL, engine->root[0], &mdata, 0, ret, desc, NULL, AC_SCAN_FT); cli_ac_freedata(&mdata); @@ -178,7 +179,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine) decoded = (unsigned char *) cli_utf16toascii((char *) smallbuff, bread); if(decoded) { - sret = cli_ac_scanbuff(decoded, strlen((char *) decoded), NULL, engine->root[0], &mdata, 1, 0, 0, -1, NULL); + sret = cli_ac_scanbuff(decoded, strlen((char *) decoded), NULL, engine->root[0], &mdata, 0, CL_TYPE_TEXT_ASCII, desc, NULL, AC_SCAN_FT); free(decoded); if(sret == CL_TYPE_HTML) ret = CL_TYPE_HTML_UTF16; @@ -212,7 +213,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine) return ret; if(out_area.length > 0) { - sret = cli_ac_scanbuff(decodedbuff, out_area.length, NULL, engine->root[0], &mdata, 1, 0, 0, -1, NULL); + sret = cli_ac_scanbuff(decodedbuff, out_area.length, NULL, engine->root[0], &mdata, 0, 0, desc, NULL, AC_SCAN_FT); /* FIXME: can we use CL_TYPE_TEXT_ASCII instead of 0? */ if(sret == CL_TYPE_HTML) { cli_dbgmsg("cli_filetype2: detected HTML signature in Unicode file\n"); /* htmlnorm is able to handle any unicode now, since it skips null chars */ diff --git a/libclamav/filetypes.h b/libclamav/filetypes.h index 57a6a7b93..d7c690668 100644 --- a/libclamav/filetypes.h +++ b/libclamav/filetypes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Sourcefire, Inc. + * Copyright (C) 2007 - 2008 Sourcefire, Inc. * Author: Tomasz Kojm * * Copyright (C) 2002 - 2005 Tomasz Kojm @@ -28,7 +28,7 @@ #include "clamav.h" #include "cltypes.h" -#define MAGIC_BUFFER_SIZE 512 +#define MAGIC_BUFFER_SIZE 1024 #define CL_TYPENO 500 #define MAX_EMBEDDED_OBJ 10 @@ -39,7 +39,6 @@ typedef enum { CL_TYPE_TEXT_UTF16BE, CL_TYPE_BINARY_DATA, /* Please do not add any new types above this line */ - CL_TYPE_IGNORED, CL_TYPE_ERROR, CL_TYPE_MSEXE, CL_TYPE_ELF, @@ -76,7 +75,8 @@ typedef enum { CL_TYPE_CABSFX, CL_TYPE_ARJSFX, CL_TYPE_NULSFT, /* on the fly */ - CL_TYPE_AUTOIT + CL_TYPE_AUTOIT, + CL_TYPE_IGNORED /* please don't add anything below */ } cli_file_t; struct cli_ftype { diff --git a/libclamav/filetypes_int.h b/libclamav/filetypes_int.h index 7fb3e0481..b73f3e81c 100644 --- a/libclamav/filetypes_int.h +++ b/libclamav/filetypes_int.h @@ -1,6 +1,6 @@ /* - * Static filetype data for use when daily.ft is not available. - * Copyright (C) 2007 Sourcefire, Inc. + * Static filetype data for use when daily.ftm is not available. + * Copyright (C) 2007 - 2008 Sourcefire, Inc. * Author: Tomasz Kojm * * This program is free software; you can redistribute it and/or modify @@ -23,7 +23,7 @@ /* Generated with the following perl script: #!/usr/bin/perl -open(FT, "daily.ft") or die "Can't open daily.ft"; +open(FT, "daily.ftm") or die "Can't open daily.ftm"; print "static const char *ftypes_int[] = {\n"; while($line = ) { chomp($line); @@ -33,104 +33,104 @@ print " NULL\n};\n" */ static const char *ftypes_int[] = { - "0:4d5a:MS-EXE/DLL:CL_TYPE_MSEXE", - "0:7f454c46:ELF:CL_TYPE_ELF", - "0:52617221:RAR:CL_TYPE_RAR", - "0:504b0304:ZIP:CL_TYPE_ZIP", - "0:504b3030504b0304:ZIP:CL_TYPE_ZIP", - "0:1f8b:GZip:CL_TYPE_GZ", - "0:425a68:BZip:CL_TYPE_BZ", - "0:60ea:ARJ:CL_TYPE_ARJ", - "0:535a4444:compress.exe'd:CL_TYPE_MSSZDD", - "0:4d534346:MS CAB:CL_TYPE_MSCAB", - "0:49545346:MS CHM:CL_TYPE_MSCHM", - "8:19040010:SIS:CL_TYPE_SIS", - "0:23407e5e:SCRENC:CL_TYPE_SCRENC", - "0:28546869732066696c65206d75737420626520636f6e76657274656420776974682042696e48657820342e3029:BinHex:CL_TYPE_BINHEX", - "0:46726f6d20:MBox:CL_TYPE_MAIL", - "0:52656365697665643a20:Raw mail:CL_TYPE_MAIL", - "0:52657475726e2d506174683a20:Maildir:CL_TYPE_MAIL", - "0:52657475726e2d706174683a20:Maildir:CL_TYPE_MAIL", - "0:44656c6976657265642d546f3a20:Mail:CL_TYPE_MAIL", - "0:582d5549444c3a20:Mail:CL_TYPE_MAIL", - "0:582d4170706172656e746c792d546f3a20:Mail:CL_TYPE_MAIL", - "0:582d456e76656c6f70652d46726f6d3a20:Mail:CL_TYPE_MAIL", - "0:582d4f726967696e616c2d546f3a20:Mail:CL_TYPE_MAIL", - "0:582d53796d616e7465632d:Symantec:CL_TYPE_MAIL", - "0:582d455653:EVS mail:CL_TYPE_MAIL", - "0:582d5265616c2d546f3a20:Mail:CL_TYPE_MAIL", - "0:582d53696576653a20:Mail:CL_TYPE_MAIL", - "0:3e46726f6d20:Mail:CL_TYPE_MAIL", - "0:446174653a20:Mail:CL_TYPE_MAIL", - "0:4d6573736167652d49643a20:Mail:CL_TYPE_MAIL", - "0:4d6573736167652d49443a20:Mail:CL_TYPE_MAIL", - "0:456e76656c6f70652d746f3a20:Mail:CL_TYPE_MAIL", - "0:44656c69766572792d646174653a20:Mail:CL_TYPE_MAIL", - "0:546f3a20:Mail:CL_TYPE_MAIL", - "0:5375626a6563743a20:Mail:CL_TYPE_MAIL", - "0:466f723a20:Eserv mail:CL_TYPE_MAIL", - "0:46726f6d3a20:Exim mail:CL_TYPE_MAIL", - "0:763a0d0a52656365697665643a20:VPOP3 Mail (DOS):CL_TYPE_MAIL", - "0:763a0a52656365697665643a20:VPOP3 Mail (UNIX):CL_TYPE_MAIL", - "0:48692e20546869732069732074686520716d61696c2d73656e64:Qmail bounce:CL_TYPE_MAIL", - "0:789f3e22:TNEF:CL_TYPE_TNEF", - "0:626567696e20:UUencoded:CL_TYPE_UUENCODED", - "0:474946:GIF:CL_TYPE_GRAPHICS", - "0:424d:BMP:CL_TYPE_GRAPHICS", - "0:ffd8ff:JPEG:CL_TYPE_GRAPHICS", - "6:4a464946:JPEG:CL_TYPE_GRAPHICS", - "6:45786966:JPEG:CL_TYPE_GRAPHICS", - "0:89504e47:PNG:CL_TYPE_GRAPHICS", - "0:52494646:RIFF:CL_TYPE_RIFF", - "0:52494658:RIFX:CL_TYPE_RIFF", - "0:d0cf11e0a1b11ae1:OLE2 container:CL_TYPE_MSOLE2", - "0:255044462d:PDF document:CL_TYPE_PDF", - "0:b6b9acaefeffffff:CryptFF:CL_TYPE_CRYPTFF", - "0:7b5c727466:RTF:CL_TYPE_RTF", - "0:000001b3:MPEG video stream:CL_TYPE_IGNORED", - "0:000001ba:MPEG sys stream:CL_TYPE_IGNORED", - "0:4f676753:Ogg Stream:CL_TYPE_IGNORED", - "0:494433:MP3:CL_TYPE_IGNORED", - "0:fffb90:MP3:CL_TYPE_IGNORED", - "0:252150532d41646f62652d:PostScript:CL_TYPE_IGNORED", - "0:3026b2758e66cf:WMA/WMV/ASF:CL_TYPE_IGNORED", - "0:2e524d46:Real Media File:CL_TYPE_IGNORED", - "*:0a46726f6d3a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_MAIL", - "*:0a52656365697665643a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_MAIL", - "*:0a52656365697665643a20{-2048}0a436f6e74656e742d747970653a20:Mail file:CL_TYPE_MAIL", - "*:4d494d452d56657273696f6e3a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_MAIL", - "*:3c4120*(68|48)(72|52)6566:HTML data:CL_TYPE_HTML", - "*:3c6120*(68|48)(72|52)6566:HTML data:CL_TYPE_HTML", - "*:3c6120*(68|48)(72|52)4546:HTML data:CL_TYPE_HTML", - "*:3c4120*(68|48)(72|52)4546:HTML data:CL_TYPE_HTML", - "*:3c68746d6c3e:HTML data:CL_TYPE_HTML", - "*:3c48544d4c3e:HTML data:CL_TYPE_HTML", - "*:3c48746d6c3e:HTML data:CL_TYPE_HTML", - "*:3c686561643e:HTML data:CL_TYPE_HTML", - "*:3c484541443e:HTML data:CL_TYPE_HTML", - "*:3c486561643e:HTML data:CL_TYPE_HTML", - "*:3c696d67:HTML data:CL_TYPE_HTML", - "*:3c494d47:HTML data:CL_TYPE_HTML", - "*:3c496d67:HTML data:CL_TYPE_HTML", - "*:3c736372697074:HTML data:CL_TYPE_HTML", - "*:3c536372697074:HTML data:CL_TYPE_HTML", - "*:3c534352495054:HTML data:CL_TYPE_HTML", - "*:3c6f626a656374:HTML data:CL_TYPE_HTML", - "*:3c4f626a656374:HTML data:CL_TYPE_HTML", - "*:3c4f424a454354:HTML data:CL_TYPE_HTML", - "*:3c696672616d65:HTML data:CL_TYPE_HTML", - "*:3c494652414d45:HTML data:CL_TYPE_HTML", - "*:3c7461626c65:HTML data:CL_TYPE_HTML", - "*:3c5441424c45:HTML data:CL_TYPE_HTML", - "*:526172211a0700:RAR-SFX:CL_TYPE_RARSFX", - "*:504b0304:ZIP-SFX:CL_TYPE_ZIPSFX", - "*:4d534346:CAB-SFX:CL_TYPE_CABSFX", - "*:60ea{7}0002:ARJ-SFX:CL_TYPE_ARJSFX", - "*:60ea{7}0102:ARJ-SFX:CL_TYPE_ARJSFX", - "*:60ea{7}0202:ARJ-SFX:CL_TYPE_ARJSFX", - "*:efbeadde4e756c6c736f6674496e7374:NSIS:CL_TYPE_NULSFT", - "*:a3484bbe986c4aa9994c530a86d6487d41553321454130(35|36):AUTOIT:CL_TYPE_AUTOIT", - "*:4d5a{60-300}50450000:PE:CL_TYPE_MSEXE", + "0:0:4d5a:MS-EXE/DLL:CL_TYPE_ANY:CL_TYPE_MSEXE", + "0:0:7f454c46:ELF:CL_TYPE_ANY:CL_TYPE_ELF", + "0:0:52617221:RAR:CL_TYPE_ANY:CL_TYPE_RAR", + "0:0:504b0304:ZIP:CL_TYPE_ANY:CL_TYPE_ZIP", + "0:0:504b3030504b0304:ZIP:CL_TYPE_ANY:CL_TYPE_ZIP", + "0:0:1f8b:GZip:CL_TYPE_ANY:CL_TYPE_GZ", + "0:0:425a68:BZip:CL_TYPE_ANY:CL_TYPE_BZ", + "0:0:60ea:ARJ:CL_TYPE_ANY:CL_TYPE_ARJ", + "0:0:535a4444:compress.exe'd:CL_TYPE_ANY:CL_TYPE_MSSZDD", + "0:0:4d534346:MS CAB:CL_TYPE_ANY:CL_TYPE_MSCAB", + "0:0:49545346:MS CHM:CL_TYPE_ANY:CL_TYPE_MSCHM", + "0:8:19040010:SIS:CL_TYPE_ANY:CL_TYPE_SIS", + "0:0:23407e5e:SCRENC:CL_TYPE_ANY:CL_TYPE_SCRENC", + "0:0:28546869732066696c65206d75737420626520636f6e76657274656420776974682042696e48657820342e3029:BinHex:CL_TYPE_ANY:CL_TYPE_BINHEX", + "0:0:46726f6d20:MBox:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:52656365697665643a20:Raw mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:52657475726e2d506174683a20:Maildir:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:52657475726e2d706174683a20:Maildir:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:44656c6976657265642d546f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d5549444c3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d4170706172656e746c792d546f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d456e76656c6f70652d46726f6d3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d4f726967696e616c2d546f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d53796d616e7465632d:Symantec:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d455653:EVS mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d5265616c2d546f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:582d53696576653a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:3e46726f6d20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:446174653a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:4d6573736167652d49643a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:4d6573736167652d49443a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:456e76656c6f70652d746f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:44656c69766572792d646174653a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:546f3a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:5375626a6563743a20:Mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:466f723a20:Eserv mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:46726f6d3a20:Exim mail:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:763a0d0a52656365697665643a20:VPOP3 Mail (DOS):CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:763a0a52656365697665643a20:VPOP3 Mail (UNIX):CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:48692e20546869732069732074686520716d61696c2d73656e64:Qmail bounce:CL_TYPE_ANY:CL_TYPE_MAIL", + "0:0:789f3e22:TNEF:CL_TYPE_ANY:CL_TYPE_TNEF", + "0:0:626567696e20:UUencoded:CL_TYPE_ANY:CL_TYPE_UUENCODED", + "0:0:474946:GIF:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:0:424d:BMP:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:0:ffd8ff:JPEG:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:6:4a464946:JPEG:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:6:45786966:JPEG:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:0:89504e47:PNG:CL_TYPE_ANY:CL_TYPE_GRAPHICS", + "0:0:52494646:RIFF:CL_TYPE_ANY:CL_TYPE_RIFF", + "0:0:52494658:RIFX:CL_TYPE_ANY:CL_TYPE_RIFF", + "0:0:d0cf11e0a1b11ae1:OLE2 container:CL_TYPE_ANY:CL_TYPE_MSOLE2", + "0:0:255044462d:PDF document:CL_TYPE_ANY:CL_TYPE_PDF", + "0:0:b6b9acaefeffffff:CryptFF:CL_TYPE_ANY:CL_TYPE_CRYPTFF", + "0:0:7b5c727466:RTF:CL_TYPE_ANY:CL_TYPE_RTF", + "0:0:000001b3:MPEG video stream:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:000001ba:MPEG sys stream:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:4f676753:Ogg Stream:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:494433:MP3:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:fffb90:MP3:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:252150532d41646f62652d:PostScript:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:3026b2758e66cf:WMA/WMV/ASF:CL_TYPE_ANY:CL_TYPE_IGNORED", + "0:0:2e524d46:Real Media File:CL_TYPE_ANY:CL_TYPE_IGNORED", + "1:*:0a46726f6d3a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_ANY:CL_TYPE_MAIL", + "1:*:0a52656365697665643a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_ANY:CL_TYPE_MAIL", + "1:*:0a52656365697665643a20{-2048}0a436f6e74656e742d747970653a20:Mail file:CL_TYPE_ANY:CL_TYPE_MAIL", + "1:*:4d494d452d56657273696f6e3a20{-2048}0a436f6e74656e742d547970653a20:Mail file:CL_TYPE_ANY:CL_TYPE_MAIL", + "1:*:3c4120*(68|48)(72|52)6566:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c6120*(68|48)(72|52)6566:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c6120*(68|48)(72|52)4546:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c4120*(68|48)(72|52)4546:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c68746d6c3e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c48544d4c3e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c48746d6c3e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c686561643e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c484541443e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c486561643e:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c696d67:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c494d47:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c496d67:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c736372697074:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c536372697074:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c534352495054:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c6f626a656374:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c4f626a656374:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c4f424a454354:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c696672616d65:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c494652414d45:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c7461626c65:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:3c5441424c45:HTML data:CL_TYPE_ANY:CL_TYPE_HTML", + "1:*:526172211a0700:RAR-SFX:CL_TYPE_ANY:CL_TYPE_RARSFX", + "1:*:504b0304:ZIP-SFX:CL_TYPE_ANY:CL_TYPE_ZIPSFX", + "1:*:4d534346:CAB-SFX:CL_TYPE_ANY:CL_TYPE_CABSFX", + "1:*:60ea{7}0002:ARJ-SFX:CL_TYPE_ANY:CL_TYPE_ARJSFX", + "1:*:60ea{7}0102:ARJ-SFX:CL_TYPE_ANY:CL_TYPE_ARJSFX", + "1:*:60ea{7}0202:ARJ-SFX:CL_TYPE_ANY:CL_TYPE_ARJSFX", + "1:*:efbeadde4e756c6c736f6674496e7374:NSIS:CL_TYPE_ANY:CL_TYPE_NULSFT", + "1:*:a3484bbe986c4aa9994c530a86d6487d41553321454130(35|36):AUTOIT:CL_TYPE_ANY:CL_TYPE_AUTOIT", + "1:*:4d5a{60-300}50450000:PE:CL_TYPE_ANY:CL_TYPE_MSEXE", NULL }; diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index b5db60ceb..e81d911fa 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -568,7 +568,7 @@ inline static int ac_addtype(struct cli_matched_type **list, cli_file_t type, of return CL_SUCCESS; } -int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint8_t otfrec, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset) +int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode) { struct cli_ac_node *current; struct cli_ac_patt *patt, *pt; @@ -605,6 +605,12 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v if(ac_findmatch(buffer, bp, length, patt, &matchend)) { pt = patt; while(pt) { + + if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) { + pt = pt->next_same; + continue; + } + realoff = offset + bp - pt->prefix_length; if((pt->offset || pt->target) && (!pt->sigid || pt->partno == 1)) { @@ -670,25 +676,31 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v offmatrix[pt->parts - 1][offmatrix[pt->partno - 1][0]] = realoff; } else if(found && pt->partno == pt->parts) { if(pt->type) { - if(otfrec) { - if(pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) { - cli_dbgmsg("Matched signature for file type %s\n", pt->virname); - type = pt->type; - if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE))) { - /* FIXME: we don't know which offset of the first part is the correct one */ - for(j = 1; j <= AC_DEFAULT_TRACKLEN && offmatrix[0][j] != -1; j++) { - if(ac_addtype(ftoffset, type, offmatrix[pt->parts - 1][j])) { - if(info.exeinfo.section) - free(info.exeinfo.section); - return CL_EMEM; - } + + if(pt->type == CL_TYPE_IGNORED && (!pt->rtype || ftype == pt->rtype)) { + if(info.exeinfo.section) + free(info.exeinfo.section); + + return CL_TYPE_IGNORED; + } + + if((pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) && (!pt->rtype || ftype == pt->rtype)) { + cli_dbgmsg("Matched signature for file type %s\n", pt->virname); + type = pt->type; + if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE))) { + /* FIXME: we don't know which offset of the first part is the correct one */ + for(j = 1; j <= AC_DEFAULT_TRACKLEN && offmatrix[0][j] != -1; j++) { + if(ac_addtype(ftoffset, type, offmatrix[pt->parts - 1][j])) { + if(info.exeinfo.section) + free(info.exeinfo.section); + return CL_EMEM; } } - - memset(offmatrix[0], -1, pt->parts * (AC_DEFAULT_TRACKLEN + 1) * sizeof(int32_t)); - for(j = 0; j < pt->parts; j++) - offmatrix[j][0] = 0; } + + memset(offmatrix[0], -1, pt->parts * (AC_DEFAULT_TRACKLEN + 1) * sizeof(int32_t)); + for(j = 0; j < pt->parts; j++) + offmatrix[j][0] = 0; } } else { /* !pt->type */ @@ -704,17 +716,21 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v } else { /* old type signature */ if(pt->type) { - if(otfrec) { - if(pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) { - cli_dbgmsg("Matched signature for file type %s at %u\n", pt->virname, realoff); - type = pt->type; - if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE))) { + if(pt->type == CL_TYPE_IGNORED && (!pt->rtype || ftype == pt->rtype)) { + if(info.exeinfo.section) + free(info.exeinfo.section); - if(ac_addtype(ftoffset, type, realoff)) { - if(info.exeinfo.section) - free(info.exeinfo.section); - return CL_EMEM; - } + return CL_TYPE_IGNORED; + } + if((pt->type > type || pt->type >= CL_TYPE_SFX || pt->type == CL_TYPE_MSEXE) && (!pt->rtype || ftype == pt->rtype)) { + cli_dbgmsg("Matched signature for file type %s at %u\n", pt->virname, realoff); + type = pt->type; + if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < MAX_EMBEDDED_OBJ) && ((ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) || ((ftype == CL_TYPE_MSEXE || ftype == CL_TYPE_ZIP) && type == CL_TYPE_MSEXE))) { + + if(ac_addtype(ftoffset, type, realoff)) { + if(info.exeinfo.section) + free(info.exeinfo.section); + return CL_EMEM; } } } @@ -738,11 +754,11 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v if(info.exeinfo.section) free(info.exeinfo.section); - return otfrec ? type : CL_CLEAN; + return (mode & AC_SCAN_FT) ? type : CL_CLEAN; } /* FIXME: clean up the code */ -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 type, uint32_t mindist, uint32_t maxdist, const char *offset, uint8_t target) +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, uint8_t target) { struct cli_ac_patt *new; char *pt, *pt2, *hex = NULL, *hexcpy = NULL; @@ -758,6 +774,7 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex if((new = (struct cli_ac_patt *) cli_calloc(1, sizeof(struct cli_ac_patt))) == NULL) return CL_EMEM; + new->rtype = rtype; new->type = type; new->sigid = sigid; new->parts = parts; diff --git a/libclamav/matcher-ac.h b/libclamav/matcher-ac.h index 933220e53..ebbce0feb 100644 --- a/libclamav/matcher-ac.h +++ b/libclamav/matcher-ac.h @@ -33,6 +33,9 @@ #define AC_CH_MAXDIST 32 extern uint8_t cli_ac_mindepth, cli_ac_maxdepth; +#define AC_SCAN_VIR 1 +#define AC_SCAN_FT 2 + struct cli_ac_data { int32_t ***offmatrix; uint32_t partsigs; @@ -58,7 +61,7 @@ struct cli_ac_patt { struct cli_ac_patt *next, *next_same; uint8_t depth; uint8_t target; - uint16_t type; + uint16_t rtype, type; }; struct cli_ac_node { @@ -72,11 +75,11 @@ struct cli_ac_node { int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern); int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint8_t tracklen); void cli_ac_freedata(struct cli_ac_data *data); -int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint8_t otfrec, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset); +int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode); int cli_ac_buildtrie(struct cli_matcher *root); int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth); void cli_ac_free(struct cli_matcher *root); -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 type, uint32_t mindist, uint32_t maxdist, const char *offset, uint8_t target); +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, uint8_t target); void cli_ac_setdepth(uint8_t mindepth, uint8_t maxdepth); #endif diff --git a/libclamav/matcher.c b/libclamav/matcher.c index b88a9cceb..47052d952 100644 --- a/libclamav/matcher.c +++ b/libclamav/matcher.c @@ -77,7 +77,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli return ret; if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, 0, ftype, -1)) != CL_VIRUS) - ret = cli_ac_scanbuff(buffer, length, virname, troot, &mdata, 0, 0, ftype, -1, NULL); + ret = cli_ac_scanbuff(buffer, length, virname, troot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR); cli_ac_freedata(&mdata); @@ -89,7 +89,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli return ret; if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, 0, ftype, -1)) != CL_VIRUS) - ret = cli_ac_scanbuff(buffer, length, virname, groot, &mdata, 0, 0, ftype, -1, NULL); + ret = cli_ac_scanbuff(buffer, length, virname, groot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR); cli_ac_freedata(&mdata); @@ -249,7 +249,7 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct return 1; } -int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset) +int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode) { unsigned char *buffer, *buff, *endbl, *upt; int ret = CL_CLEAN, type = CL_CLEAN, i, bytes; @@ -325,7 +325,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8 if(troot) { if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, ftype, desc)) != CL_VIRUS) - ret = cli_ac_scanbuff(upt, length, ctx->virname, troot, &tdata, otfrec, offset, ftype, desc, ftoffset); + ret = cli_ac_scanbuff(upt, length, ctx->virname, troot, &tdata, offset, ftype, desc, ftoffset, acmode); if(ret == CL_VIRUS) { free(buffer); @@ -343,7 +343,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8 if(!ftonly) { if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, ftype, desc)) != CL_VIRUS) - ret = cli_ac_scanbuff(upt, length, ctx->virname, groot, &gdata, otfrec, offset, ftype, desc, ftoffset); + ret = cli_ac_scanbuff(upt, length, ctx->virname, groot, &gdata, offset, ftype, desc, ftoffset, acmode); if(ret == CL_VIRUS) { free(buffer); @@ -356,7 +356,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8 else return CL_VIRUS; - } else if(otfrec && ret >= CL_TYPENO) { + } else if((acmode & AC_SCAN_FT) && ret >= CL_TYPENO) { if(ret > type) type = ret; } @@ -394,5 +394,5 @@ int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8 return CL_VIRUS; } - return otfrec ? type : CL_CLEAN; + return (acmode & AC_SCAN_FT) ? type : CL_CLEAN; } diff --git a/libclamav/matcher.h b/libclamav/matcher.h index 94ce917f3..2288afa2b 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -94,7 +94,7 @@ struct cli_target_info { int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli_file_t ftype); -int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset); +int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode); int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname); diff --git a/libclamav/nsis/nulsft.c b/libclamav/nsis/nulsft.c index f7b7f1b36..9e2c40df5 100644 --- a/libclamav/nsis/nulsft.c +++ b/libclamav/nsis/nulsft.c @@ -537,7 +537,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) { cli_dbgmsg("NSIS: Successully extracted file #%u\n", nsist.fno); lseek(nsist.ofd, 0, SEEK_SET); if(nsist.fno == 1) - ret=cli_scandesc(nsist.ofd, ctx, 0, 0, 0, NULL); + ret=cli_scandesc(nsist.ofd, ctx, 0, 0, NULL, AC_SCAN_VIR); else ret=cli_magic_scandesc(nsist.ofd, ctx); close(nsist.ofd); diff --git a/libclamav/readdb.c b/libclamav/readdb.c index ae5b6641d..4fa95dbf5 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -93,7 +93,7 @@ struct cli_ignored { int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *signo); int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo); -int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, unsigned short type, const char *offset, unsigned short target) +int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, uint16_t rtype, uint16_t type, const char *offset, uint8_t target) { struct cli_bm_patt *bm_new; char *pt, *hexcpy, *start, *n; @@ -136,7 +136,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex *pt++ = 0; } - if((ret = cli_ac_addsig(root, virname, start, root->ac_partsigs, parts, i, type, mindist, maxdist, offset, target))) { + if((ret = cli_ac_addsig(root, virname, start, root->ac_partsigs, parts, i, rtype, type, mindist, maxdist, offset, target))) { cli_errmsg("cli_parse_add(): Problem adding signature (1).\n"); error = 1; break; @@ -216,7 +216,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex return CL_EMALFDB; } - if((ret = cli_ac_addsig(root, virname, pt, root->ac_partsigs, parts, i, type, 0, 0, offset, target))) { + if((ret = cli_ac_addsig(root, virname, pt, root->ac_partsigs, parts, i, rtype, type, 0, 0, offset, target))) { cli_errmsg("cli_parse_add(): Problem adding signature (2).\n"); free(pt); return ret; @@ -226,7 +226,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex } } else if(root->ac_only || strpbrk(hexsig, "?(") || type) { - if((ret = cli_ac_addsig(root, virname, hexsig, 0, 0, 0, type, 0, 0, offset, target))) { + if((ret = cli_ac_addsig(root, virname, hexsig, 0, 0, 0, rtype, type, 0, 0, offset, target))) { cli_errmsg("cli_parse_add(): Problem adding signature (3).\n"); return ret; } @@ -449,7 +449,7 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(*pt == '=') continue; - if((ret = cli_parse_add(root, start, pt, 0, NULL, 0))) { + if((ret = cli_parse_add(root, start, pt, 0, 0, NULL, 0))) { ret = CL_EMALFDB; break; } @@ -628,7 +628,7 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, break; } - if((ret = cli_parse_add(root, virname, sig, 0, offset, target))) { + if((ret = cli_parse_add(root, virname, sig, 0, 0, offset, target))) { ret = CL_EMALFDB; break; } @@ -658,14 +658,14 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, return CL_SUCCESS; } -#define FT_TOKENS 4 -static int cli_loadft(FILE *fs, struct cl_engine **engine, unsigned int options, unsigned int internal, gzFile *gzs, unsigned int gzrsize) +#define FTM_TOKENS 8 +static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options, unsigned int internal, gzFile *gzs, unsigned int gzrsize) { - const char *tokens[FT_TOKENS]; + const char *tokens[FTM_TOKENS], *pt; char buffer[FILEBUFF]; - unsigned int line = 0; + unsigned int line = 0, sigs = 0; struct cli_ftype *new; - cli_file_t type; + cli_file_t rtype, type; int ret; @@ -690,40 +690,60 @@ static int cli_loadft(FILE *fs, struct cl_engine **engine, unsigned int options, cli_chomp(buffer); } line++; - cli_strtokenize(buffer, ':', FT_TOKENS, tokens); + cli_strtokenize(buffer, ':', FTM_TOKENS, tokens); - if(!tokens[0] || !tokens[1] || !tokens[2] || !tokens[3]) { + if(!tokens[0] || !tokens[1] || !tokens[2] || !tokens[3] || !tokens[4] || !tokens[5]) { ret = CL_EMALFDB; break; } - type = cli_ftcode(tokens[3]); - if(type == CL_TYPE_ERROR) { + if((pt = tokens[6])) { /* min version */ + if(!cli_isnumber(pt)) { + ret = CL_EMALFDB; + break; + } + if((unsigned int) atoi(pt) > cl_retflevel()) { + cli_dbgmsg("cli_loadftm: File type signature for %s not loaded (required f-level: %u)\n", tokens[3], atoi(pt)); + continue; + } + if((pt = tokens[7])) { /* max version */ + if(!cli_isnumber(pt)) { + ret = CL_EMALFDB; + break; + } + if((unsigned int) atoi(pt) < cl_retflevel()) + continue; + } + } + + rtype = cli_ftcode(tokens[4]); + type = cli_ftcode(tokens[5]); + if(rtype == CL_TYPE_ERROR || type == CL_TYPE_ERROR) { ret = CL_EMALFDB; break; } - if(*tokens[0] == '*') { - if((ret = cli_parse_add((*engine)->root[0], tokens[2], tokens[1], type, NULL, 0))) + if(atoi(tokens[0]) == 1) { /* A-C */ + if((ret = cli_parse_add((*engine)->root[0], tokens[3], tokens[2], rtype, type, strcmp(tokens[1], "*") ? tokens[1] : NULL, 0))) break; - } else { + } else if(atoi(tokens[0]) == 0) { /* memcmp() */ new = (struct cli_ftype *) cli_malloc(sizeof(struct cli_ftype)); if(!new) { ret = CL_EMEM; break; } new->type = type; - new->offset = atoi(tokens[0]); - new->magic = (unsigned char *) cli_hex2str(tokens[1]); + new->offset = atoi(tokens[1]); + new->magic = (unsigned char *) cli_hex2str(tokens[2]); if(!new->magic) { - cli_errmsg("cli_loadft: Can't decode the hex string\n"); + cli_errmsg("cli_loadftm: Can't decode the hex string\n"); ret = CL_EMALFDB; free(new); break; } - new->length = strlen(tokens[1]) / 2; - new->tname = cli_strdup(tokens[2]); + new->length = strlen(tokens[2]) / 2; + new->tname = cli_strdup(tokens[3]); if(!new->tname) { free(new->magic); free(new); @@ -732,22 +752,27 @@ static int cli_loadft(FILE *fs, struct cl_engine **engine, unsigned int options, } new->next = (*engine)->ftypes; (*engine)->ftypes = new; + + } else { + cli_dbgmsg("cli_loadftm: Unsupported mode %u\n", atoi(tokens[0])); + continue; } + sigs++; } - if(!line) { - cli_errmsg("Empty %s filetype database\n", internal ? "built-in" : ".ft"); + if(ret) { + cli_errmsg("Problem parsing %s filetype database at line %u\n", internal ? "built-in" : "external", line); cl_free(*engine); - return CL_EMALFDB; + return ret; } - if(ret) { - cli_errmsg("Problem parsing %s filetype database at line %u\n", internal ? "built-in" : ".ft", line); + if(!sigs) { + cli_errmsg("Empty %s filetype database\n", internal ? "built-in" : "external"); cl_free(*engine); - return ret; + return CL_EMALFDB; } - cli_dbgmsg("Loaded %u filetype definitions\n", line); + cli_dbgmsg("Loaded %u filetype definitions\n", sigs); return CL_SUCCESS; } @@ -1277,8 +1302,8 @@ int cli_load(const char *filename, struct cl_engine **engine, unsigned int *sign ret = cli_loadpdb(fs, engine, options, gzs, gzrsize); } else skipped = 1; - } else if(cli_strbcasestr(dbname, ".ft")) { - ret = cli_loadft(fs, engine, options, 0, gzs, gzrsize); + } else if(cli_strbcasestr(dbname, ".ftm")) { + ret = cli_loadftm(fs, engine, options, 0, gzs, gzrsize); } else if(cli_strbcasestr(dbname, ".ign")) { ret = cli_loadign(fs, engine, options, gzs, gzrsize); @@ -1757,7 +1782,7 @@ int cl_build(struct cl_engine *engine) return CL_ENULLARG; if(!engine->ftypes) - if((ret = cli_loadft(NULL, &engine, 0, 1, NULL, 0))) + if((ret = cli_loadftm(NULL, &engine, 0, 1, NULL, 0))) return ret; for(i = 0; i < CLI_MTARGETS; i++) { diff --git a/libclamav/readdb.h b/libclamav/readdb.h index 17144d47a..4a7f4944c 100644 --- a/libclamav/readdb.h +++ b/libclamav/readdb.h @@ -24,6 +24,7 @@ #include "clamav.h" #include "matcher.h" #include "str.h" +#include "cltypes.h" #define CLI_DBEXT(ext) \ ( \ @@ -42,14 +43,14 @@ cli_strbcasestr(ext, ".rmd") || \ cli_strbcasestr(ext, ".pdb") || \ cli_strbcasestr(ext, ".wdb") || \ - cli_strbcasestr(ext, ".ft") || \ + cli_strbcasestr(ext, ".ftm") || \ cli_strbcasestr(ext, ".ign") || \ cli_strbcasestr(ext, ".cvd") || \ cli_strbcasestr(ext, ".cld") \ ) -int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, unsigned short type, const char *offset, unsigned short target); +int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, uint16_t rtype, uint16_t type, const char *offset, uint8_t target); int cli_initengine(struct cl_engine **engine, unsigned int options); diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c index 4809d4a54..08f733406 100644 --- a/libclamav/regex_list.c +++ b/libclamav/regex_list.c @@ -287,7 +287,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di for(i = 0; i < matcher->root_hosts_cnt; i++) { /* doesn't need to match terminating \0*/ - rc = cli_ac_scanbuff((unsigned char*)buffer,buffer_len,info, &matcher->root_hosts[i] ,&mdata,0,0,0,-1,NULL); + rc = cli_ac_scanbuff((unsigned char*)buffer,buffer_len,info, &matcher->root_hosts[i] ,&mdata,0,0,-1,NULL,AC_SCAN_VIR); cli_ac_freedata(&mdata); if(rc) { char c; @@ -443,6 +443,7 @@ static int add_regex_list_element(struct cli_matcher* root,const char* pattern,c len = strlen(pattern); /* need not to match \0 too */ + new->rtype = 0; new->type = 0; new->sigid = 0; new->parts = 0; diff --git a/libclamav/scanners.c b/libclamav/scanners.c index 4a8d7fd0a..b8e572eec 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -165,7 +165,7 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container) ftype = cli_filetype2(fd, ctx->engine); if(ftype >= CL_TYPE_TEXT_ASCII && ftype <= CL_TYPE_TEXT_UTF16BE) { lseek(fd, 0, SEEK_SET); - ret = cli_scandesc(fd, ctx, 0, CL_TYPE_MAIL, 0, NULL); + ret = cli_scandesc(fd, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR); } close(fd); if(ret == CL_VIRUS) { @@ -250,7 +250,7 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx if(DETECT_ENCRYPTED && metadata->encrypted) { cli_dbgmsg("RAR: Encrypted files found in archive.\n"); lseek(desc, 0, SEEK_SET); - ret = cli_scandesc(desc, ctx, 0, 0, 0, NULL); + ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR); if(ret != CL_VIRUS) { *ctx->virname = "Encrypted.RAR"; return CL_VIRUS; @@ -829,7 +829,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx) if (fd >= 0) { ofd = cli_decode_ole_object(fd, dirname); if (ofd >= 0) { - ret = cli_scandesc(ofd, ctx, 0, 0, 0, NULL); + ret = cli_scandesc(ofd, ctx, 0, 0, NULL, AC_SCAN_VIR); close(ofd); } close(fd); @@ -913,7 +913,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx) snprintf(fullname, 1024, "%s/nocomment.html", tempname); fd = open(fullname, O_RDONLY|O_BINARY); if (fd >= 0) { - ret = cli_scandesc(fd, ctx, 0, CL_TYPE_HTML, 0, NULL); + ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR); close(fd); } @@ -923,7 +923,7 @@ static int cli_scanhtml(int desc, cli_ctx *ctx) snprintf(fullname, 1024, "%s/notags.html", tempname); fd = open(fullname, O_RDONLY|O_BINARY); if(fd >= 0) { - ret = cli_scandesc(fd, ctx, 0, CL_TYPE_HTML, 0, NULL); + ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR); close(fd); } } @@ -1519,20 +1519,19 @@ static int cli_scanembpe(int desc, cli_ctx *ctx) static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg) { int ret = CL_CLEAN, nret = CL_CLEAN; - uint8_t ftrec = 0, break_loop = 0; struct cli_matched_type *ftoffset = NULL, *fpt; uint32_t lastzip, lastrar; struct cli_exe_info peinfo; + unsigned int acmode = AC_SCAN_VIR, break_loop = 0; if(typercg) switch(type) { case CL_TYPE_TEXT_ASCII: case CL_TYPE_MSEXE: case CL_TYPE_ZIP: - ftrec = 1; - break; + acmode |= AC_SCAN_FT; default: - ftrec = 0; + break; } if(lseek(desc, 0, SEEK_SET) < 0) { @@ -1540,7 +1539,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg) return CL_EIO; } - ret = cli_scandesc(desc, ctx, ftrec, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset); + ret = cli_scandesc(desc, ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode); if(ret >= CL_TYPENO) { @@ -1692,7 +1691,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) if(!ctx->options) { /* raw mode (stdin, etc.) */ cli_dbgmsg("Raw mode: No support for special files\n"); - if((ret = cli_scandesc(desc, ctx, 0, 0, 0, NULL)) == CL_VIRUS) + if((ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR)) == CL_VIRUS) cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc); return ret; } diff --git a/sigtool/sigtool.c b/sigtool/sigtool.c index d8ff739c4..4c83056de 100644 --- a/sigtool/sigtool.c +++ b/sigtool/sigtool.c @@ -73,7 +73,7 @@ static const struct dblist_s { { "COPYING", 0 }, { "daily.cfg", 0 }, { "daily.ign", 0 }, - { "daily.ft", 0 }, + { "daily.ftm", 0 }, { "main.info", 0 }, { "daily.info", 0 }, /* databases */