[Forensics-changes] [yara] 297/407: Implement a function to check for undefined values. Minor improvements in PE module.

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:28:38 UTC 2017


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

bengen pushed a commit to annotated tag v3.3.0
in repository yara.

commit d2044aa78c7da54d3832a18dee291b8ccaf62838
Author: Victor M. Alvarez <plusvic at gmail.com>
Date:   Fri Jan 2 20:35:04 2015 +0100

    Implement a function to check for undefined values. Minor improvements in PE module.
---
 libyara/include/yara/modules.h |  4 +++
 libyara/include/yara/object.h  |  5 +++
 libyara/modules/pe.c           | 76 ++++++++++++++++++++++--------------------
 libyara/object.c               | 34 +++++++++++++++++++
 4 files changed, 82 insertions(+), 37 deletions(-)

diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h
index 067ea3f..13c72a9 100644
--- a/libyara/include/yara/modules.h
+++ b/libyara/include/yara/modules.h
@@ -289,6 +289,10 @@ limitations under the License.
       (context)->mem_block
 
 
+#define is_undefined(object, ...) \
+    yr_object_has_undefined_value(object, __VA_ARGS__)
+
+
 #define get_object(object, ...) \
     yr_object_lookup(object, 0, __VA_ARGS__)
 
diff --git a/libyara/include/yara/object.h b/libyara/include/yara/object.h
index 9cbe7d3..7929529 100644
--- a/libyara/include/yara/object.h
+++ b/libyara/include/yara/object.h
@@ -69,6 +69,11 @@ YR_OBJECT* yr_object_lookup(
     ...);
 
 
+int yr_object_has_undefined_value(
+    YR_OBJECT* object,
+    const char* field,
+    ...);
+
 int64_t yr_object_get_integer(
     YR_OBJECT* object,
     const char* field,
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index ced7f02..d9421ee 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -1167,18 +1167,17 @@ define_function(valid_on)
 define_function(section_index)
 {
   YR_OBJECT* module = module();
-  SIZED_STRING* sect;
-  char* name = string_argument(1);
-
-  int64_t n = get_integer(module, "number_of_sections");
-  int64_t i;
 
-  if (n == UNDEFINED)
+  if (is_undefined(module, "number_of_sections"))
     return_integer(UNDEFINED);
 
-  for (i = 0; i < n; i++)
+  char* name = string_argument(1);
+  int64_t n = get_integer(module, "number_of_sections");
+
+  for (int64_t i = 0; i < n; i++)
   {
-    sect = get_string(module, "sections[%i].name", i);
+    SIZED_STRING* sect = get_string(module, "sections[%i].name", i);
+
     if (strcmp(name, sect->c_string) == 0)
       return_integer(i);
   }
@@ -1194,33 +1193,27 @@ define_function(exports)
   YR_OBJECT* module = module();
   PE* pe = (PE*) module->data;
 
-  PIMAGE_DATA_DIRECTORY directory;
-  PIMAGE_EXPORT_DIRECTORY exports;
-  DWORD* names;
-
-  char* name;
-  int i;
-  uint64_t offset;
-
   // If not a PE file, return UNDEFINED
 
   if (pe == NULL)
     return_integer(UNDEFINED);
 
-  directory = pe_get_directory_entry(pe, IMAGE_DIRECTORY_ENTRY_EXPORT);
+  PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry(
+      pe, IMAGE_DIRECTORY_ENTRY_EXPORT);
 
   // If the PE doesn't export any functions, return FALSE
 
   if (directory->VirtualAddress == 0)
     return_integer(0);
 
-  offset = pe_rva_to_offset(pe, directory->VirtualAddress);
+  uint64_t offset = pe_rva_to_offset(pe, directory->VirtualAddress);
 
   if (offset == 0 ||
       offset >= pe->data_size)
     return_integer(0);
 
-  exports = (PIMAGE_EXPORT_DIRECTORY)(pe->data + offset);
+  PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY) \
+      (pe->data + offset);
 
   offset = pe_rva_to_offset(pe, exports->AddressOfNames);
 
@@ -1228,16 +1221,16 @@ define_function(exports)
       offset + exports->NumberOfNames * sizeof(DWORD) > pe->data_size)
     return_integer(0);
 
-  names = (DWORD*)(pe->data + offset);
+  DWORD* names = (DWORD*)(pe->data + offset);
 
-  for (i = 0; i < exports->NumberOfNames; i++)
+  for (int i = 0; i < exports->NumberOfNames; i++)
   {
     offset = pe_rva_to_offset(pe, names[i]);
 
     if (offset == 0 || offset >= pe->data_size)
       return_integer(0);
 
-    name = (char*)(pe->data + offset);
+    char* name = (char*)(pe->data + offset);
 
     if (strncmp(name, function_name, pe->data_size - offset) == 0)
       return_integer(1);
@@ -1270,7 +1263,7 @@ define_function(imphash)
 
   PE* pe = (PE*) module->data;
 
-  // If not a PE, return 0.
+  // If not a PE, return UNDEFINED.
 
   if (!pe)
     return_string(UNDEFINED);
@@ -1383,6 +1376,7 @@ define_function(imports)
         imported_func = imported_func->next;
       }
     }
+
     imported_dll = imported_dll->next;
   }
 
@@ -1392,21 +1386,25 @@ define_function(imports)
 
 define_function(locale)
 {
-  int64_t n;
-  uint64_t rsrc_language;
-  uint64_t locale = integer_argument(1);
-
   YR_OBJECT* module = module();
+
+  if (is_undefined(module, "number_of_resources"))
+    return_integer(UNDEFINED);
+
+  uint64_t locale = integer_argument(1);
   PE* pe = (PE*) module->data;
 
   // If not a PE file, return UNDEFINED
+
   if (pe == NULL)
     return_integer(UNDEFINED);
 
-  n = get_integer(module, "number_of_resources");
-  for (int i = 0; i < n; i++)
+  int64_t n = get_integer(module, "number_of_resources");
+
+  for (int64_t i = 0; i < n; i++)
   {
-    rsrc_language = get_integer(module, "resources[%i].language", i);
+    uint64_t rsrc_language = get_integer(module, "resources[%i].language", i);
+
     if ((rsrc_language & 0xFFFF) == locale)
       return_integer(1);
   }
@@ -1417,21 +1415,25 @@ define_function(locale)
 
 define_function(language)
 {
-  int64_t n;
-  uint64_t rsrc_language;
-  uint64_t language = integer_argument(1);
-
   YR_OBJECT* module = module();
+
+  if (is_undefined(module, "number_of_resources"))
+    return_integer(UNDEFINED);
+
+  uint64_t language = integer_argument(1);
   PE* pe = (PE*) module->data;
 
   // If not a PE file, return UNDEFINED
+
   if (pe == NULL)
     return_integer(UNDEFINED);
 
-  n = get_integer(module, "number_of_resources");
-  for (int i = 0; i < n; i++)
+  int64_t n = get_integer(module, "number_of_resources");
+
+  for (int64_t i = 0; i < n; i++)
   {
-    rsrc_language = get_integer(module, "resources[%i].language", i);
+    uint64_t rsrc_language = get_integer(module, "resources[%i].language", i);
+
     if ((rsrc_language & 0xFF) == language)
       return_integer(1);
   }
diff --git a/libyara/object.c b/libyara/object.c
index 050afb3..74318ea 100644
--- a/libyara/object.c
+++ b/libyara/object.c
@@ -816,6 +816,40 @@ int yr_object_dict_set_item(
 }
 
 
+int yr_object_has_undefined_value(
+    YR_OBJECT* object,
+    const char* field,
+    ...)
+{
+  YR_OBJECT* field_obj;
+
+  va_list args;
+  va_start(args, field);
+
+  if (field != NULL)
+    field_obj = _yr_object_lookup(object, 0, field, args);
+  else
+    field_obj = object;
+
+  va_end(args);
+
+  if (field_obj == NULL)
+    return TRUE;
+
+  switch(field_obj->type)
+  {
+    case OBJECT_TYPE_DOUBLE:
+      return isnan(((YR_OBJECT_DOUBLE*) field_obj)->value);
+    case OBJECT_TYPE_STRING:
+      return ((YR_OBJECT_STRING*) field_obj)->value == NULL;
+    case OBJECT_TYPE_INTEGER:
+      return ((YR_OBJECT_INTEGER*) field_obj)->value == UNDEFINED;
+  }
+
+  return FALSE;
+}
+
+
 int64_t yr_object_get_integer(
     YR_OBJECT* object,
     const char* field,

-- 
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