Browse code

add support for floating offsets

git-svn: trunk@2922

Tomasz Kojm authored on 2007/03/09 12:29:28
Showing 6 changed files
... ...
@@ -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
4 10
Binary files a/docs/signatures.pdf and b/docs/signatures.pdf differ
... ...
@@ -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