add support for floating offsets

git-svn: trunk@2922
remotes/push_mirror/metadata
Tomasz Kojm 18 years ago
parent 95b0d95e8c
commit 9b82f82b6b
  1. 6
      ChangeLog
  2. BIN
      docs/signatures.pdf
  3. 11
      docs/signatures.tex
  4. 13
      libclamav/matcher-ncore.c
  5. 18
      libclamav/matcher.c
  6. 4
      libclamav/matcher.h

@ -1,3 +1,9 @@
Fri Mar 9 02:34:11 CET 2007 (tk)
---------------------------------
* libclamav/matcher.c: add support for floating offsets, requested by
Christoph
* docs: update signatures.pdf
Thu Mar 8 22:45:39 CET 2007 (tk)
---------------------------------
* libclamav/matcher-ac.c: fix incorrect calculation of maxshift in some cases

Binary file not shown.

@ -150,7 +150,16 @@ MalwareName:TargetType:Offset:HexSignature[:MinEngineFunctionalityLevel:[Max]]
\item \verb#SL+n# = start of last section plus \verb+n+ bytes
\item \verb#SL-n# = start of last section minus \verb+n+ bytes
\end{itemize}
All signatures in the extended format must be placed in \verb+*.ndb+ files.
All the above offsets except \verb+*+ can be turned into
\textbf{floating offsets} and represented as \verb+Offset,MaxShift+ where
\verb+MaxShift+ is an unsigned integer. A floating offset will match every
offset between \verb+Offset+ and \verb#Offset+MaxShift#, eg. \verb+10,5+
will match all offsets from 10 to 15 and \verb#EP+n,y# will match all
offsets from \verb#EP+n# to \verb#EP+n+y#. Versions of ClamAV older than
0.91 will silently ignore the \verb+MaxShift+ extension and only use
\verb+Offset+.\\
All signatures in the extended format must be placed inside \verb+*.ndb+ files.
\subsection{Signatures based on archive metadata}
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,
for(i = 0; i < count; i++) {
const char *matchname = NULL, *offsetstring = NULL, *optionalsigdata = NULL;
unsigned long long startoffset = 0;
unsigned int targettype = 0;
unsigned int targettype = 0, maxshift = 0;
char *pt;
/* Get the description of the match */
@ -423,7 +423,7 @@ int cli_ncore_scandesc(int desc, cli_ctx *ctx, unsigned short ftype, int *cont,
return CL_ENCIO;
}
if(offsetstring && strcmp(offsetstring, "*")) {
off_t off = cli_caloff(offsetstring, &info, desc, ftype, &hret);
off_t off = cli_caloff(offsetstring, &info, desc, ftype, &hret, &maxshift);
if(hret == -1) {
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,
free(info.exeinfo.section);
return CL_EMALFDB;
}
if(startoffset != (unsigned long long) off) {
cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: " "%Lu, expected: %Lu\n", i, matchname, startoffset, off);
if(maxshift) {
if((startoffset < (unsigned long long) off) || (startoffset > (unsigned long long) off + maxshift)) {
cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: %Lu, expected: [%Lu..%Lu]\n", i, matchname, startoffset, off, off + maxshift);
continue;
}
} else if(startoffset != (unsigned long long) off) {
cli_dbgmsg("cli_ncore_scandesc: HW Result[%u]: %s: Virus offset: %Lu, expected: %Lu\n", i, matchname, startoffset, off);
continue;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* 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
return NULL;
}
off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret)
off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret, unsigned int *maxshift)
{
int (*einfo)(int, struct cli_exe_info *) = NULL;
unsigned int n, val;
const char *pt;
off_t pos, offset;
@ -162,6 +163,9 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f
}
}
if((pt = strchr(offstr, ',')))
*maxshift = atoi(++pt);
if(isdigit(offstr[0])) {
return atoi(offstr);
@ -256,17 +260,23 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct
{
off_t offset;
int ret;
unsigned int maxshift = 0;
if(offstr && desc != -1) {
offset = cli_caloff(offstr, info, desc, ftype, &ret);
offset = cli_caloff(offstr, info, desc, ftype, &ret, &maxshift);
if(ret == -1) {
cli_dbgmsg("cli_validatesig: Can't calculate offset for signature %s\n", virname);
return 0;
}
if(fileoff != offset) {
if(maxshift) {
if((fileoff < offset) || (fileoff > offset + maxshift)) {
cli_dbgmsg("Signature offset: %lu, expected: [%lu..%lu] (%s)\n", fileoff, offset, offset + maxshift, virname);
return 0;
}
} else if(fileoff != offset) {
cli_dbgmsg("Signature offset: %lu, expected: %lu (%s)\n", fileoff, offset, virname);
return 0;
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* 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
struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl_engine *engine);
off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret);
off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret, unsigned int *maxshift);
#endif

Loading…
Cancel
Save