[Forensics-changes] [yara] 22/407: Implement .version_info dictionary in PE module

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:27:59 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 b746e50d8ac685a7133b70474f2a4336521c8357
Author: Victor Manuel Alvarez <vmalvarez at virustotal.com>
Date:   Mon Sep 8 16:35:37 2014 +0200

    Implement .version_info dictionary in PE module
---
 libyara/include/yara/pe.h       |  25 +++
 libyara/include/yara/strutils.h |   7 +-
 libyara/modules/pe.c            | 409 +++++++++++++++++++++++-----------------
 libyara/strutils.c              |  64 ++++++-
 4 files changed, 321 insertions(+), 184 deletions(-)

diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index da90319..7914088 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -27,6 +27,11 @@ typedef uint64_t  ULONGLONG;
 
 #define FIELD_OFFSET(type, field)    ((size_t)&(((type *)0)->field))
 
+#define ALIGN_NEXT_DWORD(ptr)  (typeof(ptr)) (((size_t) ptr + 3) & ~3)
+
+#define ADD_OFFSET(ptr, offset)  (typeof(ptr)) ((uint8_t*) (ptr) + (offset))
+
+
 #ifndef _MAC
 
 #pragma pack(push,4)                   // 4 byte packing is the default
@@ -352,6 +357,14 @@ typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
 } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
 
 
+ typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+    DWORD OffsetToData;
+    DWORD Size;
+    DWORD CodePage;
+    DWORD Reserved;
+ } IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
+
+
 typedef struct _IMAGE_RESOURCE_DIRECTORY {
     DWORD Characteristics;
     DWORD TimeDateStamp;
@@ -362,4 +375,16 @@ typedef struct _IMAGE_RESOURCE_DIRECTORY {
     IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
 } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
 
+
+typedef struct _VERSION_INFO {
+    WORD   Length;
+    WORD   ValueLength;
+    WORD   Type;
+    char   Key[0];
+} VERSION_INFO, *PVERSION_INFO;
+
+
+
+
+
 #pragma pack(pop)
diff --git a/libyara/include/yara/strutils.h b/libyara/include/yara/strutils.h
index 6fc8b0e..c5993c5 100644
--- a/libyara/include/yara/strutils.h
+++ b/libyara/include/yara/strutils.h
@@ -39,6 +39,11 @@ size_t strlcpy(char *dst, const char *src, size_t size);
 size_t strlcat(char *dst, const char *src, size_t size);
 #endif
 
-#endif
+int strlen_w(const char* w_str);
+
+int strcmp_w(const char* w_str, const char* str);
 
+size_t strlcpy_w(char* dst, const char* w_src, size_t n);
+
+#endif
 
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index fa64f66..ac8df6c 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -60,36 +60,38 @@ limitations under the License.
     ((entry)->OffsetToData & 0x7FFFFFFF)
 
 
-typedef int (*RESOURCE_CALLBACK_FUNC) \
-    (int type, int id, int language, void* cb_data);
+typedef int (*RESOURCE_CALLBACK_FUNC) ( \
+     PIMAGE_RESOURCE_DATA_ENTRY rsrc_data, \
+     int rsrc_type, \
+     int rsrc_id, \
+     int rsrc_language, \
+     void* cb_data);
 
 
-typedef struct _DATA
+typedef struct _PE
 {
-  PIMAGE_NT_HEADERS32 pe_header;
-
-  size_t pe_size;
-  size_t pe_offset;
-
   uint8_t* data;
   size_t data_size;
 
-} DATA;
+  PIMAGE_NT_HEADERS32 header;
+  YR_OBJECT* object;
+
+} PE;
 
 
 PIMAGE_NT_HEADERS32 pe_get_header(
-    uint8_t* buffer,
-    size_t buffer_length)
+    uint8_t* data,
+    size_t data_size)
 {
   PIMAGE_DOS_HEADER mz_header;
   PIMAGE_NT_HEADERS32 pe_header;
 
   size_t headers_size = 0;
 
-  if (buffer_length < sizeof(IMAGE_DOS_HEADER))
+  if (data_size < sizeof(IMAGE_DOS_HEADER))
     return NULL;
 
-  mz_header = (PIMAGE_DOS_HEADER) buffer;
+  mz_header = (PIMAGE_DOS_HEADER) data;
 
   if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
     return NULL;
@@ -101,17 +103,17 @@ PIMAGE_NT_HEADERS32 pe_get_header(
                  sizeof(pe_header->Signature) + \
                  sizeof(IMAGE_FILE_HEADER);
 
-  if (buffer_length < headers_size)
+  if (data_size < headers_size)
     return NULL;
 
-  pe_header = (PIMAGE_NT_HEADERS32) (buffer + mz_header->e_lfanew);
+  pe_header = (PIMAGE_NT_HEADERS32) (data + mz_header->e_lfanew);
 
   headers_size += pe_header->FileHeader.SizeOfOptionalHeader;
 
   if (pe_header->Signature == IMAGE_NT_SIGNATURE &&
       (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ||
        pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) &&
-      buffer_length > headers_size)
+      data_size > headers_size)
   {
     return pe_header;
   }
@@ -123,24 +125,23 @@ PIMAGE_NT_HEADERS32 pe_get_header(
 
 
 PIMAGE_DATA_DIRECTORY pe_get_directory_entry(
-    PIMAGE_NT_HEADERS32 pe_header,
+    PE* pe,
     int entry)
 {
   PIMAGE_DATA_DIRECTORY result;
 
-  if (pe_header->FileHeader.Machine == 0x8664)  // is a 64-bit PE ?
-    result = &((PIMAGE_NT_HEADERS64) pe_header)->
+  if (pe->header->FileHeader.Machine == 0x8664)  // is a 64-bit PE ?
+    result = &((PIMAGE_NT_HEADERS64) pe->header)->
         OptionalHeader.DataDirectory[entry];
   else
-    result = &pe_header->OptionalHeader.DataDirectory[entry];
+    result = &pe->header->OptionalHeader.DataDirectory[entry];
 
   return result;
 }
 
 
 uint64_t pe_rva_to_offset(
-    PIMAGE_NT_HEADERS32 pe_header,
-    size_t pe_size,
+    PE* pe,
     uint64_t rva)
 {
   PIMAGE_SECTION_HEADER section;
@@ -149,14 +150,14 @@ uint64_t pe_rva_to_offset(
 
   int i = 0;
 
-  section = IMAGE_FIRST_SECTION(pe_header);
+  section = IMAGE_FIRST_SECTION(pe->header);
   section_rva = 0;
   section_offset = 0;
 
-  while(i < min(pe_header->FileHeader.NumberOfSections, MAX_PE_SECTIONS))
+  while(i < min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS))
   {
     if ((uint8_t*) section - \
-        (uint8_t*) pe_header + sizeof(IMAGE_SECTION_HEADER) < pe_size)
+        (uint8_t*) pe->data + sizeof(IMAGE_SECTION_HEADER) < pe->data_size)
     {
       if (rva >= section->VirtualAddress &&
           section_rva <= section->VirtualAddress)
@@ -179,9 +180,9 @@ uint64_t pe_rva_to_offset(
 
 
 int _pe_iterate_resources(
+    PE* pe,
     PIMAGE_RESOURCE_DIRECTORY resource_dir,
     uint8_t* rsrc_data,
-    size_t rsrc_size,
     int rsrc_tree_level,
     int* type,
     int* id,
@@ -213,9 +214,9 @@ int _pe_iterate_resources(
     if (IS_RESOURCE_SUBDIRECTORY(entry))
     {
       result = _pe_iterate_resources(
-          (PIMAGE_RESOURCE_DIRECTORY) (rsrc_data + RESOURCE_OFFSET(entry)),
+          pe,
+          (PIMAGE_RESOURCE_DIRECTORY)(rsrc_data + RESOURCE_OFFSET(entry)),
           rsrc_data,
-          rsrc_size,
           rsrc_tree_level + 1,
           type,
           id,
@@ -228,7 +229,15 @@ int _pe_iterate_resources(
     }
     else
     {
-      result = callback(*type, *id, *language, callback_data);
+      PIMAGE_RESOURCE_DATA_ENTRY data_entry = (PIMAGE_RESOURCE_DATA_ENTRY) \
+          (rsrc_data + RESOURCE_OFFSET(entry));
+
+      result = callback(
+          data_entry,
+          *type,
+          *id,
+          *language,
+          callback_data);
 
       if (result == RESOURCE_CALLBACK_ABORT)
         return RESOURCE_ITERATOR_ABORTED;
@@ -245,9 +254,7 @@ int _pe_iterate_resources(
 
 
 int pe_iterate_resources(
-    PIMAGE_NT_HEADERS32 pe_header,
-    size_t pe_size,
-    size_t pe_offset,
+    PE* pe,
     RESOURCE_CALLBACK_FUNC callback,
     void* callback_data)
 {
@@ -258,22 +265,20 @@ int pe_iterate_resources(
   int language = -1;
 
   PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry(
-      pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE);
+      pe, IMAGE_DIRECTORY_ENTRY_RESOURCE);
 
   if (directory->VirtualAddress != 0)
   {
-    offset = pe_rva_to_offset(
-        pe_header, pe_size, directory->VirtualAddress);
+    offset = pe_rva_to_offset(pe, directory->VirtualAddress);
 
     if (offset != 0 &&
-        offset < pe_size &&
-        directory->Size < pe_size - offset)
+        offset < pe->data_size &&
+        directory->Size < pe->data_size - offset)
     {
       _pe_iterate_resources(
-          (PIMAGE_RESOURCE_DIRECTORY) \
-              ((uint8_t*) pe_header - pe_offset + offset),
-          (uint8_t*) pe_header - pe_offset + offset,
-          directory->Size,
+          pe,
+          (PIMAGE_RESOURCE_DIRECTORY) (pe->data + offset),
+          pe->data + offset,
           0,
           &type,
           &id,
@@ -289,91 +294,174 @@ int pe_iterate_resources(
 }
 
 
-void pe_parse_header(
-    PIMAGE_NT_HEADERS32 pe,
+int pe_find_version_info_cb(
+    PIMAGE_RESOURCE_DATA_ENTRY rsrc_data,
+    int rsrc_type,
+    int rsrc_id,
+    int rsrc_language,
+    PE* pe)
+{
+  PVERSION_INFO version_info;
+  PVERSION_INFO string_file_info;
+
+  char key[64];
+  char value[256];
+
+  size_t version_info_offset;
+
+  if (rsrc_type == RESOURCE_TYPE_VERSION)
+  {
+    version_info_offset = pe_rva_to_offset(pe, rsrc_data->OffsetToData);
+
+    if (version_info_offset == 0)
+      return RESOURCE_CALLBACK_CONTINUE;
+
+    version_info = (PVERSION_INFO) (pe->data + version_info_offset);
+
+    if (strcmp_w(version_info->Key, "VS_VERSION_INFO") != 0)
+      return RESOURCE_CALLBACK_CONTINUE;
+
+    string_file_info = ADD_OFFSET(version_info, sizeof(VERSION_INFO) + 86);
+
+    while(strcmp_w(string_file_info->Key, "StringFileInfo") == 0)
+    {
+      PVERSION_INFO string_table = ADD_OFFSET(
+          string_file_info,
+          sizeof(VERSION_INFO) + 30);
+
+      string_file_info = ADD_OFFSET(
+          string_file_info,
+          string_file_info->Length);
+
+      string_file_info = ALIGN_NEXT_DWORD(string_file_info);
+
+      while (string_table < string_file_info)
+      {
+        PVERSION_INFO string = ADD_OFFSET(
+            string_table,
+            sizeof(VERSION_INFO) + 2 * (strlen_w(string_table->Key) + 1));
+
+        string_table = ADD_OFFSET(
+            string_table,
+            string_table->Length);
+
+        string_table = ALIGN_NEXT_DWORD(string_table);
+
+        while (string < string_table)
+        {
+          char* string_value = (char*) ADD_OFFSET(
+              string,
+              sizeof(VERSION_INFO) + 2 * (strlen_w(string->Key) + 1));
+
+          string_value = ALIGN_NEXT_DWORD(string_value);
+
+          strlcpy_w(key, string->Key, sizeof(key));
+          strlcpy_w(value, string_value, sizeof(value));
+
+          set_string(value, pe->object, "version_info[%s]", key);
+
+          string = ADD_OFFSET(string, string->Length);
+          string = ALIGN_NEXT_DWORD(string);
+        }
+      }
+    }
+
+    return RESOURCE_CALLBACK_ABORT;
+  }
+
+  return RESOURCE_CALLBACK_CONTINUE;
+}
+
+
+void pe_parse(
+    PE* pe,
     size_t base_address,
-    size_t pe_size,
-    int flags,
-    YR_OBJECT* pe_obj)
+    int flags)
 {
   PIMAGE_SECTION_HEADER section;
 
   char section_name[IMAGE_SIZEOF_SHORT_NAME + 1];
-  int i;
 
 #define OptionalHeader(field) \
-  (pe->FileHeader.Machine == 0x8664 ? \
-   ((PIMAGE_NT_HEADERS64) pe)->OptionalHeader.field: pe->OptionalHeader.field)
+  (pe->header->FileHeader.Machine == 0x8664 ? \
+   ((PIMAGE_NT_HEADERS64) pe->header)->OptionalHeader.field : \
+     pe->header->OptionalHeader.field)
 
   set_integer(
-      pe->FileHeader.Machine,
-      pe_obj, "machine");
+      pe->header->FileHeader.Machine,
+      pe->object, "machine");
 
   set_integer(
-      pe->FileHeader.NumberOfSections,
-      pe_obj, "number_of_sections");
+      pe->header->FileHeader.NumberOfSections,
+      pe->object, "number_of_sections");
 
   set_integer(
-      pe->FileHeader.TimeDateStamp,
-      pe_obj, "timestamp");
+      pe->header->FileHeader.TimeDateStamp,
+      pe->object, "timestamp");
 
   set_integer(
-      pe->FileHeader.Characteristics,
-      pe_obj, "characteristics");
+      pe->header->FileHeader.Characteristics,
+      pe->object, "characteristics");
 
   set_integer(
       flags & SCAN_FLAGS_PROCESS_MEMORY ?
         base_address + OptionalHeader(AddressOfEntryPoint) :
-        pe_rva_to_offset(
-            pe, pe_size, OptionalHeader(AddressOfEntryPoint)),
-      pe_obj, "entry_point");
+        pe_rva_to_offset(pe, OptionalHeader(AddressOfEntryPoint)),
+      pe->object, "entry_point");
 
   set_integer(
       OptionalHeader(ImageBase),
-      pe_obj, "image_base");
+      pe->object, "image_base");
 
   set_integer(
       OptionalHeader(MajorLinkerVersion),
-      pe_obj, "linker_version.major");
+      pe->object, "linker_version.major");
 
   set_integer(
       OptionalHeader(MinorLinkerVersion),
-      pe_obj, "linker_version.minor");
+      pe->object, "linker_version.minor");
 
   set_integer(
       OptionalHeader(MajorOperatingSystemVersion),
-      pe_obj, "os_version.major");
+      pe->object, "os_version.major");
 
   set_integer(
       OptionalHeader(MinorOperatingSystemVersion),
-      pe_obj, "os_version.minor");
+      pe->object, "os_version.minor");
 
   set_integer(
       OptionalHeader(MajorImageVersion),
-      pe_obj, "image_version.major");
+      pe->object, "image_version.major");
 
   set_integer(
       OptionalHeader(MinorImageVersion),
-      pe_obj, "image_version.minor");
+      pe->object, "image_version.minor");
 
   set_integer(
       OptionalHeader(MajorSubsystemVersion),
-      pe_obj, "subsystem_version.major");
+      pe->object, "subsystem_version.major");
 
   set_integer(
       OptionalHeader(MinorSubsystemVersion),
-      pe_obj, "subsystem_version.minor");
+      pe->object, "subsystem_version.minor");
 
   set_integer(
       OptionalHeader(Subsystem),
-      pe_obj, "subsystem");
+      pe->object, "subsystem");
+
+  pe_iterate_resources(
+      pe,
+      (RESOURCE_CALLBACK_FUNC) pe_find_version_info_cb,
+      (void*) pe);
 
   section = IMAGE_FIRST_SECTION(pe);
 
-  for (i = 0; i < min(pe->FileHeader.NumberOfSections, MAX_PE_SECTIONS); i++)
+  int scount = min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS);
+
+  for (int i = 0; i < scount; i++)
   {
     if ((uint8_t*) section -
-        (uint8_t*) pe + sizeof(IMAGE_SECTION_HEADER) >= pe_size)
+        (uint8_t*) pe + sizeof(IMAGE_SECTION_HEADER) >= pe->data_size)
     {
       break;
     }
@@ -382,24 +470,24 @@ void pe_parse_header(
 
     set_string(
         section_name,
-        pe_obj, "sections[%i].name", i);
+        pe->object, "sections[%i].name", i);
 
     set_integer(
         section->Characteristics,
-        pe_obj, "sections[%i].characteristics", i);
+        pe->object, "sections[%i].characteristics", i);
 
     set_integer(section->SizeOfRawData,
-        pe_obj, "sections[%i].raw_data_size", i);
+        pe->object, "sections[%i].raw_data_size", i);
 
     set_integer(section->PointerToRawData,
-        pe_obj, "sections[%i].raw_data_offset", i);
+        pe->object, "sections[%i].raw_data_offset", i);
 
     set_integer(section->VirtualAddress,
-        pe_obj, "sections[%i].virtual_address", i);
+        pe->object, "sections[%i].virtual_address", i);
 
     set_integer(
         section->Misc.VirtualSize,
-        pe_obj, "sections[%i].virtual_size", i);
+        pe->object, "sections[%i].virtual_size", i);
 
     section++;
   }
@@ -432,7 +520,7 @@ define_function(exports)
   char* function_name = string_argument(1);
 
   YR_OBJECT* module = module();
-  DATA* data = (DATA*) module->data;
+  PE* pe = (PE*) module->data;
 
   PIMAGE_DATA_DIRECTORY directory;
   PIMAGE_EXPORT_DIRECTORY exports;
@@ -444,53 +532,42 @@ define_function(exports)
 
   // if not a PE file, return UNDEFINED
 
-  if (data == NULL)
+  if (pe == NULL)
     return_integer(UNDEFINED);
 
-  directory = pe_get_directory_entry(
-      data->pe_header,
-      IMAGE_DIRECTORY_ENTRY_EXPORT);
+  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(
-      data->pe_header,
-      data->pe_size,
-      directory->VirtualAddress);
+  offset = pe_rva_to_offset(pe, directory->VirtualAddress);
 
   if (offset == 0 ||
-      offset >= data->data_size)
+      offset >= pe->data_size)
     return_integer(0);
 
-  exports = (PIMAGE_EXPORT_DIRECTORY)(data->data + offset);
+  exports = (PIMAGE_EXPORT_DIRECTORY)(pe->data + offset);
 
-  offset = pe_rva_to_offset(
-      data->pe_header,
-      data->pe_size,
-      exports->AddressOfNames);
+  offset = pe_rva_to_offset(pe, exports->AddressOfNames);
 
   if (offset == 0 ||
-      offset + exports->NumberOfNames * sizeof(DWORD) > data->data_size)
+      offset + exports->NumberOfNames * sizeof(DWORD) > pe->data_size)
     return_integer(0);
 
-  names = (DWORD*)(data->data + offset);
+  names = (DWORD*)(pe->data + offset);
 
   for (i = 0; i < exports->NumberOfNames; i++)
   {
-    offset = pe_rva_to_offset(
-        data->pe_header,
-        data->pe_size,
-        names[i]);
+    offset = pe_rva_to_offset(pe, names[i]);
 
-    if (offset == 0 || offset >= data->data_size)
+    if (offset == 0 || offset >= pe->data_size)
       return_integer(0);
 
-    name = (char*)(data->data + offset);
+    name = (char*)(pe->data + offset);
 
-    if (strncmp(name, function_name, data->data_size - offset) == 0)
+    if (strncmp(name, function_name, pe->data_size - offset) == 0)
       return_integer(1);
   }
 
@@ -508,7 +585,7 @@ define_function(imports)
   int function_name_len = strlen(function_name);
 
   YR_OBJECT* module = module();
-  DATA* data = (DATA*) module->data;
+  PE* pe = (PE*) module->data;
 
   PIMAGE_DATA_DIRECTORY directory;
   PIMAGE_IMPORT_DESCRIPTOR imports;
@@ -516,77 +593,63 @@ define_function(imports)
   PIMAGE_THUNK_DATA32 thunks32;
   PIMAGE_THUNK_DATA64 thunks64;
 
-  uint8_t* data_end;
+  uint8_t* pe_end;
   uint64_t offset;
 
   // if not a PE file, return UNDEFINED
 
-  if (data == NULL)
+  if (pe == NULL)
     return_integer(UNDEFINED);
 
-  data_end = data->data + data->data_size;
+  pe_end = pe->data + pe->data_size;
 
-  directory = pe_get_directory_entry(
-      data->pe_header,
-      IMAGE_DIRECTORY_ENTRY_IMPORT);
+  directory = pe_get_directory_entry(pe, IMAGE_DIRECTORY_ENTRY_IMPORT);
 
   if (directory->VirtualAddress == 0)
     return_integer(0);
 
-  offset = pe_rva_to_offset(
-      data->pe_header,
-      data->pe_size,
-      directory->VirtualAddress);
+  offset = pe_rva_to_offset(pe, directory->VirtualAddress);
 
   if (offset == 0 ||
-      offset + sizeof(IMAGE_IMPORT_DESCRIPTOR) > data->data_size)
+      offset + sizeof(IMAGE_IMPORT_DESCRIPTOR) > pe->data_size)
     return_integer(0);
 
-  imports = (PIMAGE_IMPORT_DESCRIPTOR)(data->data + offset);
+  imports = (PIMAGE_IMPORT_DESCRIPTOR)(pe->data + offset);
 
-  while (check_bounds(imports, IMAGE_IMPORT_DESCRIPTOR, data_end) &&
+  while (check_bounds(imports, IMAGE_IMPORT_DESCRIPTOR, pe_end) &&
          imports->Name != 0)
   {
-    offset = pe_rva_to_offset(
-        data->pe_header,
-        data->pe_size,
-        imports->Name);
+    offset = pe_rva_to_offset(pe, imports->Name);
 
     if (offset > 0 &&
-        offset <= data->data_size &&
+        offset <= pe->data_size &&
         strncasecmp(
             dll_name,
-            (char*)(data->data + offset),
-            data->data_size - offset) == 0)
+            (char*)(pe->data + offset),
+            pe->data_size - offset) == 0)
     {
-      offset = pe_rva_to_offset(
-          data->pe_header,
-          data->pe_size,
-          imports->OriginalFirstThunk);
+      offset = pe_rva_to_offset(pe, imports->OriginalFirstThunk);
 
       if (offset > 0)
       {
-        if (data->pe_header->FileHeader.Machine == 0x8664)
+        if (pe->header->FileHeader.Machine == 0x8664)
         {
-          thunks64 = (PIMAGE_THUNK_DATA64)(data->data + offset);
+          thunks64 = (PIMAGE_THUNK_DATA64)(pe->data + offset);
 
-          while (check_bounds(thunks64, IMAGE_THUNK_DATA64, data_end) &&
+          while (check_bounds(thunks64, IMAGE_THUNK_DATA64, pe_end) &&
                  thunks64->u1.Ordinal != 0)
           {
             if (!(thunks64->u1.Ordinal & IMAGE_ORDINAL_FLAG64))
             {
               // if not exported by ordinal
-              offset = pe_rva_to_offset(
-                  data->pe_header,
-                  data->pe_size,
-                  thunks64->u1.Function);
+              offset = pe_rva_to_offset(pe, thunks64->u1.Function);
 
               if (offset != 0 &&
-                  offset <= data->data_size - sizeof(IMAGE_IMPORT_BY_NAME))
+                  offset <= pe->data_size - sizeof(IMAGE_IMPORT_BY_NAME))
               {
-                import = (PIMAGE_IMPORT_BY_NAME)(data->data + offset);
+                import = (PIMAGE_IMPORT_BY_NAME)(pe->data + offset);
 
-                if (data_end - import->Name >= function_name_len)
+                if (pe_end - import->Name >= function_name_len)
                 {
                   if (strncmp((char*) import->Name,
                               function_name,
@@ -603,25 +666,22 @@ define_function(imports)
         }
         else
         {
-          thunks32 = (PIMAGE_THUNK_DATA32)(data->data + offset);
+          thunks32 = (PIMAGE_THUNK_DATA32)(pe->data + offset);
 
-          while (check_bounds(thunks32, IMAGE_THUNK_DATA32, data_end) &&
+          while (check_bounds(thunks32, IMAGE_THUNK_DATA32, pe_end) &&
                  thunks32->u1.Ordinal != 0)
           {
             if (!(thunks32->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
             {
               // if not exported by ordinal
-              offset = pe_rva_to_offset(
-                  data->pe_header,
-                  data->pe_size,
-                  thunks32->u1.Function);
+              offset = pe_rva_to_offset(pe, thunks32->u1.Function);
 
               if (offset != 0 &&
-                  offset <= data->data_size - sizeof(IMAGE_IMPORT_BY_NAME))
+                  offset <= pe->data_size - sizeof(IMAGE_IMPORT_BY_NAME))
               {
-                import = (PIMAGE_IMPORT_BY_NAME)(data->data + offset);
+                import = (PIMAGE_IMPORT_BY_NAME)(pe->data + offset);
 
-                if (data_end - import->Name >= function_name_len)
+                if (pe_end - import->Name >= function_name_len)
                 {
                   if (strncmp((char*) import->Name,
                               function_name,
@@ -655,9 +715,13 @@ typedef struct _FIND_LANGUAGE_CB_DATA
 
 
 int pe_find_language_cb(
+    PIMAGE_RESOURCE_DATA_ENTRY rsrc_data,
     int rsrc_type,
     int rsrc_id,
     int rsrc_language,
+    PIMAGE_NT_HEADERS32 pe_header,
+    size_t pe_size,
+    size_t pe_offset,
     FIND_LANGUAGE_CB_DATA* cb_data)
 {
   if (rsrc_language == cb_data->language)
@@ -678,19 +742,16 @@ define_function(language)
   cb_data.found = FALSE;
 
   YR_OBJECT* module = module();
-  DATA* data = (DATA*) module->data;
+  PE* pe = (PE*) module->data;
 
   // if not a PE file, return UNDEFINED
 
-  if (data == NULL)
+  if (pe == NULL)
     return_integer(UNDEFINED);
 
-  if (pe_iterate_resources(
-      data->pe_header,
-      data->pe_size,
-      data->pe_offset,
-      (RESOURCE_CALLBACK_FUNC) pe_find_language_cb,
-      (void*) &cb_data))
+  if (pe_iterate_resources(pe,
+          (RESOURCE_CALLBACK_FUNC) pe_find_language_cb,
+          (void*) &cb_data))
   {
     return_integer(cb_data.found);
   }
@@ -737,6 +798,8 @@ begin_declarations;
   declare_integer("entry_point");
   declare_integer("image_base");
 
+  declare_string_dictionary("version_info");
+
   begin_struct("linker_version");
     declare_integer("major");
     declare_integer("minor");
@@ -796,12 +859,6 @@ int module_load(
     void* module_data,
     size_t module_data_size)
 {
-  PIMAGE_NT_HEADERS32 pe_header;
-  YR_MEMORY_BLOCK* block;
-  DATA* data;
-
-  size_t pe_size;
-
   set_integer(
       IMAGE_FILE_MACHINE_I386, module_object,
       "MACHINE_I386");
@@ -877,9 +934,11 @@ int module_load(
       IMAGE_FILE_BYTES_REVERSED_HI, module_object,
       "BYTES_REVERSED_HI");
 
+  YR_MEMORY_BLOCK* block;
+
   foreach_memory_block(context, block)
   {
-    pe_header = pe_get_header(block->data, block->size);
+    PIMAGE_NT_HEADERS32 pe_header = pe_get_header(block->data, block->size);
 
     if (pe_header != NULL)
     {
@@ -888,27 +947,23 @@ int module_load(
       if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
           !(pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
       {
-        pe_size = block->size - ((uint8_t*) pe_header - block->data);
+        PE* pe = (PE*) yr_malloc(sizeof(PE));
 
-        pe_parse_header(
-            pe_header,
-            block->base,
-            pe_size,
-            context->flags,
-            module_object);
+        if (pe == NULL)
+          return ERROR_INSUFICIENT_MEMORY;
 
-        data = (DATA*) yr_malloc(sizeof(DATA));
+        pe->data = block->data;
+        pe->data_size = block->size;
+        pe->header = pe_header;
+        pe->object = module_object;
 
-        if (data == NULL)
-          return ERROR_INSUFICIENT_MEMORY;
+        module_object->data = pe;
 
-        data->data = block->data;
-        data->data_size = block->size;
-        data->pe_header = pe_header;
-        data->pe_size = pe_size;
-        data->pe_offset = (uint8_t*) pe_header - block->data;
+        pe_parse(
+            pe,
+            block->base,
+            context->flags);
 
-        module_object->data = data;
         break;
       }
     }
diff --git a/libyara/strutils.c b/libyara/strutils.c
index 4d4c170..32e12b1 100644
--- a/libyara/strutils.c
+++ b/libyara/strutils.c
@@ -75,10 +75,10 @@ the following implementations were taken from OpenBSD.
 
 #if !HAVE_STRLCPY
 
-size_t strlcpy(char *dst, const char *src, size_t size)
+size_t strlcpy(char* dst, const char* src, size_t size)
 {
-  register char *d = dst;
-  register const char *s = src;
+  register char* d = dst;
+  register const char* s = src;
   register size_t n = size;
 
   /* Copy as many bytes as will fit */
@@ -111,10 +111,10 @@ size_t strlcpy(char *dst, const char *src, size_t size)
 
 #if !HAVE_STRLCAT
 
-size_t strlcat(char *dst, const char *src, size_t size)
+size_t strlcat(char* dst, const char* src, size_t size)
 {
-  register char *d = dst;
-  register const char *s = src;
+  register char* d = dst;
+  register const char* s = src;
   register size_t n = size;
   size_t dlen;
 
@@ -145,3 +145,55 @@ size_t strlcat(char *dst, const char *src, size_t size)
 }
 
 #endif
+
+
+int strlen_w(const char* w_str)
+{
+  int len = 0;
+
+  while (*w_str != 0)
+  {
+    w_str += 2;
+    len += 1;
+  }
+
+  return len;
+}
+
+
+int strcmp_w(const char* w_str, const char* str)
+{
+  while (*w_str != 0 && *str != 0 && *w_str == *str)
+  {
+    w_str += 2;
+    str += 1;
+  }
+
+  if (*w_str == *str)
+    return 0;
+
+  if (*w_str > *str)
+    return 1;
+
+  return -1;
+}
+
+size_t strlcpy_w(char* dst, const char* w_src, size_t n)
+{
+  register char* d = dst;
+  register const char* s = w_src;
+
+  while (n > 1 && *s != 0)
+  {
+    *d = *s;
+    d += 1;
+    n -= 1;
+    s += 2;
+  }
+
+  while (*s) s += 2;
+
+  *d = '\0';
+
+  return (s - w_src) / 2;
+}

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