[Forensics-changes] [yara] 69/192: Add support for big-endian ELF files (#560)

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:31:47 UTC 2017


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

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

commit c9c0dfb61ed5b27bdad3433d1e8d095f2f0c5684
Author: Hilko Bengen <bengen at hilluzination.de>
Date:   Tue Nov 15 00:17:56 2016 +0100

    Add support for big-endian ELF files (#560)
---
 libyara/modules/elf.c | 207 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 130 insertions(+), 77 deletions(-)

diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index e934084..5e8c6d1 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -37,8 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define MODULE_NAME elf
 
+#define CLASS_DATA(c,d) ((c << 8) | d)
 
-int get_elf_type(
+int get_elf_class_data(
     uint8_t* buffer,
     size_t buffer_length)
 {
@@ -51,7 +52,7 @@ int get_elf_type(
 
   if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
   {
-    return elf_ident->_class;
+    return CLASS_DATA(elf_ident->_class, elf_ident->data);
   }
   else
   {
@@ -59,15 +60,13 @@ int get_elf_type(
   }
 }
 
-#define SIZE_OF_SECTION_TABLE_32(h) \
-    (sizeof(elf32_section_header_t) * yr_le16toh(h->sh_entry_count))
+#define ELF_SIZE_OF_SECTION_TABLE(bits,bo,h)       \
+  (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count))
 
-#define SIZE_OF_SECTION_TABLE_64(h) \
-    (sizeof(elf64_section_header_t) * yr_le16toh(h->sh_entry_count))
 
 
-#define ELF_RVA_TO_OFFSET(bits)                                                \
-uint64_t elf_rva_to_offset_##bits(                                             \
+#define ELF_RVA_TO_OFFSET(bits,bo)                                             \
+uint64_t elf_rva_to_offset_##bits##_##bo(                                      \
     elf##bits##_header_t* elf_header,                                          \
     uint64_t rva,                                                              \
     size_t elf_size)                                                           \
@@ -78,34 +77,34 @@ uint64_t elf_rva_to_offset_##bits(                                             \
                                                                                \
   /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */  \
                                                                                \
-  if(ULONG_MAX - yr_le##bits##toh(elf_header->sh_offset) <                     \
-     SIZE_OF_SECTION_TABLE_##bits(elf_header))                                 \
+  if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                   \
+     ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header))                            \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
-  if (yr_le##bits##toh(elf_header->sh_offset) == 0 ||                          \
-      yr_le##bits##toh(elf_header->sh_offset) > elf_size ||                    \
-      yr_le##bits##toh(elf_header->sh_offset) +                                \
-      SIZE_OF_SECTION_TABLE_##bits(elf_header) > elf_size ||                   \
-      yr_le16toh(elf_header->sh_entry_count) == 0)                             \
+  if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
+      yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
+      yr_##bo##bits##toh(elf_header->sh_offset) +                              \
+        ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size ||            \
+      yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
   section = (elf##bits##_section_header_t*)                                    \
-      ((uint8_t*) elf_header + yr_le##bits##toh(elf_header->sh_offset));       \
+      ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset));     \
                                                                                \
-  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)                 \
+  for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
   {                                                                            \
-    if (yr_le32toh(section->type) != ELF_SHT_NULL &&                           \
-        yr_le32toh(section->type) != ELF_SHT_NOBITS &&                         \
-        rva >= yr_le##bits##toh(section->addr) &&                              \
-        rva < yr_le##bits##toh(section->addr) +                                \
-        yr_le##bits##toh(section->size))                                       \
+    if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
+        yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
+        rva >= yr_##bo##bits##toh(section->addr) &&                            \
+        rva < yr_##bo##bits##toh(section->addr) +                              \
+          yr_##bo##bits##toh(section->size))                                   \
     {                                                                          \
-      return yr_le##bits##toh(section->offset) +                               \
-        (rva - yr_le##bits##toh(section->addr));                               \
+      return yr_##bo##bits##toh(section->offset) +                             \
+        (rva - yr_##bo##bits##toh(section->addr));                             \
     }                                                                          \
                                                                                \
     section++;                                                                 \
@@ -114,8 +113,8 @@ uint64_t elf_rva_to_offset_##bits(                                             \
   return UNDEFINED;                                                            \
 }
 
-#define PARSE_ELF_HEADER(bits)                                                 \
-void parse_elf_header_##bits(                                                  \
+#define PARSE_ELF_HEADER(bits,bo)                                              \
+void parse_elf_header_##bits##_##bo(                                           \
   elf##bits##_header_t* elf,                                                   \
   size_t base_address,                                                         \
   size_t elf_size,                                                             \
@@ -127,56 +126,65 @@ void parse_elf_header_##bits(                                                  \
   elf##bits##_section_header_t* section;                                       \
   elf##bits##_program_header_t* segment;                                       \
                                                                                \
-  set_integer(yr_le16toh(elf->type), elf_obj, "type");                         \
-  set_integer(yr_le16toh(elf->machine), elf_obj, "machine");                   \
-  set_integer(yr_le##bits##toh(elf->sh_offset), elf_obj, "sh_offset");         \
-  set_integer(yr_le16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");       \
-  set_integer(yr_le16toh(elf->sh_entry_count), elf_obj, "number_of_sections"); \
-  set_integer(yr_le##bits##toh(elf->ph_offset), elf_obj, "ph_offset");         \
-  set_integer(yr_le16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");       \
-  set_integer(yr_le16toh(elf->ph_entry_count), elf_obj, "number_of_segments"); \
+  set_integer(yr_##bo##16toh(elf->type), elf_obj, "type");                     \
+  set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine");               \
+  set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj,                     \
+              "sh_offset");                                                    \
+  set_integer(yr_##bo##16toh(elf->sh_entry_size), elf_obj,                     \
+              "sh_entry_size");                                                \
+  set_integer(yr_##bo##16toh(elf->sh_entry_count), elf_obj,                    \
+              "number_of_sections");                                           \
+  set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj,                     \
+              "ph_offset");                                                    \
+  set_integer(yr_##bo##16toh(elf->ph_entry_size), elf_obj,                     \
+              "ph_entry_size");                                                \
+  set_integer(yr_##bo##16toh(elf->ph_entry_count), elf_obj,                    \
+              "number_of_segments");                                           \
                                                                                \
-  if (yr_le##bits##toh(elf->entry) != 0)                                       \
+  if (yr_##bo##bits##toh(elf->entry) != 0)                                     \
   {                                                                            \
     set_integer(                                                               \
         flags & SCAN_FLAGS_PROCESS_MEMORY ?                                    \
-        base_address + yr_le##bits##toh(elf->entry) :                          \
-        elf_rva_to_offset_##bits(elf, yr_le##bits##toh(elf->entry), elf_size), \
+        base_address + yr_##bo##bits##toh(elf->entry) :                        \
+        elf_rva_to_offset_##bits##_##bo(                                       \
+            elf, yr_##bo##bits##toh(elf->entry), elf_size),                    \
         elf_obj, "entry_point");                                               \
   }                                                                            \
                                                                                \
-  if (yr_le16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                   \
-      yr_le16toh(elf->sh_str_table_index) < yr_le16toh(elf->sh_entry_count) && \
-      yr_le##bits##toh(elf->sh_offset) < elf_size &&                           \
-      yr_le##bits##toh(elf->sh_offset) + yr_le16toh(elf->sh_entry_count) *     \
-         sizeof(elf##bits##_section_header_t) <= elf_size)                     \
+  if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&               \
+      yr_##bo##16toh(elf->sh_str_table_index) <                                \
+        yr_##bo##16toh(elf->sh_entry_count) &&                                 \
+      yr_##bo##bits##toh(elf->sh_offset) < elf_size &&                         \
+      yr_##bo##bits##toh(elf->sh_offset) +                                     \
+        yr_##bo##16toh(elf->sh_entry_count) *                                  \
+        sizeof(elf##bits##_section_header_t) <= elf_size)                      \
   {                                                                            \
     char* str_table = NULL;                                                    \
                                                                                \
     section = (elf##bits##_section_header_t*)                                  \
-      ((uint8_t*) elf + yr_le##bits##toh(elf->sh_offset));                     \
+      ((uint8_t*) elf + yr_##bo##bits##toh(elf->sh_offset));                   \
                                                                                \
-    if (section[yr_le16toh(elf->sh_str_table_index)].offset < elf_size)        \
+    if (section[yr_##bo##16toh(elf->sh_str_table_index)].offset < elf_size)    \
       str_table = (char*) elf +                                                \
-        yr_le##bits##toh(section[yr_le16toh(elf->sh_str_table_index)].offset); \
+        yr_##bo##bits##toh(section[yr_##bo##16toh(elf->sh_str_table_index)].offset); \
                                                                                \
-    for (i = 0; i < yr_le16toh(elf->sh_entry_count); i++)                      \
+    for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++)                  \
     {                                                                          \
-      set_integer(yr_le32toh(section->type), elf_obj,                          \
+      set_integer(yr_##bo##32toh(section->type), elf_obj,                      \
                   "sections[%i].type", i);                                     \
-      set_integer(yr_le32toh(section->flags), elf_obj,                         \
+      set_integer(yr_##bo##32toh(section->flags), elf_obj,                     \
                   "sections[%i].flags", i);                                    \
-      set_integer(yr_le##bits##toh(section->size), elf_obj,                    \
+      set_integer(yr_##bo##bits##toh(section->size), elf_obj,                  \
                   "sections[%i].size", i);                                     \
-      set_integer(yr_le##bits##toh(section->offset), elf_obj,                  \
+      set_integer(yr_##bo##bits##toh(section->offset), elf_obj,                \
                   "sections[%i].offset", i);                                   \
                                                                                \
-      if (yr_le##bits##toh(section->name) < elf_size &&                        \
+      if (yr_##bo##bits##toh(section->name) < elf_size &&                      \
           str_table > (char*) elf &&                                           \
-          str_table + yr_le##bits##toh(section->name) <                        \
-          (char*) elf + elf_size)                                              \
+          str_table + yr_##bo##bits##toh(section->name) <                      \
+            (char*) elf + elf_size)                                            \
       {                                                                        \
-        set_string(str_table + yr_le##bits##toh(section->name), elf_obj,       \
+        set_string(str_table + yr_##bo##bits##toh(section->name), elf_obj,     \
                    "sections[%i].name", i);                                    \
       }                                                                        \
                                                                                \
@@ -184,38 +192,39 @@ void parse_elf_header_##bits(                                                  \
     }                                                                          \
   }                                                                            \
                                                                                \
-  if (yr_le16toh(elf->ph_entry_count) > 0 &&                                   \
-      yr_le16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                         \
-      yr_le##bits##toh(elf->ph_offset) < elf_size &&                           \
-      yr_le##bits##toh(elf->ph_offset) + yr_le16toh(elf->ph_entry_count) *     \
+  if (yr_##bo##16toh(elf->ph_entry_count) > 0 &&                               \
+      yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                     \
+      yr_##bo##bits##toh(elf->ph_offset) < elf_size &&                         \
+      yr_##bo##bits##toh(elf->ph_offset) +                                     \
+        yr_##bo##16toh(elf->ph_entry_count) *                                  \
         sizeof(elf##bits##_program_header_t) <= elf_size)                      \
   {                                                                            \
     segment = (elf##bits##_program_header_t*)                                  \
-      ((uint8_t*) elf + yr_le##bits##toh(elf->ph_offset));                     \
+      ((uint8_t*) elf + yr_##bo##bits##toh(elf->ph_offset));                   \
                                                                                \
-    for (i = 0; i < yr_le16toh(elf->ph_entry_count); i++)                      \
+    for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++)                  \
     {                                                                          \
       set_integer(                                                             \
-          yr_le32toh(segment->type), elf_obj, "segments[%i].type", i);         \
+          yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i);     \
       set_integer(                                                             \
-          yr_le32toh(segment->flags), elf_obj, "segments[%i].flags", i);       \
+          yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i);   \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->offset), elf_obj,                          \
+          yr_##bo##bits##toh(segment->offset), elf_obj,                        \
           "segments[%i].offset", i);                                           \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->virt_addr), elf_obj,                       \
+          yr_##bo##bits##toh(segment->virt_addr), elf_obj,                     \
           "segments[%i].virtual_address", i);                                  \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->phys_addr), elf_obj,                       \
+          yr_##bo##bits##toh(segment->phys_addr), elf_obj,                     \
           "segments[%i].physical_address", i);                                 \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->file_size), elf_obj,                       \
+          yr_##bo##bits##toh(segment->file_size), elf_obj,                     \
           "segments[%i].file_size", i);                                        \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->mem_size), elf_obj,                        \
+          yr_##bo##bits##toh(segment->mem_size), elf_obj,                      \
           "segments[%i].memory_size", i);                                      \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->alignment), elf_obj,                       \
+          yr_##bo##bits##toh(segment->alignment), elf_obj,                     \
           "segments[%i].alignment", i);                                        \
                                                                                \
       segment++;                                                               \
@@ -224,12 +233,16 @@ void parse_elf_header_##bits(                                                  \
 }
 
 
-ELF_RVA_TO_OFFSET(32);
-ELF_RVA_TO_OFFSET(64);
+ELF_RVA_TO_OFFSET(32,le);
+ELF_RVA_TO_OFFSET(64,le);
+ELF_RVA_TO_OFFSET(32,be);
+ELF_RVA_TO_OFFSET(64,be);
 
 
-PARSE_ELF_HEADER(32);
-PARSE_ELF_HEADER(64);
+PARSE_ELF_HEADER(32,le);
+PARSE_ELF_HEADER(64,le);
+PARSE_ELF_HEADER(32,be);
+PARSE_ELF_HEADER(64,be);
 
 
 begin_declarations;
@@ -407,9 +420,9 @@ int module_load(
     if (block_data == NULL)
       continue;
 
-    switch(get_elf_type(block_data, block->size))
+    switch(get_elf_class_data(block_data, block->size))
     {
-      case ELF_CLASS_32:
+      case CLASS_DATA(ELF_CLASS_32,ELF_DATA_2LSB):
 
         if (block->size > sizeof(elf32_header_t))
         {
@@ -418,7 +431,7 @@ int module_load(
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
               yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
           {
-            parse_elf_header_32(
+            parse_elf_header_32_le(
                 elf_header32,
                 block->base,
                 block->size,
@@ -429,7 +442,27 @@ int module_load(
 
         break;
 
-      case ELF_CLASS_64:
+      case CLASS_DATA(ELF_CLASS_32,ELF_DATA_2MSB):
+
+        if (block->size > sizeof(elf32_header_t))
+        {
+          elf_header32 = (elf32_header_t*) block_data;
+
+          if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+              yr_be16toh(elf_header32->type) == ELF_ET_EXEC)
+          {
+            parse_elf_header_32_be(
+                elf_header32,
+                block->base,
+                block->size,
+                context->flags,
+                module_object);
+          }
+        }
+
+        break;
+
+      case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2LSB):
 
         if (block->size > sizeof(elf64_header_t))
         {
@@ -438,7 +471,27 @@ int module_load(
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
               yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
           {
-            parse_elf_header_64(
+            parse_elf_header_64_le(
+                elf_header64,
+                block->base,
+                block->size,
+                context->flags,
+                module_object);
+          }
+        }
+
+        break;
+
+      case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2MSB):
+
+        if (block->size > sizeof(elf64_header_t))
+        {
+          elf_header64 = (elf64_header_t*) block_data;
+
+          if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+              yr_be16toh(elf_header64->type) == ELF_ET_EXEC)
+          {
+            parse_elf_header_64_be(
                 elf_header64,
                 block->base,
                 block->size,

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