[Forensics-changes] [yara] 12/407: Implement ELF module
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:27:58 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 c9622ab27aeb9cd4a50d2fd368ba847f67ea06df
Author: Victor Manuel Alvarez <vmalvarez at virustotal.com>
Date: Thu Aug 28 14:55:03 2014 +0200
Implement ELF module
---
libyara/Makefile.am | 1 +
libyara/include/yara/elf.h | 10 +-
libyara/modules/elf.c | 323 ++++++++++++++++++++++++++++++++++++++++++++
libyara/modules/module_list | 1 +
4 files changed, 334 insertions(+), 1 deletion(-)
diff --git a/libyara/Makefile.am b/libyara/Makefile.am
index f752a6b..eced228 100644
--- a/libyara/Makefile.am
+++ b/libyara/Makefile.am
@@ -1,6 +1,7 @@
MODULES = modules/tests.c
MODULES += modules/pe.c
+MODULES += modules/elf.c
if CUCKOO
MODULES += modules/cuckoo.c
diff --git a/libyara/include/yara/elf.h b/libyara/include/yara/elf.h
index e695295..d2abd69 100644
--- a/libyara/include/yara/elf.h
+++ b/libyara/include/yara/elf.h
@@ -87,8 +87,13 @@ typedef uint64_t elf64_xword_t;
#define ELF_SHT_REL 9 // Relocation entries, no addends
#define ELF_SHT_SHLIB 10 // Reserved
#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table
-#define ELF_SHT_NUM 12 // Number of defined types.
+#define ELF_SHT_NUM 12 // Number of defined types
+#define ELF_SHF_WRITE 0x1 // Section is writable
+#define ELF_SHF_ALLOC 0x2 // Section is present during execution
+#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions
+
+#pragma pack(push,1)
typedef struct
{
@@ -201,4 +206,7 @@ typedef struct
} elf64_section_header_t;
+
+#pragma pack(pop)
+
#endif
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
new file mode 100644
index 0000000..893d0a5
--- /dev/null
+++ b/libyara/modules/elf.c
@@ -0,0 +1,323 @@
+/*
+Copyright (c) 2014. The YARA Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <limits.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <yara/elf.h>
+#endif
+
+#include <yara/modules.h>
+#include <yara/mem.h>
+
+
+#define MODULE_NAME elf
+
+
+int get_elf_type(
+ uint8_t* buffer,
+ size_t buffer_length)
+{
+ elf_ident_t* elf_ident;
+
+ if (buffer_length < sizeof(elf_ident_t))
+ return 0;
+
+ elf_ident = (elf_ident_t*) buffer;
+
+ if (elf_ident->magic == ELF_MAGIC)
+ {
+ return elf_ident->_class;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+#define SIZE_OF_SECTION_TABLE_32 \
+ (sizeof(elf32_section_header_t) * elf_header->sh_entry_count)
+
+#define SIZE_OF_SECTION_TABLE_64 \
+ (sizeof(elf64_section_header_t) * elf_header->sh_entry_count)
+
+
+#define ELF_RVA_TO_OFFSET(bits) \
+uint64_t elf_rva_to_offset_##bits( \
+ elf##bits##_header_t* elf_header, \
+ uint64_t rva, \
+ size_t elf_size) \
+{ \
+ elf##bits##_section_header_t* section; \
+ \
+ /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */ \
+ \
+ if(ULONG_MAX - elf_header->sh_offset < SIZE_OF_SECTION_TABLE_##bits) \
+ { \
+ return UNDEFINED; \
+ } \
+ \
+ if (elf_header->sh_offset == 0 || \
+ elf_header->sh_offset > elf_size || \
+ elf_header->sh_offset + SIZE_OF_SECTION_TABLE_##bits > elf_size || \
+ elf_header->sh_entry_count == 0) \
+ { \
+ return UNDEFINED; \
+ } \
+ \
+ section = (elf##bits##_section_header_t*) \
+ ((uint8_t*) elf_header + elf_header->sh_offset); \
+ \
+ for (int i = 0; i < elf_header->sh_entry_count; i++) \
+ { \
+ if (section->type != ELF_SHT_NULL && \
+ section->type != ELF_SHT_NOBITS && \
+ rva >= section->addr && \
+ rva < section->addr + section->size) \
+ { \
+ return section->offset + (rva - section->addr); \
+ } \
+ \
+ section++; \
+ } \
+ \
+ return UNDEFINED; \
+}
+
+#define PARSE_ELF_HEADER(bits) \
+void parse_elf_header_##bits( \
+ elf##bits##_header_t* elf, \
+ size_t base_address, \
+ size_t elf_size, \
+ int flags, \
+ YR_OBJECT* elf_obj) \
+{ \
+ char* str_table; \
+ elf##bits##_section_header_t* section; \
+ \
+ set_integer(elf->type, elf_obj, "type"); \
+ set_integer(elf->machine, elf_obj, "machine"); \
+ set_integer(elf->sh_entry_count, elf_obj, "number_of_sections"); \
+ \
+ if (elf->entry != 0) \
+ { \
+ set_integer( \
+ flags & SCAN_FLAGS_PROCESS_MEMORY ? \
+ base_address + elf->entry : \
+ elf_rva_to_offset_##bits(elf, elf->entry, elf_size), \
+ elf_obj, "entry_point"); \
+ } \
+ \
+ if (elf->sh_offset < elf_size && \
+ elf->sh_offset + elf->sh_entry_count * \
+ sizeof(elf##bits##_section_header_t) < elf_size) \
+ { \
+ section = (elf##bits##_section_header_t*) \
+ ((uint8_t*) elf + elf->sh_offset); \
+ \
+ str_table = (char*) elf + section[elf->sh_str_table_index].offset; \
+ \
+ for (int i = 0; i < elf->sh_entry_count; i++) \
+ { \
+ set_integer(section->type, elf_obj, "sections[%i].type", i); \
+ set_integer(section->flags, elf_obj, "sections[%i].flags", i); \
+ set_integer(section->size, elf_obj, "sections[%i].size", i); \
+ set_integer(section->offset, elf_obj, "sections[%i].offset", i); \
+ set_string(str_table + section->name, elf_obj, "sections[%i].name", i); \
+ \
+ section++; \
+ } \
+ } \
+}
+
+
+ELF_RVA_TO_OFFSET(32);
+ELF_RVA_TO_OFFSET(64);
+
+
+PARSE_ELF_HEADER(32);
+PARSE_ELF_HEADER(64);
+
+
+begin_declarations;
+
+ declare_integer("ET_NONE");
+ declare_integer("ET_REL");
+ declare_integer("ET_EXEC");
+ declare_integer("ET_DYN");
+ declare_integer("ET_CORE");
+
+ declare_integer("EM_NONE");
+ declare_integer("EM_M32");
+ declare_integer("EM_SPARC");
+ declare_integer("EM_386");
+ declare_integer("EM_68K");
+ declare_integer("EM_88K");
+ declare_integer("EM_860");
+ declare_integer("EM_MIPS");
+ declare_integer("EM_ARM");
+ declare_integer("EM_MIPS");
+ declare_integer("EM_X86_64");
+
+ declare_integer("SHT_NULL");
+ declare_integer("SHT_PROGBITS");
+ declare_integer("SHT_SYMTAB");
+ declare_integer("SHT_STRTAB");
+ declare_integer("SHT_RELA");
+ declare_integer("SHT_HASH");
+ declare_integer("SHT_DYNAMIC");
+ declare_integer("SHT_NOTE");
+ declare_integer("SHT_NOBITS");
+ declare_integer("SHT_REL");
+ declare_integer("SHT_SHLIB");
+ declare_integer("SHT_DYNSYM");
+
+ declare_integer("SHF_WRITE");
+ declare_integer("SHF_ALLOC");
+ declare_integer("SHF_EXECINSTR");
+
+ declare_integer("type");
+ declare_integer("machine");
+ declare_integer("entry_point");
+ declare_integer("number_of_sections");
+
+ begin_struct_array("sections");
+ declare_integer("type");
+ declare_integer("flags");
+ declare_string("name");
+ declare_integer("size");
+ declare_integer("offset");
+ end_struct_array("sections");
+
+end_declarations;
+
+
+int module_initialize(
+ YR_MODULE* module)
+{
+ return ERROR_SUCCESS;
+}
+
+
+int module_finalize(
+ YR_MODULE* module)
+{
+ return ERROR_SUCCESS;
+}
+
+
+int module_load(
+ YR_SCAN_CONTEXT* context,
+ YR_OBJECT* module_object,
+ void* module_data,
+ size_t module_data_size)
+{
+ YR_MEMORY_BLOCK* block;
+
+ elf32_header_t* elf_header32;
+ elf64_header_t* elf_header64;
+
+ set_integer(ELF_ET_NONE, module_object, "ET_NONE");
+ set_integer(ELF_ET_REL, module_object, "ET_REL");
+ set_integer(ELF_ET_EXEC, module_object, "ET_EXEC");
+ set_integer(ELF_ET_DYN, module_object, "ET_DYN");
+ set_integer(ELF_ET_CORE, module_object, "ET_CORE");
+
+ set_integer(ELF_EM_NONE, module_object, "EM_NONE");
+ set_integer(ELF_EM_M32, module_object, "EM_M32");
+ set_integer(ELF_EM_SPARC, module_object, "EM_SPARC");
+ set_integer(ELF_EM_386, module_object, "EM_386");
+ set_integer(ELF_EM_68K, module_object, "EM_68K");
+ set_integer(ELF_EM_88K, module_object, "EM_88K");
+ set_integer(ELF_EM_860, module_object, "EM_860");
+ set_integer(ELF_EM_MIPS, module_object, "EM_MIPS");
+ set_integer(ELF_EM_ARM, module_object, "EM_ARM");
+ set_integer(ELF_EM_MIPS, module_object, "EM_MIPS");
+ set_integer(ELF_EM_X86_64, module_object, "EM_X86_64");
+
+ set_integer(ELF_SHT_NULL, module_object, "SHT_NULL");
+ set_integer(ELF_SHT_PROGBITS, module_object, "SHT_PROGBITS");
+ set_integer(ELF_SHT_SYMTAB, module_object, "SHT_SYMTAB");
+ set_integer(ELF_SHT_STRTAB, module_object, "SHT_STRTAB");
+ set_integer(ELF_SHT_RELA, module_object, "SHT_RELA");
+ set_integer(ELF_SHT_HASH, module_object, "SHT_HASH");
+ set_integer(ELF_SHT_DYNAMIC, module_object, "SHT_DYNAMIC");
+ set_integer(ELF_SHT_NOTE, module_object, "SHT_NOTE");
+ set_integer(ELF_SHT_NOBITS, module_object, "SHT_NOBITS");
+ set_integer(ELF_SHT_REL, module_object, "SHT_REL");
+ set_integer(ELF_SHT_SHLIB, module_object, "SHT_SHLIB");
+ set_integer(ELF_SHT_DYNSYM, module_object, "SHT_DYNSYM");
+
+ set_integer(ELF_SHF_WRITE, module_object, "SHF_WRITE");
+ set_integer(ELF_SHF_ALLOC, module_object, "SHF_ALLOC");
+ set_integer(ELF_SHF_EXECINSTR, module_object, "SHF_EXECINSTR");
+
+ foreach_memory_block(context, block)
+ {
+ switch(get_elf_type(block->data, block->size))
+ {
+ case ELF_CLASS_32:
+
+ if (block->size > sizeof(elf32_header_t))
+ {
+ elf_header32 = (elf32_header_t*) block->data;
+
+ if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+ elf_header32->type == ELF_ET_EXEC)
+ {
+ parse_elf_header_32(
+ elf_header32,
+ block->base,
+ block->size,
+ context->flags,
+ module_object);
+ }
+ }
+
+ break;
+
+ case ELF_CLASS_64:
+
+ if (block->size > sizeof(elf64_header_t))
+ {
+ elf_header64 = (elf64_header_t*) block->data;
+
+ if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+ elf_header64->type == ELF_ET_EXEC)
+ {
+ parse_elf_header_64(
+ elf_header64,
+ block->base,
+ block->size,
+ context->flags,
+ module_object);
+ }
+ }
+
+ break;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+int module_unload(YR_OBJECT* module_object)
+{
+ return ERROR_SUCCESS;
+}
diff --git a/libyara/modules/module_list b/libyara/modules/module_list
index 274c9f3..c27a21e 100644
--- a/libyara/modules/module_list
+++ b/libyara/modules/module_list
@@ -1,5 +1,6 @@
MODULE(tests)
MODULE(pe)
+MODULE(elf)
#ifdef CUCKOO
MODULE(cuckoo)
--
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