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