git-svn: trunk@2922
Tomasz Kojm authored on 2007/03/09 12:29:28... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Fri Mar 9 02:34:11 CET 2007 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav/matcher.c: add support for floating offsets, requested by |
|
4 |
+ Christoph |
|
5 |
+ * docs: update signatures.pdf |
|
6 |
+ |
|
1 | 7 |
Thu Mar 8 22:45:39 CET 2007 (tk) |
2 | 8 |
--------------------------------- |
3 | 9 |
* libclamav/matcher-ac.c: fix incorrect calculation of maxshift in some cases |
... | ... |
@@ -150,7 +150,16 @@ MalwareName:TargetType:Offset:HexSignature[:MinEngineFunctionalityLevel:[Max]] |
150 | 150 |
\item \verb#SL+n# = start of last section plus \verb+n+ bytes |
151 | 151 |
\item \verb#SL-n# = start of last section minus \verb+n+ bytes |
152 | 152 |
\end{itemize} |
153 |
- All signatures in the extended format must be placed in \verb+*.ndb+ files. |
|
153 |
+ All the above offsets except \verb+*+ can be turned into |
|
154 |
+ \textbf{floating offsets} and represented as \verb+Offset,MaxShift+ where |
|
155 |
+ \verb+MaxShift+ is an unsigned integer. A floating offset will match every |
|
156 |
+ offset between \verb+Offset+ and \verb#Offset+MaxShift#, eg. \verb+10,5+ |
|
157 |
+ will match all offsets from 10 to 15 and \verb#EP+n,y# will match all |
|
158 |
+ offsets from \verb#EP+n# to \verb#EP+n+y#. Versions of ClamAV older than |
|
159 |
+ 0.91 will silently ignore the \verb+MaxShift+ extension and only use |
|
160 |
+ \verb+Offset+.\\ |
|
161 |
+ |
|
162 |
+ All signatures in the extended format must be placed inside \verb+*.ndb+ files. |
|
154 | 163 |
|
155 | 164 |
\subsection{Signatures based on archive metadata} |
156 | 165 |
In order to detect some malware which spreads inside of Zip or RAR archives |
... | ... |
@@ -371,7 +371,7 @@ int cli_ncore_scandesc(int desc, cli_ctx *ctx, unsigned short ftype, int *cont, |
371 | 371 |
for(i = 0; i < count; i++) { |
372 | 372 |
const char *matchname = NULL, *offsetstring = NULL, *optionalsigdata = NULL; |
373 | 373 |
unsigned long long startoffset = 0; |
374 |
- unsigned int targettype = 0; |
|
374 |
+ unsigned int targettype = 0, maxshift = 0; |
|
375 | 375 |
char *pt; |
376 | 376 |
|
377 | 377 |
/* Get the description of the match */ |
... | ... |
@@ -423,7 +423,7 @@ int cli_ncore_scandesc(int desc, cli_ctx *ctx, unsigned short ftype, int *cont, |
423 | 423 |
return CL_ENCIO; |
424 | 424 |
} |
425 | 425 |
if(offsetstring && strcmp(offsetstring, "*")) { |
426 |
- off_t off = cli_caloff(offsetstring, &info, desc, ftype, &hret); |
|
426 |
+ off_t off = cli_caloff(offsetstring, &info, desc, ftype, &hret, &maxshift); |
|
427 | 427 |
|
428 | 428 |
if(hret == -1) { |
429 | 429 |
cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Bad offset in signature\n", i, matchname); |
... | ... |
@@ -432,8 +432,13 @@ int cli_ncore_scandesc(int desc, cli_ctx *ctx, unsigned short ftype, int *cont, |
432 | 432 |
free(info.exeinfo.section); |
433 | 433 |
return CL_EMALFDB; |
434 | 434 |
} |
435 |
- if(startoffset != (unsigned long long) off) { |
|
436 |
- cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: " "%Lu, expected: %Lu\n", i, matchname, startoffset, off); |
|
435 |
+ if(maxshift) { |
|
436 |
+ if((startoffset < (unsigned long long) off) || (startoffset > (unsigned long long) off + maxshift)) { |
|
437 |
+ cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: %Lu, expected: [%Lu..%Lu]\n", i, matchname, startoffset, off, off + maxshift); |
|
438 |
+ continue; |
|
439 |
+ } |
|
440 |
+ } else if(startoffset != (unsigned long long) off) { |
|
441 |
+ cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: %Lu, expected: %Lu\n", i, matchname, startoffset, off); |
|
437 | 442 |
continue; |
438 | 443 |
} |
439 | 444 |
} |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -121,10 +121,11 @@ struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl_engine |
121 | 121 |
return NULL; |
122 | 122 |
} |
123 | 123 |
|
124 |
-off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret) |
|
124 |
+off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret, unsigned int *maxshift) |
|
125 | 125 |
{ |
126 | 126 |
int (*einfo)(int, struct cli_exe_info *) = NULL; |
127 | 127 |
unsigned int n, val; |
128 |
+ const char *pt; |
|
128 | 129 |
off_t pos, offset; |
129 | 130 |
|
130 | 131 |
|
... | ... |
@@ -162,6 +163,9 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f |
162 | 162 |
} |
163 | 163 |
} |
164 | 164 |
|
165 |
+ if((pt = strchr(offstr, ','))) |
|
166 |
+ *maxshift = atoi(++pt); |
|
167 |
+ |
|
165 | 168 |
if(isdigit(offstr[0])) { |
166 | 169 |
return atoi(offstr); |
167 | 170 |
|
... | ... |
@@ -256,17 +260,23 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct |
256 | 256 |
{ |
257 | 257 |
off_t offset; |
258 | 258 |
int ret; |
259 |
+ unsigned int maxshift = 0; |
|
259 | 260 |
|
260 | 261 |
|
261 | 262 |
if(offstr && desc != -1) { |
262 |
- offset = cli_caloff(offstr, info, desc, ftype, &ret); |
|
263 |
+ offset = cli_caloff(offstr, info, desc, ftype, &ret, &maxshift); |
|
263 | 264 |
|
264 | 265 |
if(ret == -1) { |
265 | 266 |
cli_dbgmsg("cli_validatesig: Can't calculate offset for signature %s\n", virname); |
266 | 267 |
return 0; |
267 | 268 |
} |
268 | 269 |
|
269 |
- if(fileoff != offset) { |
|
270 |
+ if(maxshift) { |
|
271 |
+ if((fileoff < offset) || (fileoff > offset + maxshift)) { |
|
272 |
+ cli_dbgmsg("Signature offset: %lu, expected: [%lu..%lu] (%s)\n", fileoff, offset, offset + maxshift, virname); |
|
273 |
+ return 0; |
|
274 |
+ } |
|
275 |
+ } else if(fileoff != offset) { |
|
270 | 276 |
cli_dbgmsg("Signature offset: %lu, expected: %lu (%s)\n", fileoff, offset, virname); |
271 | 277 |
return 0; |
272 | 278 |
} |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
- * Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net> |
|
2 |
+ * Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> |
|
3 | 3 |
* |
4 | 4 |
* This program is free software; you can redistribute it and/or modify |
5 | 5 |
* it under the terms of the GNU General Public License as published by |
... | ... |
@@ -45,6 +45,6 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct |
45 | 45 |
|
46 | 46 |
struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl_engine *engine); |
47 | 47 |
|
48 |
-off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret); |
|
48 |
+off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret, unsigned int *maxshift); |
|
49 | 49 |
|
50 | 50 |
#endif |