From f45851e6bd22f9d9973c83f88912377bbadabab7 Mon Sep 17 00:00:00 2001 From: ocean Date: Tue, 3 Jan 2017 20:21:40 -0800 Subject: [PATCH 1/2] modified elfcore to support more than one prstatus --- cle/backends/elfcore.py | 206 +++++++++++++++++++++------------------- 1 file changed, 107 insertions(+), 99 deletions(-) diff --git a/cle/backends/elfcore.py b/cle/backends/elfcore.py index cb33109e8..4c05370af 100644 --- a/cle/backends/elfcore.py +++ b/cle/backends/elfcore.py @@ -33,93 +33,38 @@ def __repr__(self): return "" % (self.name, self.n_type, len(self.desc)) -class ELFCore(ELF): - """ - Loader class for ELF core files. - """ - - def __init__(self, binary, **kwargs): - super(ELFCore, self).__init__(binary, **kwargs) - - self.notes = [ ] +class PRStatus(object): + def __init__(self): + self.cursig = None + self.sigpend = None + self.sighold = None + + self.pid = None + self.ppid = None + self.pgrp = None + self.sid = None + + self.utime_usec = None + self.stime_usec = None + self.cutime_usec = None + self.cstime_usec = None + self.registers = None # siginfo self.si_signo = None self.si_code = None self.si_errno = None - - # prstatus - self.pr_cursig = None - self.pr_sigpend = None - self.pr_sighold = None - - self.pr_pid = None - self.pr_ppid = None - self.pr_pgrp = None - self.pr_sid = None - - self.pr_utime_usec = None - self.pr_stime_usec = None - self.pr_cutime_usec = None - self.pr_cstime_usec = None - self.registers = None self.pr_fpvalid = None - self.__extract_note_info() - - if not self.pr_fpvalid is None and (self.arch.name == 'X86' or self.arch.name == 'AMD64'): - if not bool(self.pr_fpvalid): - l.warning("No SSE registers could be loaded from core file") - - supported_filetypes = ['elfcore'] - - def initial_register_values(self): - return self.registers.iteritems() - - def __extract_note_info(self): - """ - All meaningful information about the process's state at crashtime is stored in the note segment. - """ - for seg_readelf in self.reader.iter_segments(): - if seg_readelf.header.p_type == 'PT_NOTE': - self.__parse_notes(seg_readelf) - break - else: - l.warning("Could not find note segment, cannot initialize registers") - - def __parse_notes(self, seg): - """ - This exists, because note parsing in elftools is not good. - """ - - blob = seg.data() - - note_pos = 0 - while note_pos < len(blob): - name_sz, desc_sz, n_type = struct.unpack("<3I", blob[note_pos:note_pos+12]) - name_sz_rounded = (((name_sz + (4 - 1)) / 4) * 4) - desc_sz_rounded = (((desc_sz + (4 - 1)) / 4) * 4) - # description size + the rounded name size + header size - n_size = desc_sz_rounded + name_sz_rounded + 12 - - # name_sz includes the null byte - name = blob[note_pos+12:note_pos+12+name_sz-1] - desc = blob[note_pos+12+name_sz_rounded:note_pos+12+name_sz_rounded+desc_sz] - - self.notes.append(CoreNote(n_type, name, desc)) - note_pos += n_size - - # prstatus - prstatus = filter(lambda x: x.n_type == 'NT_PRSTATUS', self.notes) - if len(prstatus) > 1: - raise CLEError("Multiple occurences of NT_PRSTATUS notes in core file") - prstatus = prstatus[0] - - self.__parse_prstatus(prstatus) + @staticmethod + def parse_prstatus(prstatus, elf): + result = PRStatus() + result.__parse_prstatus(prstatus, elf) + return result - def __parse_prstatus(self, prstatus): + def __parse_prstatus(self, prstatus, elf): """ Parse out the prstatus, accumulating the general purpose register values. Supports AMD64, X86, ARM, and AARCH64 at the moment. @@ -135,7 +80,7 @@ def __parse_prstatus(self, prstatus): # this field is a short, but it's padded to an int self.pr_cursig = struct.unpack(" Date: Wed, 4 Jan 2017 13:16:11 -0800 Subject: [PATCH 2/2] fixed var names --- cle/backends/elfcore.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cle/backends/elfcore.py b/cle/backends/elfcore.py index 4c05370af..478034c0e 100644 --- a/cle/backends/elfcore.py +++ b/cle/backends/elfcore.py @@ -50,14 +50,14 @@ def __init__(self): self.cstime_usec = None self.registers = None + self.fpvalid = None + # siginfo self.si_signo = None self.si_code = None self.si_errno = None self.registers = None - self.pr_fpvalid = None - @staticmethod def parse_prstatus(prstatus, elf): result = PRStatus() @@ -150,10 +150,10 @@ def __parse_prstatus(self, prstatus, elf): del self.registers['xxx'] pos += nreg * arch_bytes - self.pr_fpvalid = struct.unpack("