From 89fb16ed0a2765520658dbfaceb3320617ced6b9 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 20 Jul 2022 19:39:11 +0200 Subject: [PATCH] elf_decode: decode notes & coredumps --- metasm/exe_format/elf.rb | 9 +++++--- metasm/exe_format/elf_decode.rb | 37 ++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/metasm/exe_format/elf.rb b/metasm/exe_format/elf.rb index 5d07a48a9..62ee98d2f 100644 --- a/metasm/exe_format/elf.rb +++ b/metasm/exe_format/elf.rb @@ -15,7 +15,9 @@ class ELF < ExeFormat VERSION = { 0 => 'INVALID', 1 => 'CURRENT' } ABI = { 0 => 'SYSV', 1 => 'HPUX', 2 => 'NETBSD', 3 => 'LINUX', 6 => 'SOLARIS', 7 => 'AIX', 8 => 'IRIX', 9 => 'FREEBSD', - 10 => 'TRU64', 11 => 'MODESTO', 12 => 'OPENBSD', 97 => 'ARM', + 10 => 'TRU64', 11 => 'MODESTO', 12 => 'OPENBSD', + 13 => 'OPENVMS', 14 => 'NSK', 15 => 'AROS', + 97 => 'ARM', 255 => 'STANDALONE'} TYPE = { 0 => 'NONE', 1 => 'REL', 2 => 'EXEC', 3 => 'DYN', 4 => 'CORE' } TYPE_LOPROC = 0xff00 @@ -196,7 +198,8 @@ class ELF < ExeFormat SYMBOL_TYPE_LOPROC = 13 SYMBOL_TYPE_HIPROC = 15 - SYMBOL_VISIBILITY = { 0 => 'DEFAULT', 1 => 'INTERNAL', 2 => 'HIDDEN', 3 => 'PROTECTED' } + SYMBOL_VISIBILITY = { 0 => 'DEFAULT', 1 => 'INTERNAL', 2 => 'HIDDEN', 3 => 'PROTECTED', + 4 => 'EXPORTED', 5 => 'SINGLETON', 6 => 'ELIMINATE' } RELOCATION_TYPE = { # key are in MACHINE.values '386' => { 0 => 'NONE', 1 => '32', 2 => 'PC32', 3 => 'GOT32', @@ -711,7 +714,7 @@ def self.gnu_hash_symbol_name(name) } end - attr_accessor :header, :segments, :sections, :tag, :symbols, :relocations, :endianness, :bitsize, :debug, :eh_frame + attr_accessor :header, :segments, :sections, :tag, :symbols, :relocations, :endianness, :bitsize, :debug, :eh_frame, :note def initialize(cpu=nil) @header = Header.new @tag = {} diff --git a/metasm/exe_format/elf_decode.rb b/metasm/exe_format/elf_decode.rb index b70b3140b..d6d1337b5 100644 --- a/metasm/exe_format/elf_decode.rb +++ b/metasm/exe_format/elf_decode.rb @@ -816,6 +816,35 @@ def arch_decode_segments_reloc_aarch64(reloc) Metasm::Relocation.new(Expression[target], :u64, @endianness) if target end + def decode_notes(off = nil, len = nil) + if not off + if s = @segments.find { |s_| s_.type == 'NOTE' } + # this way it also works with LoadedELF + off = addr_to_off(s.vaddr) || s.offset + len ||= s.filesz + elsif s = @sections.find { |s_| s_.type == 'NOTE' } + # if no DYNAMIC segment, assume we decode an ET_REL from file + off = s.offset + len ||= s.size + end + end + return if not @encoded.ptr = off + len ||= @encoded.length - @encoded.ptr + + @note = [] + while @encoded.ptr < off+len + namesz = decode_word + descsz = decode_word + type = decode_word + name = @encoded.read(namesz).chomp(0.chr) + @encoded.ptr += 4 - ((namesz-1) % 4) - 1 # name padded to next numeric field alignment + descr = @encoded.read(descsz) + @encoded.ptr += 4 - ((descsz-1) % 4) - 1 # ^ + + @note << [name, type, descr] + end + end + class DwarfDebug # decode a DWARF2 'compilation unit' def decode(elf, info, abbrev, str) @@ -1094,6 +1123,12 @@ def decode_segments_dynamic(decode_relocs=true) decode_segments_relocs_interpret end + # decode coredump file elements + def decode_core + decode_segments + decode_notes + end + # decodes the dynamic segment, fills segments.encoded def decode_segments decode_segments_dynamic @@ -1143,7 +1178,7 @@ def decode case @header.type when 'DYN', 'EXEC'; decode_segments when 'REL'; decode_sections - when 'CORE' + when 'CORE'; decode_core end end