From cc47f5fb6dbe16aee110faa6270d9ef2fa7a290f Mon Sep 17 00:00:00 2001 From: Marco Bonelli Date: Fri, 17 Sep 2021 22:37:03 +0200 Subject: [PATCH] Keep raw note descriptors in ELF note sections as raw bytes (#372) * ELF notes: keep raw note descriptors as bytes * py3compat: add bytes2hex function * elf/descriptions: use bytes2hex where needed * ELF notes: convert to string only for known types --- elftools/common/py3compat.py | 2 ++ elftools/elf/descriptions.py | 8 +++----- elftools/elf/notes.py | 8 +++++--- examples/elf_notes.py | 5 +++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/elftools/common/py3compat.py b/elftools/common/py3compat.py index 2296771..7a823a6 100644 --- a/elftools/common/py3compat.py +++ b/elftools/common/py3compat.py @@ -21,6 +21,7 @@ if PY3: # and strings are different types and bytes hold numeric values when # iterated over. + def bytes2hex(b): return b.hex() def bytes2str(b): return b.decode('latin-1') def str2bytes(s): return s.encode('latin-1') def int2byte(i): return bytes((i,)) @@ -41,6 +42,7 @@ else: import cStringIO StringIO = BytesIO = cStringIO.StringIO + def bytes2hex(b): return b.encode('hex') def bytes2str(b): return b def str2bytes(s): return s int2byte = chr diff --git a/elftools/elf/descriptions.py b/elftools/elf/descriptions.py index 82fdff6..9b89415 100644 --- a/elftools/elf/descriptions.py +++ b/elftools/elf/descriptions.py @@ -13,7 +13,7 @@ from .enums import ( ENUM_RELOC_TYPE_MIPS, ENUM_ATTR_TAG_ARM, ENUM_DT_FLAGS, ENUM_DT_FLAGS_1) from .constants import ( P_FLAGS, RH_FLAGS, SH_FLAGS, SUNW_SYMINFO_FLAGS, VER_FLAGS) -from ..common.py3compat import iteritems +from ..common.py3compat import bytes2hex, iteritems def describe_ei_class(x): @@ -193,7 +193,7 @@ def describe_note(x): desc = '' if x['n_type'] == 'NT_GNU_ABI_TAG': if x['n_name'] == 'Android': - desc = '\n description data: %s ' % ' '.join("%02x" % ord(b) for b in x['n_descdata']) + desc = '\n description data: %s ' % bytes2hex(x['n_descdata']) else: desc = '\n OS: %s, ABI: %d.%d.%d' % ( _DESCR_NOTE_ABI_TAG_OS.get(n_desc['abi_os'], _unknown), @@ -203,9 +203,7 @@ def describe_note(x): elif x['n_type'] == 'NT_GNU_GOLD_VERSION': desc = '\n Version: %s' % (n_desc) else: - desc = '\n description data: {}'.format(' '.join( - '{:02x}'.format(ord(byte)) for byte in n_desc - )) + desc = '\n description data: {}'.format(bytes2hex(n_desc)) if x['n_type'] == 'NT_GNU_ABI_TAG' and x['n_name'] == 'Android': note_type = 'NT_VERSION' diff --git a/elftools/elf/notes.py b/elftools/elf/notes.py index 3e46b3a..382da94 100644 --- a/elftools/elf/notes.py +++ b/elftools/elf/notes.py @@ -6,7 +6,7 @@ # Eli Bendersky (eliben@gmail.com) # This code is in the public domain #------------------------------------------------------------------------------- -from ..common.py3compat import bytes2str +from ..common.py3compat import bytes2hex, bytes2str from ..common.utils import struct_parse, roundup from ..construct import CString @@ -29,14 +29,16 @@ def iter_notes(elffile, offset, size): CString('').parse(elffile.stream.read(disk_namesz))) offset += disk_namesz - desc_data = bytes2str(elffile.stream.read(note['n_descsz'])) + desc_data = elffile.stream.read(note['n_descsz']) note['n_descdata'] = desc_data if note['n_type'] == 'NT_GNU_ABI_TAG': note['n_desc'] = struct_parse(elffile.structs.Elf_abi, elffile.stream, offset) elif note['n_type'] == 'NT_GNU_BUILD_ID': - note['n_desc'] = ''.join('%.2x' % ord(b) for b in desc_data) + note['n_desc'] = bytes2hex(desc_data) + elif note['n_type'] == 'NT_GNU_GOLD_VERSION': + note['n_desc'] = bytes2str(desc_data) elif note['n_type'] == 'NT_PRPSINFO': note['n_desc'] = struct_parse(elffile.structs.Elf_Prpsinfo, elffile.stream, diff --git a/examples/elf_notes.py b/examples/elf_notes.py index 9e34918..1be56e0 100644 --- a/examples/elf_notes.py +++ b/examples/elf_notes.py @@ -16,6 +16,7 @@ sys.path[0:0] = ['.', '..'] from elftools.elf.elffile import ELFFile from elftools.elf.sections import NoteSection +from elftools.common.py3compat import bytes2hex def process_file(filename): @@ -36,10 +37,10 @@ def process_file(filename): desc['abi_major'], desc['abi_minor'], desc['abi_tiny'])) - elif note['n_type'] == 'NT_GNU_BUILD_ID': + elif note['n_type'] in {'NT_GNU_BUILD_ID', 'NT_GNU_GOLD_VERSION'}: print(' Desc:', desc) else: - print(' Desc:', ''.join('%.2x' % ord(b) for b in desc)) + print(' Desc:', bytes2hex(desc)) if __name__ == '__main__': -- 2.30.2