[Forensics-changes] [yara] 01/05: New upstream version 3.7.1

Hilko Bengen bengen at moszumanska.debian.org
Tue Jan 16 12:50:43 UTC 2018


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to branch master
in repository yara.

commit 3e2af45b1cc5551c12563cea8785bd9cf7c0b102
Author: Hilko Bengen <bengen at debian.org>
Date:   Tue Jan 16 13:41:59 2018 +0100

    New upstream version 3.7.1
---
 configure.ac                   |   2 +-
 docs/conf.py                   |   2 +-
 docs/modules/dotnet.rst        |   1 -
 docs/modules/pe.rst            |   9 ++
 docs/writingmodules.rst        |   2 +-
 libyara/Makefile.am            |   2 +-
 libyara/compiler.c             |  65 +-----------
 libyara/include/yara/libyara.h |   2 +-
 libyara/include/yara/limits.h  |   2 +-
 libyara/include/yara/re.h      |   2 +-
 libyara/lexer.c                | 226 ++++++++++++++++++++++++++---------------
 libyara/lexer.l                |  64 +++++++++++-
 libyara/modules/pe.c           |  29 +++++-
 tests/data/baz.yar             |   1 +
 tests/data/foo.yar             |   3 +
 tests/data/include/bar.yar     |   3 +
 tests/data/true.yar            |   1 -
 tests/test-api.c               |   4 +-
 tests/test-rules.c             |   6 +-
 19 files changed, 265 insertions(+), 161 deletions(-)

diff --git a/configure.ac b/configure.ac
index e8fa183..eb88ff8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([yara], [3.7.0], [vmalvarez at virustotal.com])
+AC_INIT([yara], [3.7.1], [vmalvarez at virustotal.com])
 
 AM_SILENT_RULES([yes])
 AC_CONFIG_SRCDIR([yara.c])
diff --git a/docs/conf.py b/docs/conf.py
index c876d50..8e5e559 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -53,7 +53,7 @@ copyright = u'2014-2017, VirusTotal'
 # The short X.Y version.
 version = '3.7'
 # The full version, including alpha/beta/rc tags.
-release = '3.7.0'
+release = '3.7.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/modules/dotnet.rst b/docs/modules/dotnet.rst
index cf5dcc2..2411e4c 100644
--- a/docs/modules/dotnet.rst
+++ b/docs/modules/dotnet.rst
@@ -165,7 +165,6 @@ Reference
 
         String containing the public key or token which identifies the author of
         this assembly.
-        assembly.
 
 .. c:type:: number_of_user_strings
 
diff --git a/docs/modules/pe.rst b/docs/modules/pe.rst
index 4a156f9..a3f414f 100644
--- a/docs/modules/pe.rst
+++ b/docs/modules/pe.rst
@@ -533,6 +533,15 @@ Reference
 
     *Example:  pe.exports(72)*
 
+.. c:function:: exports(/regular_expression/)
+
+    .. versionadded:: 3.7.1
+
+    Function returning true if the PE exports *regular_expression* or
+    false otherwise.
+
+    *Example:  pe.exports(/^AXS@@/)*
+
 .. c:type:: number_of_exports
 
     .. versionadded:: 3.6.0
diff --git a/docs/writingmodules.rst b/docs/writingmodules.rst
index a5f9775..b3fab50 100644
--- a/docs/writingmodules.rst
+++ b/docs/writingmodules.rst
@@ -201,7 +201,7 @@ In our case the resulting *module_list* is::
     MODULE(demo)
 
 The second step is modifying the *Makefile.am* to tell the *make* program that
-the source code for your module most be compiled and linked into YARA. At the
+the source code for your module must be compiled and linked into YARA. At the
 very beginning of *libyara/Makefile.am* you'll find this::
 
     MODULES =  modules/tests.c
diff --git a/libyara/Makefile.am b/libyara/Makefile.am
index 2944147..7efadbb 100644
--- a/libyara/Makefile.am
+++ b/libyara/Makefile.am
@@ -103,7 +103,7 @@ noinst_HEADERS = \
 
 lib_LTLIBRARIES = libyara.la
 
-libyara_la_LDFLAGS = -version-number 3:7:0
+libyara_la_LDFLAGS = -version-number 3:7:1
 
 BUILT_SOURCES = \
   lexer.c \
diff --git a/libyara/compiler.c b/libyara/compiler.c
index d362f03..2661e8d 100644
--- a/libyara/compiler.c
+++ b/libyara/compiler.c
@@ -56,7 +56,7 @@ static void _yr_compiler_default_include_free(
     const char* callback_result_ptr,
     void* user_data)
 {
-  if(callback_result_ptr != NULL)
+  if (callback_result_ptr != NULL)
   {
     yr_free((void*)callback_result_ptr);
   }
@@ -73,14 +73,7 @@ const char* _yr_compiler_default_include_callback(
   struct stat stbuf;
   #endif
 
-  #ifdef _MSC_VER
-  char* b = NULL;
-  #endif
-
-  char* s = NULL;
-  char* f;
   char* file_buffer;
-  char buffer[1024];
 
   #ifdef _MSC_VER
   long file_size;
@@ -90,62 +83,11 @@ const char* _yr_compiler_default_include_callback(
 
   int fd = -1;
 
-  if (calling_rule_filename != NULL)
-    strlcpy(buffer, calling_rule_filename, sizeof(buffer));
-  else
-    buffer[0] = '\0';
-
-  s = strrchr(buffer, '/');
-
-  #ifdef _MSC_VER
-  b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
-  #endif
-
   #ifdef _MSC_VER
-  if (s != NULL || b != NULL)
+  _sopen_s(&fd, include_name, _O_RDONLY, _SH_DENYRW, _S_IREAD);
   #else
-  if (s != NULL)
+  fd = open(include_name, O_RDONLY);
   #endif
-  {
-    #ifdef _MSC_VER
-    f = (b > s) ? (b + 1) : (s + 1);
-    #else
-    f = s + 1;
-    #endif
-
-    strlcpy(f, include_name, sizeof(buffer) - (f - buffer));
-
-    f = buffer;
-
-    // SECURITY: Potential for directory traversal here.
-    #ifdef _MSC_VER
-    _sopen_s(&fd, f, _O_RDONLY, _SH_DENYRW, _S_IREAD);
-    #else
-    fd = open(f, O_RDONLY);
-    #endif
-
-    // if include file was not found relative to current source file,
-    // try to open it with path as specified by user (maybe user wrote
-    // a full path)
-    if (fd == -1)
-    {
-      f = (char*) include_name;
-    }
-  }
-  else
-  {
-    f = (char*) include_name;
-  }
-
-  if (fd == -1)
-  {
-    // SECURITY: Potential for directory traversal here.
-    #ifdef _MSC_VER
-    _sopen_s(&fd, f, _O_RDONLY, _SH_DENYRW, _S_IREAD);
-    #else
-    fd = open(f, O_RDONLY);
-    #endif
-  }
 
   if (fd == -1)
     return NULL;
@@ -220,6 +162,7 @@ YR_API int yr_compiler_create(
   new_compiler->errors = 0;
   new_compiler->callback = NULL;
   new_compiler->include_callback = _yr_compiler_default_include_callback;
+  new_compiler->incl_clbk_user_data = NULL;
   new_compiler->include_free = _yr_compiler_default_include_free;
   new_compiler->last_error = ERROR_SUCCESS;
   new_compiler->last_error_line = 0;
diff --git a/libyara/include/yara/libyara.h b/libyara/include/yara/libyara.h
index cbddd1a..b0748cb 100644
--- a/libyara/include/yara/libyara.h
+++ b/libyara/include/yara/libyara.h
@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define YR_MAJOR_VERSION   3
 #define YR_MINOR_VERSION   7
-#define YR_MICRO_VERSION   0
+#define YR_MICRO_VERSION   1
 
 #define version_str(s) _version_str(s)
 #define _version_str(s) #s
diff --git a/libyara/include/yara/limits.h b/libyara/include/yara/limits.h
index 90677be..fcae04a 100644
--- a/libyara/include/yara/limits.h
+++ b/libyara/include/yara/limits.h
@@ -82,6 +82,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define RE_MAX_FIBERS                   1024
 
 // Maximum number of levels in regexp's AST
-#define RE_MAX_AST_LEVELS               6000
+#define RE_MAX_AST_LEVELS               5000
 
 #endif
diff --git a/libyara/include/yara/re.h b/libyara/include/yara/re.h
index 43fca27..68a152b 100644
--- a/libyara/include/yara/re.h
+++ b/libyara/include/yara/re.h
@@ -169,7 +169,7 @@ struct RE
 
 struct RE_ERROR
 {
-  char message[512];
+  char message[384];
 };
 
 
diff --git a/libyara/lexer.c b/libyara/lexer.c
index a2e008b..fbe1a38 100644
--- a/libyara/lexer.c
+++ b/libyara/lexer.c
@@ -1010,11 +1010,25 @@ with noyywrap then we can remove this pragma.
 #define snprintf _snprintf
 #endif
 
-#line 1013 "lexer.c"
+static int is_absolute_path(
+    char* path)
+{
+  if (path == NULL)
+    return FALSE;
+
+  #if defined(_WIN32) || defined(__CYGWIN__)
+  return strlen(path) > 2 &&
+      path[1] == ':' && (path[2] == '/' || path[2] == '\\');
+  #else
+  return strlen(path) > 0 && path[0] == '/';
+  #endif
+}
+
+#line 1027 "lexer.c"
 #define YY_NO_UNISTD_H 1
 #define YY_NO_INPUT 1
 
-#line 1017 "lexer.c"
+#line 1031 "lexer.c"
 
 #define INITIAL 0
 #define str 1
@@ -1290,10 +1304,10 @@ YY_DECL
 		}
 
 	{
-#line 144 "lexer.l"
+#line 158 "lexer.l"
 
 
-#line 1296 "lexer.c"
+#line 1310 "lexer.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1360,208 +1374,208 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 146 "lexer.l"
+#line 160 "lexer.l"
 { return _DOT_DOT_;     }
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 147 "lexer.l"
+#line 161 "lexer.l"
 { return _LT_;          }
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 148 "lexer.l"
+#line 162 "lexer.l"
 { return _GT_;          }
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 149 "lexer.l"
+#line 163 "lexer.l"
 { return _LE_;          }
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 150 "lexer.l"
+#line 164 "lexer.l"
 { return _GE_;          }
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 151 "lexer.l"
+#line 165 "lexer.l"
 { return _EQ_;          }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 152 "lexer.l"
+#line 166 "lexer.l"
 { return _NEQ_;         }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 153 "lexer.l"
+#line 167 "lexer.l"
 { return _SHIFT_LEFT_;  }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 154 "lexer.l"
+#line 168 "lexer.l"
 { return _SHIFT_RIGHT_; }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 155 "lexer.l"
+#line 169 "lexer.l"
 { return _PRIVATE_;     }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 156 "lexer.l"
+#line 170 "lexer.l"
 { return _GLOBAL_;      }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 157 "lexer.l"
+#line 171 "lexer.l"
 { return _RULE_;        }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 158 "lexer.l"
+#line 172 "lexer.l"
 { return _META_;        }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 159 "lexer.l"
+#line 173 "lexer.l"
 { return _STRINGS_;     }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 160 "lexer.l"
+#line 174 "lexer.l"
 { return _ASCII_;       }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 161 "lexer.l"
+#line 175 "lexer.l"
 { return _WIDE_;        }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 162 "lexer.l"
+#line 176 "lexer.l"
 { return _FULLWORD_;    }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 163 "lexer.l"
+#line 177 "lexer.l"
 { return _NOCASE_;      }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 164 "lexer.l"
+#line 178 "lexer.l"
 { return _CONDITION_;   }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 165 "lexer.l"
+#line 179 "lexer.l"
 { return _TRUE_;        }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 166 "lexer.l"
+#line 180 "lexer.l"
 { return _FALSE_;       }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 167 "lexer.l"
+#line 181 "lexer.l"
 { return _NOT_;         }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 168 "lexer.l"
+#line 182 "lexer.l"
 { return _AND_;         }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 169 "lexer.l"
+#line 183 "lexer.l"
 { return _OR_;          }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 170 "lexer.l"
+#line 184 "lexer.l"
 { return _AT_;          }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 171 "lexer.l"
+#line 185 "lexer.l"
 { return _IN_;          }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 172 "lexer.l"
+#line 186 "lexer.l"
 { return _OF_;          }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 173 "lexer.l"
+#line 187 "lexer.l"
 { return _THEM_;        }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 174 "lexer.l"
+#line 188 "lexer.l"
 { return _FOR_;         }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 175 "lexer.l"
+#line 189 "lexer.l"
 { return _ALL_;         }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 176 "lexer.l"
+#line 190 "lexer.l"
 { return _ANY_;         }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 177 "lexer.l"
+#line 191 "lexer.l"
 { return _ENTRYPOINT_;  }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 178 "lexer.l"
+#line 192 "lexer.l"
 { return _FILESIZE_;    }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 179 "lexer.l"
+#line 193 "lexer.l"
 { return _MATCHES_;     }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 180 "lexer.l"
+#line 194 "lexer.l"
 { return _CONTAINS_;    }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 181 "lexer.l"
+#line 195 "lexer.l"
 { return _IMPORT_;      }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 184 "lexer.l"
+#line 198 "lexer.l"
 { BEGIN(comment);       }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 185 "lexer.l"
+#line 199 "lexer.l"
 { BEGIN(INITIAL);       }
 	YY_BREAK
 case 39:
 /* rule 39 can match eol */
 YY_RULE_SETUP
-#line 186 "lexer.l"
+#line 200 "lexer.l"
 { /* skip comments */   }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 189 "lexer.l"
+#line 203 "lexer.l"
 { /* skip single-line comments */ }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 192 "lexer.l"
+#line 206 "lexer.l"
 {
                           yyextra->lex_buf_ptr = yyextra->lex_buf;
                           yyextra->lex_buf_len = 0;
@@ -1571,33 +1585,76 @@ YY_RULE_SETUP
 case 42:
 /* rule 42 can match eol */
 YY_RULE_SETUP
-#line 199 "lexer.l"
+#line 213 "lexer.l"
 { yytext_to_buffer; }
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 202 "lexer.l"
+#line 216 "lexer.l"
 {
 
   if (compiler->include_callback != NULL)
   {
+    #ifdef _MSC_VER
+    char* b = NULL;
+    #endif
+    char* s = NULL;
+    char* f;
+
+    char buffer[1024];
     const char* included_rules;
     char* current_file_name;
+    char* include_path;
 
     *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path
 
-    // move path of current source file into buffer
     current_file_name = yr_compiler_get_current_file_name(compiler);
 
+    if (current_file_name == NULL ||
+        compiler->include_callback != _yr_compiler_default_include_callback ||
+        is_absolute_path(yyextra->lex_buf))
+    {
+      include_path = yyextra->lex_buf;
+    }
+    else
+    {
+      strlcpy(buffer, current_file_name, sizeof(buffer));
+      s = strrchr(buffer, '/');
+
+      #ifdef _MSC_VER
+      b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
+      #endif
+
+      #ifdef _MSC_VER
+      if (s != NULL || b != NULL)
+      #else
+      if (s != NULL)
+      #endif
+      {
+        #ifdef _MSC_VER
+        f = (b > s) ? (b + 1) : (s + 1);
+        #else
+        f = s + 1;
+        #endif
+
+        strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer));
+        include_path = buffer;
+      }
+      else
+      {
+        include_path = yyextra->lex_buf;
+      }
+    }
+
     included_rules = compiler->include_callback(
-        yyextra->lex_buf,
+        include_path,
         current_file_name,
         compiler->current_namespace->name,
         compiler->incl_clbk_user_data);
 
     if (included_rules != NULL)
     {
-      int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf);
+      int error_code = _yr_compiler_push_file_name(compiler, include_path);
 
       if (error_code != ERROR_SUCCESS)
       {
@@ -1665,7 +1722,7 @@ case YY_STATE_EOF(str):
 case YY_STATE_EOF(regexp):
 case YY_STATE_EOF(include):
 case YY_STATE_EOF(comment):
-#line 286 "lexer.l"
+#line 343 "lexer.l"
 {
 
   YR_COMPILER* compiler = yyget_extra(yyscanner);
@@ -1681,7 +1738,7 @@ case YY_STATE_EOF(comment):
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 300 "lexer.l"
+#line 357 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1694,7 +1751,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 311 "lexer.l"
+#line 368 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1707,7 +1764,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 322 "lexer.l"
+#line 379 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1726,7 +1783,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 339 "lexer.l"
+#line 396 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1745,7 +1802,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 356 "lexer.l"
+#line 413 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1764,7 +1821,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 373 "lexer.l"
+#line 430 "lexer.l"
 {
 
   char* text = yytext;
@@ -1805,7 +1862,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 412 "lexer.l"
+#line 469 "lexer.l"
 {
 
   if (strlen(yytext) > 128)
@@ -1821,7 +1878,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 426 "lexer.l"
+#line 483 "lexer.l"
 {
 
   char *endptr;
@@ -1864,7 +1921,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 466 "lexer.l"
+#line 523 "lexer.l"
 {
   yylval->double_ = atof(yytext);
   return _DOUBLE_;
@@ -1872,7 +1929,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 471 "lexer.l"
+#line 528 "lexer.l"
 {
 
   char *endptr;
@@ -1891,7 +1948,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 487 "lexer.l"
+#line 544 "lexer.l"
 {
 
   char *endptr;
@@ -1910,7 +1967,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 504 "lexer.l"
+#line 561 "lexer.l"
 {     /* saw closing quote - all done */
 
   alloc_sized_string(s, yyextra->lex_buf_len);
@@ -1926,7 +1983,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 518 "lexer.l"
+#line 575 "lexer.l"
 {
 
   lex_check_space_ok("\t", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1936,7 +1993,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 526 "lexer.l"
+#line 583 "lexer.l"
 {
 
   lex_check_space_ok("\n", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1946,7 +2003,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 534 "lexer.l"
+#line 591 "lexer.l"
 {
 
   lex_check_space_ok("\"", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1956,7 +2013,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 542 "lexer.l"
+#line 599 "lexer.l"
 {
 
   lex_check_space_ok("\\", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1966,7 +2023,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 550 "lexer.l"
+#line 607 "lexer.l"
 {
 
    int result;
@@ -1979,13 +2036,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 561 "lexer.l"
+#line 618 "lexer.l"
 { yytext_to_buffer; }
 	YY_BREAK
 case 62:
 /* rule 62 can match eol */
 YY_RULE_SETUP
-#line 564 "lexer.l"
+#line 621 "lexer.l"
 {
   syntax_error("unterminated string");
 }
@@ -1993,14 +2050,14 @@ YY_RULE_SETUP
 case 63:
 /* rule 63 can match eol */
 YY_RULE_SETUP
-#line 569 "lexer.l"
+#line 626 "lexer.l"
 {
   syntax_error("illegal escape sequence");
 }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 574 "lexer.l"
+#line 631 "lexer.l"
 {
 
   if (yyextra->lex_buf_len > 0)
@@ -2028,7 +2085,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 600 "lexer.l"
+#line 657 "lexer.l"
 {
 
   lex_check_space_ok("/", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -2038,7 +2095,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 608 "lexer.l"
+#line 665 "lexer.l"
 {
 
   lex_check_space_ok("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -2053,20 +2110,20 @@ YY_RULE_SETUP
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 621 "lexer.l"
+#line 678 "lexer.l"
 { yytext_to_buffer; }
 	YY_BREAK
 case 68:
 /* rule 68 can match eol */
 YY_RULE_SETUP
-#line 624 "lexer.l"
+#line 681 "lexer.l"
 {
   syntax_error("unterminated regular expression");
 }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 629 "lexer.l"
+#line 686 "lexer.l"
 {
 
   yylval->sized_string = NULL;
@@ -2077,7 +2134,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 638 "lexer.l"
+#line 695 "lexer.l"
 {
 
   yylval->sized_string = NULL;
@@ -2089,7 +2146,7 @@ YY_RULE_SETUP
 case 71:
 /* rule 71 can match eol */
 YY_RULE_SETUP
-#line 647 "lexer.l"
+#line 704 "lexer.l"
 {
   // Match hex-digits with whitespace or comments. The latter are stripped
   // out by hex_lexer.l
@@ -2105,12 +2162,12 @@ YY_RULE_SETUP
 case 72:
 /* rule 72 can match eol */
 YY_RULE_SETUP
-#line 660 "lexer.l"
+#line 717 "lexer.l"
 /* skip whitespace */
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 662 "lexer.l"
+#line 719 "lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -2125,10 +2182,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 674 "lexer.l"
+#line 731 "lexer.l"
 ECHO;
 	YY_BREAK
-#line 2131 "lexer.c"
+#line 2188 "lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -3277,7 +3334,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 674 "lexer.l"
+#line 731 "lexer.l"
 
 
 
@@ -3494,3 +3551,4 @@ int yr_lex_parse_rules_fd(
   return compiler->errors;
 }
 
+
diff --git a/libyara/lexer.l b/libyara/lexer.l
index f2c8b9d..5f50d7f 100644
--- a/libyara/lexer.l
+++ b/libyara/lexer.l
@@ -116,6 +116,20 @@ with noyywrap then we can remove this pragma.
 #define snprintf _snprintf
 #endif
 
+static int is_absolute_path(
+    char* path)
+{
+  if (path == NULL)
+    return FALSE;
+
+  #if defined(_WIN32) || defined(__CYGWIN__)
+  return strlen(path) > 2 &&
+      path[1] == ':' && (path[2] == '/' || path[2] == '\\');
+  #else
+  return strlen(path) > 0 && path[0] == '/';
+  #endif
+}
+
 %}
 
 %option reentrant bison-bridge
@@ -203,23 +217,66 @@ include[ \t]+\"         {
 
   if (compiler->include_callback != NULL)
   {
+    #ifdef _MSC_VER
+    char* b = NULL;
+    #endif
+    char* s = NULL;
+    char* f;
+
+    char buffer[1024];
     const char* included_rules;
     char* current_file_name;
+    char* include_path;
 
     *yyextra->lex_buf_ptr = '\0'; // null-terminate included file path
 
-    // move path of current source file into buffer
     current_file_name = yr_compiler_get_current_file_name(compiler);
 
+    if (current_file_name == NULL ||
+        compiler->include_callback != _yr_compiler_default_include_callback ||
+        is_absolute_path(yyextra->lex_buf))
+    {
+      include_path = yyextra->lex_buf;
+    }
+    else
+    {
+      strlcpy(buffer, current_file_name, sizeof(buffer));
+      s = strrchr(buffer, '/');
+
+      #ifdef _MSC_VER
+      b = strrchr(buffer, '\\'); // in Windows both path delimiters are accepted
+      #endif
+
+      #ifdef _MSC_VER
+      if (s != NULL || b != NULL)
+      #else
+      if (s != NULL)
+      #endif
+      {
+        #ifdef _MSC_VER
+        f = (b > s) ? (b + 1) : (s + 1);
+        #else
+        f = s + 1;
+        #endif
+
+        strlcpy(f, yyextra->lex_buf, sizeof(buffer) - (f - buffer));
+        include_path = buffer;
+      }
+      else
+      {
+        include_path = yyextra->lex_buf;
+      }
+    }
+
     included_rules = compiler->include_callback(
-        yyextra->lex_buf,
+        include_path,
         current_file_name,
         compiler->current_namespace->name,
         compiler->incl_clbk_user_data);
 
     if (included_rules != NULL)
     {
-      int error_code = _yr_compiler_push_file_name(compiler, yyextra->lex_buf);
+      int error_code = _yr_compiler_push_file_name(compiler, include_path);
 
       if (error_code != ERROR_SUCCESS)
       {
@@ -886,3 +943,4 @@ int yr_lex_parse_rules_fd(
 
   return compiler->errors;
 }
+
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 15385cd..a4205c0 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -1563,6 +1563,32 @@ define_function(exports)
 }
 
 
+define_function(exports_regexp)
+{
+  RE* regex = regexp_argument(1);
+
+  YR_OBJECT* module = module();
+  PE* pe = (PE*) module->data;
+
+  IMPORT_EXPORT_FUNCTION* exported_func;
+
+  if (!pe)
+    return_integer(UNDEFINED);
+
+  exported_func = pe->exported_functions;
+
+  while (exported_func != NULL)
+  {
+    if (yr_re_match(regex, exported_func->name) != -1)
+      return_integer(1);
+
+    exported_func = exported_func->next;
+  }
+
+  return_integer(0);
+}
+
+
 define_function(exports_ordinal)
 {
   uint64_t ordinal = integer_argument(1);
@@ -2017,7 +2043,7 @@ define_function(calculate_checksum)
     if (4 * i == csum_offset)
       continue;
 
-    if (4 * i + 4 < pe->data_size)
+    if (4 * i + 4 <= pe->data_size)
     {
       csum += ((uint64_t) pe->data[4 * i] +
           ((uint64_t) pe->data[4 * i + 1] << 8)  +
@@ -2233,6 +2259,7 @@ begin_declarations;
   declare_function("section_index", "s", "i", section_index_name);
   declare_function("section_index", "i", "i", section_index_addr);
   declare_function("exports", "s", "i", exports);
+  declare_function("exports", "r", "i", exports_regexp);
   declare_function("exports", "i", "i", exports_ordinal);
   declare_function("imports", "ss", "i", imports);
   declare_function("imports", "si", "i", imports_ordinal);
diff --git a/tests/data/baz.yar b/tests/data/baz.yar
new file mode 100644
index 0000000..25a89aa
--- /dev/null
+++ b/tests/data/baz.yar
@@ -0,0 +1 @@
+rule baz { condition: true }
diff --git a/tests/data/foo.yar b/tests/data/foo.yar
new file mode 100644
index 0000000..507213c
--- /dev/null
+++ b/tests/data/foo.yar
@@ -0,0 +1,3 @@
+include "include/bar.yar"
+
+rule foo { condition: bar }
diff --git a/tests/data/include/bar.yar b/tests/data/include/bar.yar
new file mode 100644
index 0000000..b5db2ab
--- /dev/null
+++ b/tests/data/include/bar.yar
@@ -0,0 +1,3 @@
+include "../baz.yar"
+
+rule bar { condition: baz }
diff --git a/tests/data/true.yar b/tests/data/true.yar
deleted file mode 100644
index 55d91be..0000000
--- a/tests/data/true.yar
+++ /dev/null
@@ -1 +0,0 @@
-rule test { condition: true }
diff --git a/tests/test-api.c b/tests/test-api.c
index 3f18675..80de2c3 100644
--- a/tests/test-api.c
+++ b/tests/test-api.c
@@ -105,14 +105,14 @@ void test_file_descriptor()
   YR_RULES* rules = NULL;
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-  HANDLE fd = CreateFile("tests/data/true.yar", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+  HANDLE fd = CreateFile("tests/data/baz.yar", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
   if (fd == INVALID_HANDLE_VALUE)
   {
     fputs("CreateFile failed", stderr);
     exit(1);
   }
 #else
-  int fd = open("tests/data/true.yar", O_RDONLY);
+  int fd = open("tests/data/baz.yar", O_RDONLY);
   if (fd < 0)
   {
     perror("open");
diff --git a/tests/test-rules.c b/tests/test-rules.c
index 6d0a7e3..99c7e1c 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -1737,7 +1737,11 @@ void test_integer_functions()
 void test_include_files()
 {
   assert_true_rule(
-    "include \"tests/data/true.yar\" rule t { condition: test }",
+    "include \"tests/data/baz.yar\" rule t { condition: baz }",
+    NULL);
+
+  assert_true_rule(
+    "include \"tests/data/foo.yar\" rule t { condition: foo }",
     NULL);
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git



More information about the forensics-changes mailing list