├── makeelf ├── __init__.py ├── type │ ├── __init__.py │ ├── align.py │ ├── uint16.py │ ├── uint32.py │ ├── uint64.py │ ├── uint8.py │ ├── uint24.py │ └── enum.py ├── utils.py ├── test_elf.py ├── test_elfsect.py ├── elfsect.py ├── test_elfstruct.py ├── elf.py └── elfstruct.py ├── MANIFEST.in ├── .travis.yml ├── setup.py ├── .github └── workflows │ ├── doxygen.yml │ └── pythonapp.yml ├── README.txt ├── README.md └── LICENSE /makeelf/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /makeelf/type/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | -------------------------------------------------------------------------------- /makeelf/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file utils.py 3 | # \brief Utility functions 4 | def bytes_xor(lhs, rhs): 5 | res = [] 6 | for a, b in zip(lhs, rhs): 7 | res.append(a ^ b) 8 | return bytes(res) 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | - "pypy3.5" 5 | install: 6 | - pip install . 7 | # command to run tests 8 | script: 9 | # - python3 makeelf/elfstruct.py 10 | # - python3 makeelf/elfsect.py 11 | - python3 -m unittest makeelf.test_elf 12 | - python3 -m unittest makeelf.test_elfsect 13 | - python3 -m unittest makeelf.test_elfstruct 14 | -------------------------------------------------------------------------------- /makeelf/type/align.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file align.py 3 | # \brief alignment function 4 | from math import ceil 5 | 6 | def align(b, alignment=4): 7 | """Returns bytes object aligned to specified number of bytes""" 8 | full = ceil(len(b) / alignment) 9 | diff = (full * alignment) - len(b) 10 | return b + bytes(diff) 11 | 12 | def unalign(b, alignment=4): 13 | """Returns bytes after end of alignment to specified number of bytes""" 14 | return b[alignment:] 15 | -------------------------------------------------------------------------------- /makeelf/type/uint16.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file uint16.py 3 | # \brief Unsigned 16-bit Integer 4 | import struct 5 | 6 | class uint16: 7 | 8 | def __init__(self, integer, little=False): 9 | self.little = little 10 | if little: 11 | self._endian = '<' 12 | else: 13 | self._endian = '>' 14 | self.integer = integer 15 | 16 | def __bytes__(self): 17 | return struct.pack("%sH" % self._endian, int(self.integer)) 18 | 19 | def __str__(self): 20 | return "%d" % self.integer 21 | 22 | def __len__(self): 23 | return len(bytes(self)) 24 | 25 | def from_bytes(b, little=False): 26 | if little: 27 | _endian = '<' 28 | else: 29 | _endian = '>' 30 | integer, = struct.unpack("%sH" % _endian,b[:2]) 31 | return uint16(integer), b[2:] 32 | -------------------------------------------------------------------------------- /makeelf/type/uint32.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file uint32.py 3 | # \brief Unsigned 32-bit Integer 4 | import struct 5 | 6 | class uint32: 7 | 8 | def __init__(self, integer, little=False): 9 | self.little = little 10 | if little: 11 | self._endian = '<' 12 | else: 13 | self._endian = '>' 14 | self.integer = integer 15 | 16 | def __bytes__(self): 17 | return struct.pack("%sI" % self._endian, int(self.integer)) 18 | 19 | def __str__(self): 20 | return "%d" % self.integer 21 | 22 | def __len__(self): 23 | return len(bytes(self)) 24 | 25 | def from_bytes(b, little=False): 26 | if little: 27 | _endian = '<' 28 | else: 29 | _endian = '>' 30 | integer, = struct.unpack("%sI" % _endian, b[:4]) 31 | return uint32(integer), b[4:] 32 | -------------------------------------------------------------------------------- /makeelf/type/uint64.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file uint64.py 3 | # \brief Unsigned 64-bit Integer 4 | import struct 5 | 6 | class uint64: 7 | 8 | def __init__(self, integer, little=False): 9 | self.little = little 10 | if little: 11 | self._endian = '<' 12 | else: 13 | self._endian = '>' 14 | self.integer = integer 15 | 16 | def __bytes__(self): 17 | return struct.pack("%sQ" % self._endian, int(self.integer)) 18 | 19 | def __str__(self): 20 | return "%d" % self.integer 21 | 22 | def __len__(self): 23 | return len(bytes(self)) 24 | 25 | def from_bytes(b, little=False): 26 | if little: 27 | _endian = '<' 28 | else: 29 | _endian = '>' 30 | integer, = struct.unpack("%sQ" % _endian, b[:8]) 31 | return uint64(integer), b[8:] 32 | -------------------------------------------------------------------------------- /makeelf/type/uint8.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file uint8.py 3 | # \brief Unsigned 8-bit Integer 4 | import struct 5 | 6 | class uint8: 7 | 8 | def __init__(self, integer, little=False): 9 | self.little = little 10 | if little: 11 | self._endian = '<' 12 | else: 13 | self._endian = '>' 14 | self.integer = integer 15 | 16 | def __bytes__(self): 17 | return struct.pack("%sB" % self._endian, int(self.integer))[-1:] 18 | 19 | def __str__(self): 20 | return "%d" % self.integer 21 | 22 | def __len__(self): 23 | return len(bytes(self)) 24 | 25 | def from_bytes(b, little=False): 26 | if little: 27 | _endian = '<' 28 | else: 29 | _endian = '>' 30 | integer, = struct.unpack("%sB" % _endian,b[:1]) 31 | return uint8(integer), b[1:] 32 | -------------------------------------------------------------------------------- /makeelf/type/uint24.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ## \file uint24.py 3 | # \brief Unsigned 24-bit Integer 4 | import struct 5 | 6 | class uint24: 7 | 8 | def __init__(self, integer, little=False): 9 | self.little = little 10 | if little: 11 | self._endian = '<' 12 | else: 13 | self._endian = '>' 14 | self.integer = integer 15 | 16 | def __bytes__(self): 17 | return struct.pack("%sI" % self._endian, int(self.integer))[-3:] 18 | 19 | def __str__(self): 20 | return "%d" % self.integer 21 | 22 | def __len__(self): 23 | return len(bytes(self)) 24 | 25 | def from_bytes(b, little=False): 26 | if little: 27 | _endian = '<' 28 | else: 29 | _endian = '>' 30 | integer, = struct.unpack("%sI" % _endian,b'\0'+b[:3]) 31 | return uint24(integer), b[3:] 32 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from distutils.core import setup 3 | 4 | setup( 5 | name = 'makeelf', 6 | packages = ['makeelf', 'makeelf.type'], 7 | version = '0.3.5', 8 | description = 'ELF reader-writer library', 9 | url = 'https://github.com/v3l0c1r4pt0r/makeelf', 10 | author = 'v3l0c1r4pt0r', 11 | author_email = 'v3l0c1r4pt0r@gmail.com', 12 | classifiers = [ 13 | 'Programming Language :: Python', 14 | 'Programming Language :: Python :: 3', 15 | 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 16 | 'Development Status :: 3 - Alpha', 17 | 'Intended Audience :: Developers', 18 | 'Topic :: Software Development :: Libraries :: Python Modules', 19 | ], 20 | long_description = '''MakeELF is a Python library to parse, modify and create ELF binaries. It provides following features: 21 | 22 | - easy to use, standard Python interface 23 | - reading existing ELF files to Python representation 24 | - modification of every aspect of ELF format structures 25 | - ability to skip any validation to test other parsers for potential errors 26 | - creating new valid ELF files with just one step 27 | - easy serialization of every structure present in ELF file 28 | ''', 29 | ) 30 | -------------------------------------------------------------------------------- /.github/workflows/doxygen.yml: -------------------------------------------------------------------------------- 1 | name: Build Doxygen 2 | 3 | on: 4 | # for now, make it manual ?? 5 | push: 6 | branches: 7 | - master 8 | - devel 9 | tags: 10 | - '*' 11 | 12 | jobs: 13 | doxygen: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 18 | - uses: actions/checkout@v2 19 | 20 | - name: Doxygen Action 21 | uses: mattnotmitt/doxygen-action@v1.1.0 22 | with: 23 | # Path to Doxyfile 24 | doxyfile-path: ./Doxyfile 25 | # Working directory 26 | working-directory: . 27 | 28 | - name: Archive Doxygen pages 29 | uses: actions/upload-artifact@v1 30 | with: 31 | name: makeelf-doxygen 32 | path: doc/html 33 | 34 | - name: Upload to webserver 35 | env: 36 | DOXYGEN_USER: ${{ secrets.DOXYGEN_USER }} 37 | DOXYGEN_PASS: ${{ secrets.DOXYGEN_PASS }} 38 | run: | 39 | set -e 40 | cd doc/html 41 | ftp -i -n static.re-ws.pl <