Repository: Gallopsled/pwntools

Issue:
Pwntools cannot work with pyelftools-0.30
I just installed pwntools in my new VM. But I encountered some problems.
```python
/usr/local/lib/python3.10/dist-packages/pwnlib/elf/corefile.py in <module>
     77 
     78 import elftools
---> 79 from elftools.common.py3compat import bytes2str
     80 from elftools.common.utils import roundup
     81 from elftools.common.utils import struct_parse
```
Afterwards, I found that pyelftools just released 0.30 version and it refactors out py3compat.
Therefore, this line won't work anymore.
https://github.com/Gallopsled/pwntools/blob/dev/pwnlib/elf/corefile.py#L79
```python
from elftools.common.py3compat import bytes2str
```


Discussion:
btw, `bytes2str` is moved to `elftools.common.utils`

https://github.com/eliben/pyelftools/blob/v0.30/elftools/common/utils.py#L22
pyelftools 0.3 removed support for python 2, so we can't update as long as we support python 2 ourselves.

But removing usage of that wrapper is fine either way.

Resolving patch:
diff --git a/pwnlib/elf/corefile.py b/pwnlib/elf/corefile.py
--- a/pwnlib/elf/corefile.py
+++ b/pwnlib/elf/corefile.py
@@ -76,7 +76,6 @@
 from io import BytesIO, StringIO
 
 import elftools
-from elftools.common.py3compat import bytes2str
 from elftools.common.utils import roundup
 from elftools.common.utils import struct_parse
 from elftools.construct import CString
@@ -94,6 +93,7 @@
 from pwnlib.util.fiddling import unhex
 from pwnlib.util.misc import read
 from pwnlib.util.misc import write
+from pwnlib.util.packing import _decode
 from pwnlib.util.packing import pack
 from pwnlib.util.packing import unpack_many
 
@@ -134,12 +134,13 @@ def iter_notes(self):
         self.stream.seek(offset)
         # n_namesz is 4-byte aligned.
         disk_namesz = roundup(note['n_namesz'], 2)
-        note['n_name'] = bytes2str(
-            CString('').parse(self.stream.read(disk_namesz)))
-        offset += disk_namesz
+        with context.local(encoding='latin-1'):
+            note['n_name'] = _decode(
+                CString('').parse(self.stream.read(disk_namesz)))
+            offset += disk_namesz
 
-        desc_data = bytes2str(self.stream.read(note['n_descsz']))
-        note['n_desc'] = desc_data
+            desc_data = _decode(self.stream.read(note['n_descsz']))
+            note['n_desc'] = desc_data
         offset += roundup(note['n_descsz'], 2)
         note['n_size'] = offset - note['n_offset']
         yield note
diff --git a/pwnlib/util/packing.py b/pwnlib/util/packing.py
--- a/pwnlib/util/packing.py
+++ b/pwnlib/util/packing.py
@@ -1065,6 +1065,9 @@ def _encode(s):
     return s.encode(context.encoding)
 
 def _decode(b):
+    if isinstance(b, (str, six.text_type)):
+        return b   # already text
+
     if context.encoding == 'auto':
         try:
             return b.decode('utf-8')
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -47,7 +47,8 @@
 
 install_requires     = ['paramiko>=1.15.2',
                         'mako>=1.0.0',
-                        'pyelftools>=0.2.4',
+                        'pyelftools>=0.24, <0.30; python_version < "3"',
+                        'pyelftools>=0.24; python_version >= "3"',
                         'capstone>=3.0.5rc2', # See Gallopsled/pwntools#971, Gallopsled/pwntools#1160
                         'ropgadget>=5.3',
                         'pyserial>=2.7',


Test patch: