Keep raw note descriptors in ELF note sections as raw bytes (#372)
authorMarco Bonelli <mb5.marcob@gmail.com>
Fri, 17 Sep 2021 20:37:03 +0000 (22:37 +0200)
committerGitHub <noreply@github.com>
Fri, 17 Sep 2021 20:37:03 +0000 (13:37 -0700)
* 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
elftools/elf/descriptions.py
elftools/elf/notes.py
examples/elf_notes.py

index 2296771956f4becb84d14476186066929b733927..7a823a697a168d19c12ff339775c628456474436 100644 (file)
@@ -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
index 82fdff65c43849d0279d36c0f396ab72679fc814..9b89415e83700dd5ab31fc2e08714855543ffef1 100644 (file)
@@ -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'
index 3e46b3a30a8b637477e882c1cb5572651a9b1e03..382da94e9d730d3cce5c1796e5d1030f173ed7d6 100644 (file)
@@ -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,
index 9e349182dea2f1308743a3d3f37e48f31770f8d5..1be56e06ffa200be8b7b2bb7c3c08b57c6ad554e 100644 (file)
@@ -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__':