diff --git a/components/espcoredump/corefile/elf.py b/components/espcoredump/corefile/elf.py index 8ffa12b6cd..82527cf72e 100644 --- a/components/espcoredump/corefile/elf.py +++ b/components/espcoredump/corefile/elf.py @@ -126,6 +126,8 @@ class ElfFile(object): self.load_segments = [] # type: list[ElfSegment] self.note_segments = [] # type: list[ElfNoteSegment] + self.sha256 = b'' # type: bytes + if elf_path and os.path.isfile(elf_path): self.read_elf(elf_path) @@ -156,6 +158,12 @@ class ElfFile(object): sec.data, sec.sh.sh_flags) for sec in self._model.sections] + # calculate sha256 of the input bytes (note: this may not be the same as the sha256 of any generated + # output struct, as the ELF parser may change some details.) + sha256 = hashlib.sha256() + sha256.update(elf_bytes) + self.sha256 = sha256.digest() + @staticmethod def _parse_string_table(byte_str, offset): # type: (bytes, int) -> str section_name_str = byte_str[offset:] @@ -215,15 +223,6 @@ class ElfFile(object): return Struct(*args) - @property - def sha256(self): # type: () -> bytes - """ - :return: SHA256 hash of the input ELF file - """ - sha256 = hashlib.sha256() - sha256.update(self._struct.build(self._model)) # type: ignore - return sha256.digest() - class ElfSection(object): SHF_WRITE = 0x01 @@ -284,6 +283,13 @@ class ElfNoteSegment(ElfSegment): super(ElfNoteSegment, self).__init__(addr, data, flags) self.type = ElfFile.PT_NOTE self.note_secs = NoteSections.parse(self.data) + for note in self.note_secs: + # note.name should include a terminating NUL byte, plus possible + # padding + # + # (note: construct.PaddingString can't parse this if there + # are non-zero padding bytes after the NUL, it also parses those.) + note.name = note.name.split(b'\x00')[0] @staticmethod def _type_str(): # type: () -> str diff --git a/components/espcoredump/corefile/loader.py b/components/espcoredump/corefile/loader.py index 144a350826..dbf292d517 100644 --- a/components/espcoredump/corefile/loader.py +++ b/components/espcoredump/corefile/loader.py @@ -88,7 +88,7 @@ class EspCoreDumpVersion(object): COREDUMP_SUPPORTED_TARGETS = XTENSA_CHIPS + RISCV_CHIPS - def __init__(self, version=None): # type: (int) -> None + def __init__(self, version=None): # type: (Optional[int]) -> None """Constructor for core dump version """ super(EspCoreDumpVersion, self).__init__() @@ -248,7 +248,7 @@ class EspCoreDumpLoader(EspCoreDumpVersion): else: raise NotImplementedError - def _extract_elf_corefile(self, exe_name=None, e_machine=ESPCoreDumpElfFile.EM_XTENSA): # type: (str, int) -> None + def _extract_elf_corefile(self, exe_name=None, e_machine=ESPCoreDumpElfFile.EM_XTENSA): # type: (Optional[str], int) -> None """ Reads the ELF formatted core dump image and parse it """ @@ -261,7 +261,7 @@ class EspCoreDumpLoader(EspCoreDumpVersion): for seg in core_elf.note_segments: for note_sec in seg.note_secs: # Check for version info note - if note_sec.name == 'ESP_CORE_DUMP_INFO' \ + if note_sec.name == b'ESP_CORE_DUMP_INFO' \ and note_sec.type == ESPCoreDumpElfFile.PT_INFO \ and exe_name: exe_elf = ElfFile(exe_name) @@ -271,10 +271,20 @@ class EspCoreDumpLoader(EspCoreDumpVersion): 'sha256' / Bytes(64) # SHA256 as hex string ) coredump_sha256 = coredump_sha256_struct.parse(note_sec.desc[:coredump_sha256_struct.sizeof()]) - if coredump_sha256.sha256 != app_sha256: + + logging.debug('App SHA256: {!r}'.format(app_sha256)) + logging.debug('Core dump SHA256: {!r}'.format(coredump_sha256)) + + # Actual coredump SHA may be shorter than a full SHA256 hash + # with NUL byte padding, according to the app's APP_RETRIEVE_LEN_ELF_SHA + # length + core_sha_trimmed = coredump_sha256.sha256.rstrip(b'\x00').decode() + app_sha_trimmed = app_sha256[:len(core_sha_trimmed)].decode() + + if core_sha_trimmed != app_sha_trimmed: raise ESPCoreDumpLoaderError( - 'Invalid application image for coredump: coredump SHA256({!r}) != app SHA256({!r}).' - .format(coredump_sha256, app_sha256)) + 'Invalid application image for coredump: coredump SHA256({}) != app SHA256({}).' + .format(core_sha_trimmed, app_sha_trimmed)) if coredump_sha256.ver != self.version: raise ESPCoreDumpLoaderError( 'Invalid application image for coredump: coredump SHA256 version({}) != app SHA256 version({}).'