├── tests ├── __init__.py └── test_build_elf.py ├── simpleelf ├── __init__.py ├── elf_builder.py ├── elf_consts.py └── elf_structs.py ├── requirements.txt ├── .gitignore ├── .github └── workflows │ ├── python-publish.yml │ └── python-package.yml ├── pyproject.toml └── README.md /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /simpleelf/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | construct>=2.10.54 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ide related 2 | .idea/ 3 | 4 | # cache 5 | *.pyc 6 | __pycache__ 7 | 8 | # poetry related 9 | Lib/ 10 | Scripts/ 11 | pyvenv.cfg 12 | 13 | # build related 14 | *.whl 15 | dist 16 | build 17 | *.egg-info 18 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflows will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Set up Python 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: '3.x' 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install setuptools wheel twine build 25 | - name: Build and publish 26 | env: 27 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 28 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 29 | run: | 30 | python3 -m build 31 | twine upload dist/* 32 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ '**' ] 9 | pull_request: 10 | branches: [ '**' ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | python-version: [3.8, 3.9, "3.10", 3.11] 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | - name: Set up Python ${{ matrix.python-version }} 23 | uses: actions/setup-python@v4 24 | with: 25 | python-version: ${{ matrix.python-version }} 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install flake8 pytest 30 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 31 | - name: Lint with flake8 32 | run: | 33 | flake8 . --max-line-length=127 34 | - name: Test with pytest 35 | run: | 36 | pytest 37 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "simpleelf" 3 | version = "1.0.0" 4 | description = "Simple ELF parser and builder" 5 | readme = "README.md" 6 | requires-python = ">=3.8" 7 | license = { file = "LICENSE" } 8 | keywords = ["elf", "reverse-engineering", "research"] 9 | authors = [ 10 | { name = "doronz88", email = "doron88@gmail.com" } 11 | ] 12 | maintainers = [ 13 | { name = "doronz88", email = "doron88@gmail.com" } 14 | ] 15 | classifiers = [ 16 | "Development Status :: 5 - Production/Stable", 17 | "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", 18 | "Programming Language :: Python :: 3", 19 | "Programming Language :: Python :: 3.8", 20 | "Programming Language :: Python :: 3.9", 21 | "Programming Language :: Python :: 3.10", 22 | "Programming Language :: Python :: 3.11", 23 | "Programming Language :: Python :: 3 :: Only", 24 | ] 25 | dynamic = ["dependencies"] 26 | 27 | [project.optional-dependencies] 28 | test = ["pytest"] 29 | 30 | [project.urls] 31 | "Homepage" = "https://github.com/doronz88/simpleelf" 32 | "Bug Reports" = "https://github.com/doronz88/simpleelf/issues" 33 | 34 | [tool.setuptools.packages.find] 35 | exclude = ["docs*", "tests*"] 36 | 37 | [tool.setuptools.dynamic] 38 | dependencies = { file = ["requirements.txt"] } 39 | 40 | [build-system] 41 | requires = ["setuptools>=43.0.0", "wheel"] 42 | build-backend = "setuptools.build_meta" 43 | -------------------------------------------------------------------------------- /tests/test_build_elf.py: -------------------------------------------------------------------------------- 1 | from simpleelf import elf_consts 2 | from simpleelf.elf_builder import ElfBuilder, ElfStructs 3 | from simpleelf.elf_consts import ELFCLASS64 4 | 5 | structs = ElfStructs('<') 6 | 7 | 8 | def test_build_elf32(): 9 | e = ElfBuilder() 10 | e.set_endianity('<') 11 | e.set_machine(elf_consts.EM_ARM) 12 | 13 | code = b'CODECODE' 14 | 15 | # add a segment 16 | text_address = 0x1234 17 | text_buffer = b'cybercyberbitimbitim' + code 18 | e.add_segment(text_address, text_buffer, 19 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 20 | 21 | # add a second segment 22 | e.add_segment(0x88771122, b'data in 0x88771122', 23 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 24 | 25 | # add a code section inside the first segment 26 | code_address = text_address + text_buffer.find(code) # point at CODECODE 27 | code_size = len(code) 28 | e.add_code_section(code_address, code_size, name='.text') 29 | 30 | # set entry point 31 | e.set_entry(code_address) 32 | 33 | # add .bss section. not requiring a loaded segment from 34 | # file 35 | bss_address = 0x5678 36 | bss_size = 0x200 37 | e.add_empty_data_section(bss_address, bss_size, name='.bss') 38 | 39 | elf_raw = e.build() 40 | parsed_raw_elf = structs.Elf32.parse(elf_raw) 41 | 42 | assert structs.Elf32.build( 43 | parsed_raw_elf) == elf_raw, "rebuilt elf is not the same" 44 | 45 | 46 | def test_build_elf64(): 47 | e = ElfBuilder(ELFCLASS64) 48 | e.set_endianity('<') 49 | e.set_machine(elf_consts.EM_ARM) 50 | 51 | code = b'CODECODE' 52 | 53 | # add a segment 54 | text_address = 0x1234 55 | text_buffer = b'cybercyberbitimbitim' + code 56 | e.add_segment(text_address, text_buffer, 57 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 58 | 59 | # add a second segment 60 | e.add_segment(0x88771122, b'data in 0x88771122', 61 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 62 | 63 | # add a code section inside the first segment 64 | code_address = text_address + text_buffer.find(code) # point at CODECODE 65 | code_size = len(code) 66 | e.add_code_section(code_address, code_size, name='.text') 67 | 68 | # set entry point 69 | e.set_entry(code_address) 70 | 71 | # add .bss section. not requiring a loaded segment from 72 | # file 73 | bss_address = 0x5678 74 | bss_size = 0x200 75 | e.add_empty_data_section(bss_address, bss_size, name='.bss') 76 | 77 | elf_raw = e.build() 78 | open('/tmp/foo', 'wb').write(elf_raw) 79 | parsed_raw_elf = structs.Elf64.parse(elf_raw) 80 | 81 | assert structs.Elf64.build(parsed_raw_elf) == elf_raw, "rebuilt elf is not the same" 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Python package](https://github.com/doronz88/simpleelf/workflows/Python%20package/badge.svg) 2 | 3 | # Introduction 4 | ELF file is not only an executable, but a very convenient way to describe 5 | a program's layout in memory. The original intention of this project is to 6 | allow an individual to create an ELF file which describes the memory mapping 7 | used for an embedded program. Especially useful for using together with other 8 | analysis tools, such as: 9 | IDA/Ghidra/etc... They can have all its desired information without the need to 10 | open just an ordinary `.bin` file and running several IDAPython scripts 11 | (I'm sick of `Load additional binary file...` option). 12 | 13 | Pull Requests are of course more than welcome :smirk:. 14 | 15 | # Installation 16 | 17 | Use `pip`: 18 | 19 | ```bash 20 | python3 -m pip install simpleelf 21 | ``` 22 | 23 | Or clone yourself and build: 24 | 25 | ```bash 26 | git clone git@github.com:doronz88/simpleelf.git 27 | cd simpleelf 28 | python -m pip install -e . -U 29 | ``` 30 | 31 | # Running 32 | 33 | Now you can just import simpleelf and start playing with it. 34 | 35 | ## Parsing 36 | 37 | Parsing is easy using `ElfStruct`. 38 | Try it out: 39 | 40 | ```python 41 | from simpleelf.elf_structs import ElfStructs 42 | 43 | ElfStructs('<').Elf32.parse(elf32_buffer) # outputs a constucts' container 44 | ElfStructs('<').Elf64.parse(elf64_buffer) # outputs a constucts' container 45 | ``` 46 | 47 | ## Building from scratch 48 | 49 | Building is easy using `ElfBuilder`. 50 | Try it out: 51 | 52 | ```python 53 | from simpleelf.elf_builder import ElfBuilder 54 | from simpleelf import elf_consts 55 | 56 | # can also be used with ELFCLASS64 to create 64bit layouts 57 | e = ElfBuilder(elf_consts.ELFCLASS32) 58 | e.set_endianity('<') 59 | e.set_machine(elf_consts.EM_ARM) 60 | 61 | code = b'CODECODE' 62 | 63 | # add a segment 64 | text_address = 0x1234 65 | text_buffer = b'cybercyberbitimbitim' + code 66 | e.add_segment(text_address, text_buffer, 67 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 68 | 69 | # add a second segment 70 | e.add_segment(0x88771122, b'data in 0x88771122', 71 | elf_consts.PF_R | elf_consts.PF_W | elf_consts.PF_X) 72 | 73 | # add a code section inside the first segment 74 | code_address = text_address + text_buffer.find(code) # point at CODECODE 75 | code_size = len(code) 76 | e.add_code_section(code_address, code_size, name='.text') 77 | 78 | # set entry point 79 | e.set_entry(code_address) 80 | 81 | # add .bss section. not requiring a loaded segment from 82 | # file 83 | bss_address = 0x5678 84 | bss_size = 0x200 85 | e.add_empty_data_section(bss_address, bss_size, name='.bss') 86 | 87 | # get raw elf 88 | e.build() 89 | ``` 90 | -------------------------------------------------------------------------------- /simpleelf/elf_builder.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | from typing import Optional, Tuple, Union 3 | 4 | from construct import Padding 5 | 6 | from simpleelf import elf_consts 7 | from simpleelf.elf_consts import ELFCLASS32 8 | from simpleelf.elf_structs import ElfStructs 9 | 10 | Segment = namedtuple('Segment', ['address', 'flags', 'contents']) 11 | Section = namedtuple('Section', ['type', 'name', 'address', 'flags', 'size']) 12 | 13 | 14 | class ElfBuilder: 15 | 16 | def __init__(self, elf_class: int = ELFCLASS32): 17 | self._class = elf_class 18 | self._segments = [] 19 | self._sections = [] 20 | self._e_type = elf_consts.ET_EXEC 21 | self._machine = 0 22 | self._entry = 0 23 | self._endianity = '<' 24 | self._structs = ElfStructs(self._endianity) 25 | if elf_class == ELFCLASS32: 26 | self._e_ehsize = self._structs.Elf32_Ehdr.sizeof() 27 | self._e_phoff = self._e_ehsize 28 | self._e_phentsize = 0x20 # TODO: calculate according to the struct 29 | self._e_shentsize = 0x28 # TODO: calculate according to the struct 30 | else: 31 | self._e_ehsize = self._structs.Elf64_Ehdr.sizeof() 32 | self._e_phoff = self._e_ehsize 33 | self._e_phentsize = 0x38 # TODO: calculate according to the struct 34 | self._e_shentsize = 0x40 # TODO: calculate according to the struct 35 | self._e_phnum = 0 36 | self._e_shnum = 0 37 | self._e_shoff = self._e_phoff + self._e_phentsize * self._e_phnum 38 | self._strtab_text = b'\x00.strtab\x00' 39 | 40 | self._add_section(self._structs.Elf_SectionType.SHT_NULL, 0, 0, 0, 0) 41 | 42 | def set_endianity(self, endianity: str) -> None: 43 | """ 44 | Set endianity 45 | 46 | :param endianity: Either '<' for LE or '>' for BE 47 | :return: None 48 | """ 49 | self._endianity = endianity 50 | self._structs = ElfStructs(endianity) 51 | 52 | def add_segment(self, address: int, contents: bytes, flags: int) -> None: 53 | self._e_phnum += 1 54 | self._e_shoff += self._e_phentsize + len(contents) 55 | self._segments.append(Segment(address=address, flags=flags, contents=contents)) 56 | 57 | def find_loaded_data(self, address: int, size: Optional[int] = None) -> Optional[Tuple[int, bytes]]: 58 | """ 59 | Searches the entire ELF memory layout for the data loaded at a given address 60 | 61 | :param address: Address to search for 62 | :param size: Size of data to read from that address 63 | :return: None of address isn't mapped or a tuple of the offset within the ELF file and the actual data 64 | """ 65 | offset = self._e_phoff 66 | data = None 67 | 68 | for segment in self._segments: 69 | # skip program header 70 | offset += self._e_phentsize 71 | 72 | if (segment.address <= address) and (segment.address + len(segment.contents) >= address): 73 | offset += address - segment.address 74 | data = segment.contents[address - segment.address:] 75 | else: 76 | if data is None: 77 | # skip current segment contents 78 | offset += len(segment.contents) 79 | 80 | if data is None: 81 | return None 82 | 83 | if size is not None: 84 | data = data[:size] 85 | 86 | return offset, data 87 | 88 | def add_code_section(self, address: int, size: int, writeable: bool = False, 89 | name: Optional[Union[str, int]] = None) -> None: 90 | """ 91 | Add code section 92 | 93 | :param address: Section address 94 | :param size: Section size 95 | :param writeable: Determine if section is writable 96 | :param name: Section's name (either None, string name, or an offset from .strtab) 97 | :return: None 98 | """ 99 | flags = elf_consts.SHF_ALLOC | elf_consts.SHF_EXECINSTR 100 | if writeable: 101 | flags |= elf_consts.SHF_WRITE 102 | self._add_section(self._structs.Elf_SectionType.SHT_PROGBITS, address, size, flags, name=name) 103 | 104 | def add_empty_data_section(self, address: int, size: int, name: Optional[Union[str, int]] = None) -> None: 105 | """ 106 | Add an empty data section (usually for .bss) 107 | 108 | :param address: Section's address 109 | :param size: Section's size 110 | :param name: Section's name (either None, string name, or an offset from .strtab) 111 | :return: 112 | """ 113 | self._add_section(self._structs.Elf_SectionType.SHT_NOBITS, address, size, 114 | elf_consts.SHF_ALLOC | elf_consts.SHF_WRITE, name=name) 115 | 116 | def set_machine(self, machine: int) -> None: 117 | """ Set machine type """ 118 | self._machine = machine 119 | 120 | def set_entry(self, entry: int) -> None: 121 | """ Set entrypoint address """ 122 | self._entry = entry 123 | 124 | def set_type(self, e_type: int) -> None: 125 | self._e_type = e_type 126 | 127 | def build(self) -> bytes: 128 | structs = self._structs 129 | 130 | # append strtab as the last section 131 | self._add_string_section() 132 | 133 | if self._endianity == '<': 134 | e_ident_data = elf_consts.ELFDATA2LSB 135 | else: 136 | e_ident_data = elf_consts.ELFDATA2MSB 137 | 138 | elf = { 139 | 'header': { 140 | 'e_ident': { 141 | 'magic': elf_consts.ELFMAG, 142 | 'class': self._class, 143 | 'data': e_ident_data, 144 | 'osabi': elf_consts.ELFOSABI_NONE, 145 | 'pad': Padding(8), 146 | }, 147 | 'e_type': self._e_type, 148 | 'e_machine': self._machine, 149 | 'e_version': elf_consts.EV_CURRENT, 150 | 'e_entry': self._entry, 151 | 'e_phoff': self._e_phoff, 152 | 'e_shoff': self._e_shoff + len(self._strtab_text), 153 | 'e_flags': 0, 154 | 'e_ehsize': self._e_ehsize, 155 | 'e_phentsize': self._e_phentsize, 156 | 'e_phnum': self._e_phnum, 157 | 'e_shentsize': self._e_shentsize, 158 | 'e_shnum': self._e_shnum, 159 | 'e_shstrndx': self._e_shnum - 1, 160 | }, 161 | 'segments': [], 162 | 'sections': [], 163 | } 164 | 165 | # add segments 166 | segment_data_offset = self._e_phoff + self._e_phnum * self._e_phentsize 167 | 168 | for segment in self._segments: 169 | elf['segments'].append({ 170 | 'p_type': self._structs.Elf_SegmentType.PT_LOAD, 171 | 'p_offset': segment_data_offset, 172 | 'p_vaddr': segment.address, 173 | 'p_paddr': segment.address, 174 | 'p_filesz': len(segment.contents), 175 | 'p_memsz': len(segment.contents), 176 | 'p_flags': segment.flags, 177 | 'p_align': 0x20, 178 | 'data': segment.contents 179 | }) 180 | segment_data_offset += len(segment.contents) 181 | 182 | end_of_segments_offset = segment_data_offset 183 | 184 | # add sections 185 | for section in self._sections: 186 | if section.name is None: 187 | sh_name = elf_consts.SHN_UNDEF 188 | else: 189 | if type(section.name) is int: 190 | sh_name = section.name 191 | else: 192 | sh_name = self._strtab_text.find(section.name.encode() + b'\x00') 193 | 194 | if section.type == self._structs.Elf_SectionType.SHT_PROGBITS: 195 | size = section.size 196 | offset, contents = self.find_loaded_data(section.address, size) 197 | else: 198 | # every non-loaded data into memory, which resides only in ELF 199 | # will be pointed by `end_of_segments_offset`. 200 | # we can append data there 201 | offset = end_of_segments_offset 202 | 203 | if section.type == self._structs.Elf_SectionType.SHT_STRTAB: 204 | # the string table is object-globalized 205 | contents = self._strtab_text 206 | size = len(contents) 207 | else: 208 | # .bss section for example, where place in memory is just 209 | # allocated with no specific data 210 | contents = b'' 211 | size = section.size 212 | 213 | if section.type != self._structs.Elf_SectionType.SHT_NOBITS: 214 | end_of_segments_offset += size 215 | 216 | elf['sections'].append({ 217 | 'sh_name': sh_name, 218 | 'sh_type': section.type, 219 | 'sh_flags': section.flags, 220 | 'sh_addr': section.address, 221 | 'sh_offset': offset, 222 | 'sh_size': size, 223 | 'sh_link': 0, 224 | 'sh_info': 0, 225 | 'sh_addralign': 0x20, 226 | 'sh_entsize': 0, 227 | 'data': contents 228 | }) 229 | 230 | return structs.Elf32.build(elf) if self._class == ELFCLASS32 else structs.Elf64.build(elf) 231 | 232 | def _add_section(self, type_, address: int, size: int, flags: int, name: Optional[Union[str, int]] = None) -> None: 233 | """ 234 | Add section 235 | 236 | :param type_: A value from Elf_SectionType enum 237 | :param address: Section's address 238 | :param size: Section's size 239 | :param flags: Section's flags 240 | :param name: Section's name (either None, string name, or an offset from .strtab) 241 | :return: None 242 | """ 243 | if name is not None: 244 | if isinstance(name, str): 245 | self._strtab_text += name.encode() + b'\x00' 246 | 247 | # create segment for the section if necessary 248 | if type_ in (self._structs.Elf_SectionType.SHT_PROGBITS,): 249 | if self.find_loaded_data(address) is None: 250 | raise Exception( 251 | "section of type SHT_PROGBITS not inside any segment") 252 | 253 | section = Section( 254 | name=name, 255 | type=type_, 256 | address=address, 257 | size=size, 258 | flags=flags) 259 | 260 | self._e_shnum += 1 261 | self._sections.append(section) 262 | 263 | def _add_string_section(self) -> None: 264 | """ Add string section (.strtab) """ 265 | self._add_section(self._structs.Elf_SectionType.SHT_STRTAB, 0, len(self._strtab_text), 1, elf_consts.SHF_ALLOC) 266 | -------------------------------------------------------------------------------- /simpleelf/elf_consts.py: -------------------------------------------------------------------------------- 1 | EI_NIDENT = 16 2 | ELFMAG = b"\177ELF" 3 | 4 | PF_R = 0x4 5 | PF_W = 0x2 6 | PF_X = 0x1 7 | 8 | SHF_WRITE = 0x1 9 | SHF_ALLOC = 0x2 10 | SHF_EXECINSTR = 0x4 11 | SHF_RELA_LIVEPATCH = 0x00100000 12 | SHF_RO_AFTER_INIT = 0x00200000 13 | SHF_MASKPROC = 0xf0000000 14 | 15 | ELFCLASSNONE = 0 16 | ELFCLASS32 = 1 17 | ELFCLASS64 = 2 18 | ELFCLASSNUM = 3 19 | 20 | ELFDATANONE = 0 21 | ELFDATA2LSB = 1 22 | ELFDATA2MSB = 2 23 | 24 | PT_NULL = 0 25 | PT_LOAD = 1 26 | PT_DYNAMIC = 2 27 | PT_INTER = 3 28 | PT_NOTE = 4 29 | PT_SHLIB = 5 30 | PT_PHDR = 6 31 | PT_TLS = 7 # Thread local storage segment 32 | PT_LOOS = 0x60000000 # OS-specific 33 | PT_HIOS = 0x6fffffff # OS-specific 34 | PT_LOPROC = 0x70000000 35 | PT_HIPROC = 0x7fffffff 36 | PT_GNU_EH_FRAME = 0x6474e550 37 | 38 | ET_NONE = 0 39 | ET_REL = 1 40 | ET_EXEC = 2 41 | ET_DYN = 3 42 | ET_CORE = 4 43 | ET_LOPROC = 0xff00 44 | ET_HIPROC = 0xffff 45 | 46 | EV_NONE = 0 47 | EV_CURRENT = 1 48 | EV_NUM = 2 49 | 50 | ELFOSABI_NONE = 0 51 | ELFOSABI_LINUX = 3 52 | 53 | SHN_UNDEF = 0 54 | SHN_LORESERVE = 0xff00 55 | SHN_LOPROC = 0xff00 56 | SHN_HIPROC = 0xff1f 57 | SHN_LIVEPATCH = 0xff20 58 | SHN_ABS = 0xfff1 59 | SHN_COMMON = 0xfff2 60 | SHN_HIRESERVE = 0xffff 61 | 62 | SHT_NULL = 0 63 | SHT_PROGBITS = 1 64 | SHT_SYMTAB = 2 65 | SHT_STRTAB = 3 66 | SHT_RELA = 4 67 | SHT_HASH = 5 68 | SHT_DYNAMIC = 6 69 | SHT_NOTE = 7 70 | SHT_NOBITS = 8 71 | SHT_REL = 9 72 | SHT_SHLIB = 10 73 | SHT_DYNSYM = 11 74 | SHT_NUM = 12 75 | SHT_LOPROC = 0x70000000 76 | SHT_HIPROC = 0x7fffffff 77 | SHT_LOUSER = 0x80000000 78 | SHT_HIUSER = 0xffffffff 79 | 80 | EM_NONE = 0 # No machine 81 | EM_M32 = 1 # AT&T WE 32100 82 | EM_SPARC = 2 # SPARC 83 | EM_386 = 3 # Intel 80386 84 | EM_68K = 4 # Motorola 68000 85 | EM_88K = 5 # Motorola 88000 86 | EM_IAMCU = 6 # Intel MCU 87 | EM_860 = 7 # Intel 80860 88 | EM_MIPS = 8 # MIPS I Architecture 89 | EM_S370 = 9 # IBM System/370 Processor 90 | EM_MIPS_RS3_LE = 10 # MIPS RS3000 Little-endian 91 | EM_PARISC = 15 # Hewlett-Packard PA-RISC 92 | EM_VPP500 = 17 # Fujitsu VPP500 93 | EM_SPARC32PLUS = 18 # Enhanced instruction set SPARC 94 | EM_960 = 19 # Intel 80960 95 | EM_PPC = 20 # PowerPC 96 | EM_PPC64 = 21 # 64-bit PowerPC 97 | EM_S390 = 22 # IBM System/390 Processor 98 | EM_SPU = 23 # IBM SPU/SPC 99 | EM_V800 = 36 # NEC V800 100 | EM_FR20 = 37 # Fujitsu FR20 101 | EM_RH32 = 38 # TRW RH-32 102 | EM_RCE = 39 # Motorola RCE 103 | EM_ARM = 40 # ARM 32-bit architecture (AARCH32) 104 | EM_ALPHA = 41 # Digital Alpha 105 | EM_SH = 42 # Hitachi SH 106 | EM_SPARCV9 = 43 # SPARC Version 9 107 | EM_TRICORE = 44 # Siemens TriCore embedded processor 108 | EM_ARC = 45 # Argonaut RISC Core Argonaut Technologies Inc. 109 | EM_H8_300 = 46 # Hitachi H8/300 110 | EM_H8_300H = 47 # Hitachi H8/300H 111 | EM_H8S = 48 # Hitachi H8S 112 | EM_H8_500 = 49 # Hitachi H8/500 113 | EM_IA_64 = 50 # Intel IA-64 processor architecture 114 | EM_MIPS_X = 51 # Stanford MIPS-X 115 | EM_COLDFIRE = 52 # Motorola ColdFire 116 | EM_68HC12 = 53 # Motorola M68HC12 117 | EM_MMA = 54 # Fujitsu MMA Multimedia Accelerator 118 | EM_PCP = 55 # Siemens PCP 119 | EM_NCPU = 56 # Sony nCPU embedded RISC processor 120 | EM_NDR1 = 57 # Denso NDR1 microprocessor 121 | EM_STARCORE = 58 # Motorola Star*Core processor 122 | EM_ME16 = 59 # Toyota ME16 processor 123 | EM_ST100 = 60 # STMicroelectronics ST100 processor 124 | EM_TINYJ = 61 # Advanced Logic Corp. TinyJ embedded processor family 125 | EM_X86_64 = 62 # AMD x86-64 architecture 126 | EM_PDSP = 63 # Sony DSP Processor 127 | EM_PDP10 = 64 # Digital Equipment Corp. PDP-10 128 | EM_PDP11 = 65 # Digital Equipment Corp. PDP-11 129 | EM_FX66 = 66 # Siemens FX66 microcontroller 130 | EM_ST9PLUS = 67 # STMicroelectronics ST9+ 8/16 bit microcontroller 131 | EM_ST7 = 68 # STMicroelectronics ST7 8-bit microcontroller 132 | EM_68HC16 = 69 # Motorola MC68HC16 Microcontroller 133 | EM_68HC11 = 70 # Motorola MC68HC11 Microcontroller 134 | EM_68HC08 = 71 # Motorola MC68HC08 Microcontroller 135 | EM_68HC05 = 72 # Motorola MC68HC05 Microcontroller 136 | EM_SVX = 73 # Silicon Graphics SVx 137 | EM_ST19 = 74 # STMicroelectronics ST19 8-bit microcontroller 138 | EM_VAX = 75 # Digital VAX 139 | EM_CRIS = 76 # Axis Communications 32-bit embedded processor 140 | EM_JAVELIN = 77 # Infineon Technologies 32-bit embedded processor 141 | EM_FIREPATH = 78 # Element 14 64-bit DSP Processor 142 | EM_ZSP = 79 # LSI Logic 16-bit DSP Processor 143 | EM_MMIX = 80 # Donald Knuth's educational 64-bit processor 144 | EM_HUANY = 81 # Harvard University machine-independent object files 145 | EM_PRISM = 82 # SiTera Prism 146 | EM_AVR = 83 # Atmel AVR 8-bit microcontroller 147 | EM_FR30 = 84 # Fujitsu FR30 148 | EM_D10V = 85 # Mitsubishi D10V 149 | EM_D30V = 86 # Mitsubishi D30V 150 | EM_V850 = 87 # NEC v850 151 | EM_M32R = 88 # Mitsubishi M32R 152 | EM_MN10300 = 89 # Matsushita MN10300 153 | EM_MN10200 = 90 # Matsushita MN10200 154 | EM_PJ = 91 # picoJava 155 | EM_OPENRISC = 92 # OpenRISC 32-bit embedded processor 156 | EM_ARC_COMPACT = 93 # ARC International ARCompact processor (old 157 | # spelling/synonym: ) # 158 | EM_XTENSA = 94 # Tensilica Xtensa Architecture 159 | EM_VIDEOCORE = 95 # Alphamosaic VideoCore processor 160 | EM_TMM_GPP = 96 # Thompson Multimedia General Purpose Processor 161 | EM_NS32K = 97 # National Semiconductor 32000 series 162 | EM_TPC = 98 # Tenor Network TPC processor 163 | EM_SNP1K = 99 # Trebia SNP 1000 processor 164 | EM_ST200 = 100 # STMicroelectronics (www.st.com) ST200 microcontroller 165 | EM_IP2K = 101 # Ubicom IP2xxx microcontroller family 166 | EM_MAX = 102 # MAX Processor 167 | EM_CR = 103 # National Semiconductor CompactRISC microprocessor 168 | EM_F2MC16 = 104 # Fujitsu F2MC16 169 | EM_MSP430 = 105 # Texas Instruments embedded microcontroller msp430 170 | EM_BLACKFIN = 106 # Analog Devices Blackfin (DSP) processor 171 | EM_SE_C33 = 107 # S1C33 Family of Seiko Epson processors 172 | EM_SEP = 108 # Sharp embedded microprocessor 173 | EM_ARCA = 109 # Arca RISC Microprocessor 174 | EM_UNICORE = 110 # Microprocessor series from PKU-Unity Ltd. and MPRC of 175 | # Peking University 176 | EM_EXCESS = 111 # eXcess: 16/32/64-bit configurable embedded CPU 177 | EM_DXP = 112 # Icera Semiconductor Inc. Deep Execution Processor 178 | EM_ALTERA_NIOS2 = 113 # Altera Nios II soft-core processor 179 | EM_CRX = 114 # National Semiconductor CompactRISC CRX microprocessor 180 | EM_XGATE = 115 # Motorola XGATE embedded processor 181 | EM_C166 = 116 # Infineon C16x/XC16x processor 182 | EM_M16C = 117 # Renesas M16C series microprocessors 183 | EM_DSPIC30F = 118 # Microchip Technology dsPIC30F Digital Signal Controller 184 | EM_CE = 119 # Freescale Communication Engine RISC core 185 | EM_M32C = 120 # Renesas M32C series microprocessors 186 | EM_TSK3000 = 131 # Altium TSK3000 core 187 | EM_RS08 = 132 # Freescale RS08 embedded processor 188 | EM_SHARC = 133 # Analog Devices SHARC family of 32-bit DSP processors 189 | EM_ECOG2 = 134 # Cyan Technology eCOG2 microprocessor 190 | EM_SCORE7 = 135 # Sunplus S+core7 RISC processor 191 | EM_DSP24 = 136 # New Japan Radio (NJR) 24-bit DSP Processor 192 | EM_VIDEOCORE3 = 137 # Broadcom VideoCore III processor 193 | EM_LATTICEMICO32 = 138 # RISC processor for Lattice FPGA architecture 194 | EM_SE_C17 = 139 # Seiko Epson C17 family 195 | EM_TI_C6000 = 140 # The Texas Instruments TMS320C6000 DSP family 196 | EM_TI_C2000 = 141 # The Texas Instruments TMS320C2000 DSP family 197 | EM_TI_C5500 = 142 # The Texas Instruments TMS320C55x DSP family 198 | EM_TI_ARP32 = 143 # Texas Instruments Application Specific RISC Processor 199 | # 32bit fetch 200 | EM_TI_PRU = 144 # Texas Instruments Programmable Realtime Unit 201 | EM_MMDSP_PLUS = 160 # STMicroelectronics 64bit VLIW Data Signal Processor 202 | EM_CYPRESS_M8C = 161 # Cypress M8C microprocessor 203 | EM_R32C = 162 # Renesas R32C series microprocessors 204 | EM_TRIMEDIA = 163 # NXP Semiconductors TriMedia architecture family 205 | EM_QDSP6 = 164 # QUALCOMM DSP6 Processor 206 | EM_8051 = 165 # Intel 8051 and variants 207 | EM_STXP7X = 166 # STMicroelectronics STxP7x family of configurable and 208 | # extensible RISC processors 209 | EM_NDS32 = 167 # Andes Technology compact code size embedded RISC processor 210 | # family 211 | EM_ECOG1 = 168 # Cyan Technology eCOG1X family 212 | EM_ECOG1X = 168 # Cyan Technology eCOG1X family 213 | EM_MAXQ30 = 169 # Dallas Semiconductor MAXQ30 Core Micro-controllers 214 | EM_XIMO16 = 170 # New Japan Radio (NJR) 16-bit DSP Processor 215 | EM_MANIK = 171 # M2000 Reconfigurable RISC Microprocessor 216 | EM_CRAYNV2 = 172 # Cray Inc. NV2 vector architecture 217 | EM_RX = 173 # Renesas RX family 218 | EM_METAG = 174 # Imagination Technologies META processor architecture 219 | EM_MCST_ELBRUS = 175 # MCST Elbrus general purpose hardware architecture 220 | EM_ECOG16 = 176 # Cyan Technology eCOG16 family 221 | EM_CR16 = 177 # National Semiconductor CompactRISC CR16 16-bit microprocessor 222 | EM_ETPU = 178 # Freescale Extended Time Processing Unit 223 | EM_SLE9X = 179 # Infineon Technologies SLE9X core 224 | EM_L10M = 180 # Intel L10M 225 | EM_K10M = 181 # Intel K10M 226 | EM_AVR32 = 185 # Atmel Corporation 32-bit microprocessor family 227 | EM_STM8 = 186 # STMicroeletronics STM8 8-bit microcontroller 228 | EM_TILE64 = 187 # Tilera TILE64 multicore architecture family 229 | EM_TILEPRO = 188 # Tilera TILEPro multicore architecture family 230 | EM_MICROBLAZE = 189 # Xilinx MicroBlaze 32-bit RISC soft processor core 231 | EM_CUDA = 190 # NVIDIA CUDA architecture 232 | EM_TILEGX = 191 # Tilera TILE-Gx multicore architecture family 233 | EM_CLOUDSHIELD = 192 # CloudShield architecture family 234 | EM_COREA_1ST = 193 # KIPO-KAIST Core-A 1st generation processor family 235 | EM_COREA_2ND = 194 # KIPO-KAIST Core-A 2nd generation processor family 236 | EM_ARC_COMPACT2 = 195 # Synopsys ARCompact V2 237 | EM_OPEN8 = 196 # Open8 8-bit RISC soft processor core 238 | EM_RL78 = 197 # Renesas RL78 family 239 | EM_VIDEOCORE5 = 198 # Broadcom VideoCore V processor 240 | EM_78KOR = 199 # Renesas 78KOR family 241 | EM_56800EX = 200 # Freescale 56800EX Digital Signal Controller (DSC) 242 | EM_BA1 = 201 # Beyond BA1 CPU architecture 243 | EM_BA2 = 202 # Beyond BA2 CPU architecture 244 | EM_XCORE = 203 # XMOS xCORE processor family 245 | EM_MCHP_PIC = 204 # Microchip 8-bit PIC(r) family 246 | EM_INTEL205 = 205 # Reserved by Intel 247 | EM_INTEL206 = 206 # Reserved by Intel 248 | EM_INTEL207 = 207 # Reserved by Intel 249 | EM_INTEL208 = 208 # Reserved by Intel 250 | EM_INTEL209 = 209 # Reserved by Intel 251 | EM_KM32 = 210 # KM211 KM32 32-bit processor 252 | EM_KMX32 = 211 # KM211 KMX32 32-bit processor 253 | EM_KMX16 = 212 # KM211 KMX16 16-bit processor 254 | EM_KMX8 = 213 # KM211 KMX8 8-bit processor 255 | EM_KVARC = 214 # KM211 KVARC processor 256 | EM_CDP = 215 # Paneve CDP architecture family 257 | EM_COGE = 216 # Cognitive Smart Memory Processor 258 | EM_COOL = 217 # Bluechip Systems CoolEngine 259 | EM_NORC = 218 # Nanoradio Optimized RISC 260 | EM_CSR_KALIMBA = 219 # CSR Kalimba architecture family 261 | EM_Z80 = 220 # Zilog Z80 262 | EM_VISIUM = 221 # Controls and Data Services VISIUMcore processor 263 | EM_FT32 = 222 # FTDI Chip FT32 high performance 32-bit RISC architecture 264 | EM_MOXIE = 223 # Moxie processor family 265 | EM_AMDGPU = 224 # AMD GPU architecture 266 | EM_RISCV = 243 # RISC-V 267 | EM_BPF = 247 # Linux BPF - in-kernel virtual machine 268 | -------------------------------------------------------------------------------- /simpleelf/elf_structs.py: -------------------------------------------------------------------------------- 1 | from construct import Array, Bytes, Const, Default, Enum, Hex, If, Int8ub, Int8ul, Int16ub, Int16ul, Int32ub, Int32ul, \ 2 | Int64ub, Int64ul, Padding, Pointer, Struct, this 3 | 4 | from simpleelf import elf_consts 5 | 6 | 7 | class ElfStructs: 8 | def __init__(self, endianity='<'): 9 | if endianity == '<': 10 | Int8u = Int8ul 11 | Int16u = Int16ul 12 | # Int32s = Int32sl 13 | Int32u = Int32ul 14 | # Int64s = Int64sl 15 | Int64u = Int64ul 16 | else: 17 | Int8u = Int8ub 18 | Int16u = Int16ub 19 | # Int32s = Int32sb 20 | Int32u = Int32ub 21 | # Int64s = Int64sb 22 | Int64u = Int64ub 23 | 24 | Elf32_Addr = Int32u 25 | # Elf32_Half = Int16u 26 | Elf32_Off = Int32u 27 | # Elf32_Sword = Int32s 28 | Elf32_Word = Int32u 29 | 30 | Elf64_Addr = Int64u 31 | # Elf64_Half = Int16u 32 | # Elf64_SHalf = Int16u 33 | Elf64_Off = Int64u 34 | # Elf64_Sword = Int32s 35 | Elf64_Word = Int32u 36 | Elf64_Xword = Int64u 37 | # Elf64_Sxword = Int64s 38 | 39 | self.Elf_Class = Enum(Hex(Int8u), 40 | ELFCLASSNONE=elf_consts.ELFCLASSNONE, 41 | ELFCLASS32=elf_consts.ELFCLASS32, 42 | ELFCLASS64=elf_consts.ELFCLASS64, 43 | ELFCLASSNUM=elf_consts.ELFCLASSNUM, 44 | ) 45 | 46 | self.Elf_Data = Enum(Hex(Int8u), 47 | ELFDATANONE=elf_consts.ELFDATANONE, 48 | ELFDATA2LSB=elf_consts.ELFDATA2LSB, 49 | ELFDATA2MSB=elf_consts.ELFDATA2MSB, 50 | ) 51 | 52 | self.Elf_Machine = Enum(Int16u, 53 | EM_NONE=elf_consts.EM_NONE, 54 | EM_M32=elf_consts.EM_M32, 55 | EM_SPARC=elf_consts.EM_SPARC, 56 | EM_386=elf_consts.EM_386, 57 | EM_68K=elf_consts.EM_68K, 58 | EM_88K=elf_consts.EM_88K, 59 | EM_IAMCU=elf_consts.EM_IAMCU, 60 | EM_860=elf_consts.EM_860, 61 | EM_MIPS=elf_consts.EM_MIPS, 62 | EM_S370=elf_consts.EM_S370, 63 | EM_MIPS_RS3_LE=elf_consts.EM_MIPS_RS3_LE, 64 | EM_PARISC=elf_consts.EM_PARISC, 65 | EM_VPP500=elf_consts.EM_VPP500, 66 | EM_SPARC32PLUS=elf_consts.EM_SPARC32PLUS, 67 | EM_960=elf_consts.EM_960, 68 | EM_PPC=elf_consts.EM_PPC, 69 | EM_PPC64=elf_consts.EM_PPC64, 70 | EM_S390=elf_consts.EM_S390, 71 | EM_SPU=elf_consts.EM_SPU, 72 | EM_V800=elf_consts.EM_V800, 73 | EM_FR20=elf_consts.EM_FR20, 74 | EM_RH32=elf_consts.EM_RH32, 75 | EM_RCE=elf_consts.EM_RCE, 76 | EM_ARM=elf_consts.EM_ARM, 77 | EM_ALPHA=elf_consts.EM_ALPHA, 78 | EM_SH=elf_consts.EM_SH, 79 | EM_SPARCV9=elf_consts.EM_SPARCV9, 80 | EM_TRICORE=elf_consts.EM_TRICORE, 81 | EM_ARC=elf_consts.EM_ARC, 82 | EM_H8_300=elf_consts.EM_H8_300, 83 | EM_H8_300H=elf_consts.EM_H8_300H, 84 | EM_H8S=elf_consts.EM_H8S, 85 | EM_H8_500=elf_consts.EM_H8_500, 86 | EM_IA_64=elf_consts.EM_IA_64, 87 | EM_MIPS_X=elf_consts.EM_MIPS_X, 88 | EM_COLDFIRE=elf_consts.EM_COLDFIRE, 89 | EM_68HC12=elf_consts.EM_68HC12, 90 | EM_MMA=elf_consts.EM_MMA, 91 | EM_PCP=elf_consts.EM_PCP, 92 | EM_NCPU=elf_consts.EM_NCPU, 93 | EM_NDR1=elf_consts.EM_NDR1, 94 | EM_STARCORE=elf_consts.EM_STARCORE, 95 | EM_ME16=elf_consts.EM_ME16, 96 | EM_ST100=elf_consts.EM_ST100, 97 | EM_TINYJ=elf_consts.EM_TINYJ, 98 | EM_X86_64=elf_consts.EM_X86_64, 99 | EM_PDSP=elf_consts.EM_PDSP, 100 | EM_PDP10=elf_consts.EM_PDP10, 101 | EM_PDP11=elf_consts.EM_PDP11, 102 | EM_FX66=elf_consts.EM_FX66, 103 | EM_ST9PLUS=elf_consts.EM_ST9PLUS, 104 | EM_ST7=elf_consts.EM_ST7, 105 | EM_68HC16=elf_consts.EM_68HC16, 106 | EM_68HC11=elf_consts.EM_68HC11, 107 | EM_68HC08=elf_consts.EM_68HC08, 108 | EM_68HC05=elf_consts.EM_68HC05, 109 | EM_SVX=elf_consts.EM_SVX, 110 | EM_ST19=elf_consts.EM_ST19, 111 | EM_VAX=elf_consts.EM_VAX, 112 | EM_CRIS=elf_consts.EM_CRIS, 113 | EM_JAVELIN=elf_consts.EM_JAVELIN, 114 | EM_FIREPATH=elf_consts.EM_FIREPATH, 115 | EM_ZSP=elf_consts.EM_ZSP, 116 | EM_MMIX=elf_consts.EM_MMIX, 117 | EM_HUANY=elf_consts.EM_HUANY, 118 | EM_PRISM=elf_consts.EM_PRISM, 119 | EM_AVR=elf_consts.EM_AVR, 120 | EM_FR30=elf_consts.EM_FR30, 121 | EM_D10V=elf_consts.EM_D10V, 122 | EM_D30V=elf_consts.EM_D30V, 123 | EM_V850=elf_consts.EM_V850, 124 | EM_M32R=elf_consts.EM_M32R, 125 | EM_MN10300=elf_consts.EM_MN10300, 126 | EM_MN10200=elf_consts.EM_MN10200, 127 | EM_PJ=elf_consts.EM_PJ, 128 | EM_OPENRISC=elf_consts.EM_OPENRISC, 129 | EM_ARC_COMPACT=elf_consts.EM_ARC_COMPACT, 130 | EM_XTENSA=elf_consts.EM_XTENSA, 131 | EM_VIDEOCORE=elf_consts.EM_VIDEOCORE, 132 | EM_TMM_GPP=elf_consts.EM_TMM_GPP, 133 | EM_NS32K=elf_consts.EM_NS32K, 134 | EM_TPC=elf_consts.EM_TPC, 135 | EM_SNP1K=elf_consts.EM_SNP1K, 136 | EM_ST200=elf_consts.EM_ST200, 137 | EM_IP2K=elf_consts.EM_IP2K, 138 | EM_MAX=elf_consts.EM_MAX, 139 | EM_CR=elf_consts.EM_CR, 140 | EM_F2MC16=elf_consts.EM_F2MC16, 141 | EM_MSP430=elf_consts.EM_MSP430, 142 | EM_BLACKFIN=elf_consts.EM_BLACKFIN, 143 | EM_SE_C33=elf_consts.EM_SE_C33, 144 | EM_SEP=elf_consts.EM_SEP, 145 | EM_ARCA=elf_consts.EM_ARCA, 146 | EM_UNICORE=elf_consts.EM_UNICORE, 147 | EM_EXCESS=elf_consts.EM_EXCESS, 148 | EM_DXP=elf_consts.EM_DXP, 149 | EM_ALTERA_NIOS2=elf_consts.EM_ALTERA_NIOS2, 150 | EM_CRX=elf_consts.EM_CRX, 151 | EM_XGATE=elf_consts.EM_XGATE, 152 | EM_C166=elf_consts.EM_C166, 153 | EM_M16C=elf_consts.EM_M16C, 154 | EM_DSPIC30F=elf_consts.EM_DSPIC30F, 155 | EM_CE=elf_consts.EM_CE, 156 | EM_M32C=elf_consts.EM_M32C, 157 | EM_TSK3000=elf_consts.EM_TSK3000, 158 | EM_RS08=elf_consts.EM_RS08, 159 | EM_SHARC=elf_consts.EM_SHARC, 160 | EM_ECOG2=elf_consts.EM_ECOG2, 161 | EM_SCORE7=elf_consts.EM_SCORE7, 162 | EM_DSP24=elf_consts.EM_DSP24, 163 | EM_VIDEOCORE3=elf_consts.EM_VIDEOCORE3, 164 | EM_LATTICEMICO32=elf_consts.EM_LATTICEMICO32, 165 | EM_SE_C17=elf_consts.EM_SE_C17, 166 | EM_TI_C6000=elf_consts.EM_TI_C6000, 167 | EM_TI_C2000=elf_consts.EM_TI_C2000, 168 | EM_TI_C5500=elf_consts.EM_TI_C5500, 169 | EM_TI_ARP32=elf_consts.EM_TI_ARP32, 170 | EM_TI_PRU=elf_consts.EM_TI_PRU, 171 | EM_MMDSP_PLUS=elf_consts.EM_MMDSP_PLUS, 172 | EM_CYPRESS_M8C=elf_consts.EM_CYPRESS_M8C, 173 | EM_R32C=elf_consts.EM_R32C, 174 | EM_TRIMEDIA=elf_consts.EM_TRIMEDIA, 175 | EM_QDSP6=elf_consts.EM_QDSP6, 176 | EM_8051=elf_consts.EM_8051, 177 | EM_STXP7X=elf_consts.EM_STXP7X, 178 | EM_NDS32=elf_consts.EM_NDS32, 179 | EM_ECOG1=elf_consts.EM_ECOG1, 180 | EM_ECOG1X=elf_consts.EM_ECOG1X, 181 | EM_MAXQ30=elf_consts.EM_MAXQ30, 182 | EM_XIMO16=elf_consts.EM_XIMO16, 183 | EM_MANIK=elf_consts.EM_MANIK, 184 | EM_CRAYNV2=elf_consts.EM_CRAYNV2, 185 | EM_RX=elf_consts.EM_RX, 186 | EM_METAG=elf_consts.EM_METAG, 187 | EM_MCST_ELBRUS=elf_consts.EM_MCST_ELBRUS, 188 | EM_ECOG16=elf_consts.EM_ECOG16, 189 | EM_CR16=elf_consts.EM_CR16, 190 | EM_ETPU=elf_consts.EM_ETPU, 191 | EM_SLE9X=elf_consts.EM_SLE9X, 192 | EM_L10M=elf_consts.EM_L10M, 193 | EM_K10M=elf_consts.EM_K10M, 194 | EM_AVR32=elf_consts.EM_AVR32, 195 | EM_STM8=elf_consts.EM_STM8, 196 | EM_TILE64=elf_consts.EM_TILE64, 197 | EM_TILEPRO=elf_consts.EM_TILEPRO, 198 | EM_MICROBLAZE=elf_consts.EM_MICROBLAZE, 199 | EM_CUDA=elf_consts.EM_CUDA, 200 | EM_TILEGX=elf_consts.EM_TILEGX, 201 | EM_CLOUDSHIELD=elf_consts.EM_CLOUDSHIELD, 202 | EM_COREA_1ST=elf_consts.EM_COREA_1ST, 203 | EM_COREA_2ND=elf_consts.EM_COREA_2ND, 204 | EM_ARC_COMPACT2=elf_consts.EM_ARC_COMPACT2, 205 | EM_OPEN8=elf_consts.EM_OPEN8, 206 | EM_RL78=elf_consts.EM_RL78, 207 | EM_VIDEOCORE5=elf_consts.EM_VIDEOCORE5, 208 | EM_78KOR=elf_consts.EM_78KOR, 209 | EM_56800EX=elf_consts.EM_56800EX, 210 | EM_BA1=elf_consts.EM_BA1, 211 | EM_BA2=elf_consts.EM_BA2, 212 | EM_XCORE=elf_consts.EM_XCORE, 213 | EM_MCHP_PIC=elf_consts.EM_MCHP_PIC, 214 | EM_INTEL205=elf_consts.EM_INTEL205, 215 | EM_INTEL206=elf_consts.EM_INTEL206, 216 | EM_INTEL207=elf_consts.EM_INTEL207, 217 | EM_INTEL208=elf_consts.EM_INTEL208, 218 | EM_INTEL209=elf_consts.EM_INTEL209, 219 | EM_KM32=elf_consts.EM_KM32, 220 | EM_KMX32=elf_consts.EM_KMX32, 221 | EM_KMX16=elf_consts.EM_KMX16, 222 | EM_KMX8=elf_consts.EM_KMX8, 223 | EM_KVARC=elf_consts.EM_KVARC, 224 | EM_CDP=elf_consts.EM_CDP, 225 | EM_COGE=elf_consts.EM_COGE, 226 | EM_COOL=elf_consts.EM_COOL, 227 | EM_NORC=elf_consts.EM_NORC, 228 | EM_CSR_KALIMBA=elf_consts.EM_CSR_KALIMBA, 229 | EM_Z80=elf_consts.EM_Z80, 230 | EM_VISIUM=elf_consts.EM_VISIUM, 231 | EM_FT32=elf_consts.EM_FT32, 232 | EM_MOXIE=elf_consts.EM_MOXIE, 233 | EM_AMDGPU=elf_consts.EM_AMDGPU, 234 | EM_RISCV=elf_consts.EM_RISCV, 235 | ) 236 | 237 | self.Elf_SegmentType = Enum(Hex(Int32u), 238 | PT_NULL=elf_consts.PT_NULL, 239 | PT_LOAD=elf_consts.PT_LOAD, 240 | PT_DYNAMIC=elf_consts.PT_DYNAMIC, 241 | PT_INTER=elf_consts.PT_INTER, 242 | PT_NOTE=elf_consts.PT_NOTE, 243 | PT_SHLIB=elf_consts.PT_SHLIB, 244 | PT_PHDR=elf_consts.PT_PHDR, 245 | PT_TLS=elf_consts.PT_TLS, 246 | PT_LOOS=elf_consts.PT_LOOS, 247 | PT_HIOS=elf_consts.PT_HIOS, 248 | PT_LOPROC=elf_consts.PT_LOPROC, 249 | PT_HIPROC=elf_consts.PT_HIPROC, 250 | PT_GNU_EH_FRAME=elf_consts.PT_GNU_EH_FRAME, 251 | ) 252 | 253 | self.Elf_Type = Enum(Hex(Int16u), 254 | ET_NONE=elf_consts.ET_NONE, 255 | ET_REL=elf_consts.ET_REL, 256 | ET_EXEC=elf_consts.ET_EXEC, 257 | ET_DYN=elf_consts.ET_DYN, 258 | ET_CORE=elf_consts.ET_CORE, 259 | ET_LOPROC=elf_consts.ET_LOPROC, 260 | ET_HIPROC=elf_consts.ET_HIPROC, 261 | ) 262 | 263 | self.Elf_Version = Enum(Hex(Int8u), 264 | EV_NONE=elf_consts.EV_NONE, 265 | EV_CURRENT=elf_consts.EV_CURRENT, 266 | EV_NUM=elf_consts.EV_NUM, 267 | ) 268 | 269 | self.Elf_Version2 = Enum(Hex(Int32u), 270 | EV_NONE=elf_consts.EV_NONE, 271 | EV_CURRENT=elf_consts.EV_CURRENT, 272 | EV_NUM=elf_consts.EV_NUM, 273 | ) 274 | 275 | self.Elf_OsAbi = Enum(Hex(Int8u), 276 | ELFOSABI_NONE=elf_consts.ELFOSABI_NONE, 277 | ELFOSABI_LINUX=elf_consts.ELFOSABI_LINUX, 278 | ) 279 | 280 | # special section indexes 281 | self.Elf_SectionIndex = Enum(Hex(Int32u), 282 | SHN_UNDEF=elf_consts.SHN_UNDEF, 283 | SHN_LORESERVE=elf_consts.SHN_LORESERVE, 284 | SHN_LOPROC=elf_consts.SHN_LOPROC, 285 | SHN_HIPROC=elf_consts.SHN_HIPROC, 286 | SHN_LIVEPATCH=elf_consts.SHN_LIVEPATCH, 287 | SHN_ABS=elf_consts.SHN_ABS, 288 | SHN_COMMON=elf_consts.SHN_COMMON, 289 | SHN_HIRESERVE=elf_consts.SHN_HIRESERVE, 290 | ) 291 | 292 | self.Elf_SectionType = Enum(Hex(Int32u), 293 | SHT_NULL=elf_consts.SHT_NULL, 294 | SHT_PROGBITS=elf_consts.SHT_PROGBITS, 295 | SHT_SYMTAB=elf_consts.SHT_SYMTAB, 296 | SHT_STRTAB=elf_consts.SHT_STRTAB, 297 | SHT_RELA=elf_consts.SHT_RELA, 298 | SHT_HASH=elf_consts.SHT_HASH, 299 | SHT_DYNAMIC=elf_consts.SHT_DYNAMIC, 300 | SHT_NOTE=elf_consts.SHT_NOTE, 301 | SHT_NOBITS=elf_consts.SHT_NOBITS, 302 | SHT_REL=elf_consts.SHT_REL, 303 | SHT_SHLIB=elf_consts.SHT_SHLIB, 304 | SHT_DYNSYM=elf_consts.SHT_DYNSYM, 305 | SHT_NUM=elf_consts.SHT_NUM, 306 | SHT_LOPROC=elf_consts.SHT_LOPROC, 307 | SHT_HIPROC=elf_consts.SHT_HIPROC, 308 | SHT_LOUSER=elf_consts.SHT_LOUSER, 309 | SHT_HIUSER=elf_consts.SHT_HIUSER, 310 | ) 311 | 312 | self.Elf32_Phdr = Struct( 313 | 'p_type' / self.Elf_SegmentType, 314 | 'p_offset' / Hex(Elf32_Off), 315 | 'p_vaddr' / Hex(Elf32_Addr), 316 | 'p_paddr' / Hex(Elf32_Addr), 317 | 'p_filesz' / Hex(Elf32_Word), 318 | 'p_memsz' / Hex(Elf32_Word), 319 | 'p_flags' / Hex(Elf32_Word), 320 | 'p_align' / Hex(Elf32_Word), 321 | 'data' / If(this.p_type == self.Elf_SegmentType.PT_LOAD, 322 | Pointer(this.p_offset, Bytes(this.p_filesz))) 323 | ) 324 | 325 | self.Elf64_Phdr = Struct( 326 | 'p_type' / self.Elf_SegmentType, 327 | 'p_flags' / Hex(Elf64_Word), 328 | 'p_offset' / Hex(Elf64_Off), 329 | 'p_vaddr' / Hex(Elf64_Addr), 330 | 'p_paddr' / Hex(Elf64_Addr), 331 | 'p_filesz' / Hex(Elf64_Xword), 332 | 'p_memsz' / Hex(Elf64_Xword), 333 | 'p_align' / Hex(Elf64_Xword), 334 | 'data' / If(this.p_type == self.Elf_SegmentType.PT_LOAD, 335 | Pointer(this.p_offset, Bytes(this.p_filesz))) 336 | ) 337 | 338 | self.Elf32_Ehdr = Struct( 339 | 'e_ident' / Struct( 340 | 'magic' / Const(elf_consts.ELFMAG), 341 | 'class' / self.Elf_Class, 342 | 'data' / self.Elf_Data, 343 | 'version' / Default(self.Elf_Version, 344 | self.Elf_Version.EV_CURRENT), 345 | 'osabi' / self.Elf_OsAbi, 346 | 'pad' / Padding(8), 347 | ), 348 | 'e_type' / Default(self.Elf_Type, self.Elf_Type.ET_EXEC), 349 | 'e_machine' / Hex(self.Elf_Machine), 350 | 'e_version' / Default(self.Elf_Version2, 351 | self.Elf_Version2.EV_CURRENT), 352 | 'e_entry' / Hex(Int32u), 353 | 'e_phoff' / Hex(Int32u), 354 | 'e_shoff' / Hex(Int32u), 355 | 'e_flags' / Default(Hex(Int32u), 0), 356 | 'e_ehsize' / Hex(Int16u), 357 | 'e_phentsize' / Hex(Int16u), 358 | 'e_phnum' / Hex(Int16u), 359 | 'e_shentsize' / Hex(Int16u), 360 | 'e_shnum' / Hex(Int16u), 361 | 'e_shstrndx' / Hex(Int16u), 362 | ) 363 | 364 | self.Elf64_Ehdr = Struct( 365 | 'e_ident' / Struct( 366 | 'magic' / Const(elf_consts.ELFMAG), 367 | 'class' / self.Elf_Class, 368 | 'data' / self.Elf_Data, 369 | 'version' / Default(self.Elf_Version, 370 | self.Elf_Version.EV_CURRENT), 371 | 'osabi' / self.Elf_OsAbi, 372 | 'pad' / Padding(8), 373 | ), 374 | 'e_type' / Default(self.Elf_Type, self.Elf_Type.ET_EXEC), 375 | 'e_machine' / Hex(self.Elf_Machine), 376 | 'e_version' / Default(self.Elf_Version2, 377 | self.Elf_Version2.EV_CURRENT), 378 | 'e_entry' / Hex(Elf64_Addr), 379 | 'e_phoff' / Hex(Elf64_Off), 380 | 'e_shoff' / Hex(Elf64_Off), 381 | 'e_flags' / Default(Hex(Int32u), 0), 382 | 'e_ehsize' / Hex(Int16u), 383 | 'e_phentsize' / Hex(Int16u), 384 | 'e_phnum' / Hex(Int16u), 385 | 'e_shentsize' / Hex(Int16u), 386 | 'e_shnum' / Hex(Int16u), 387 | 'e_shstrndx' / Hex(Int16u), 388 | ) 389 | 390 | self.Elf32_Shdr = Struct( 391 | 'sh_name' / self.Elf_SectionIndex, 392 | 'sh_type' / self.Elf_SectionType, 393 | 'sh_flags' / Hex(Int32u), 394 | 'sh_addr' / Hex(Int32u), 395 | 'sh_offset' / Hex(Int32u), 396 | 'sh_size' / Hex(Int32u), 397 | 'sh_link' / Hex(Int32u), 398 | 'sh_info' / Hex(Int32u), 399 | 'sh_addralign' / Hex(Int32u), 400 | 'sh_entsize' / Hex(Int32u), 401 | 'data' / If(this.sh_type != self.Elf_SectionType.SHT_NOBITS, 402 | Pointer(this.sh_offset, Bytes(this.sh_size))) 403 | ) 404 | 405 | self.Elf64_Shdr = Struct( 406 | 'sh_name' / self.Elf_SectionIndex, 407 | 'sh_type' / self.Elf_SectionType, 408 | 'sh_flags' / Hex(Elf64_Xword), 409 | 'sh_addr' / Hex(Elf64_Addr), 410 | 'sh_offset' / Hex(Elf64_Off), 411 | 'sh_size' / Hex(Elf64_Xword), 412 | 'sh_link' / Hex(Elf64_Word), 413 | 'sh_info' / Hex(Elf64_Word), 414 | 'sh_addralign' / Hex(Elf64_Xword), 415 | 'sh_entsize' / Hex(Elf64_Xword), 416 | 'data' / If(this.sh_type != self.Elf_SectionType.SHT_NOBITS, 417 | Pointer(this.sh_offset, Bytes(this.sh_size))) 418 | ) 419 | 420 | self.Elf32 = Struct( 421 | 'header' / self.Elf32_Ehdr, 422 | 'segments' / Pointer(this.header.e_phoff, 423 | Array(this.header.e_phnum, self.Elf32_Phdr)), 424 | 'sections' / Pointer(this.header.e_shoff, 425 | Array(this.header.e_shnum, self.Elf32_Shdr)), 426 | ) 427 | 428 | self.Elf64 = Struct( 429 | 'header' / self.Elf64_Ehdr, 430 | 'segments' / Pointer(this.header.e_phoff, 431 | Array(this.header.e_phnum, self.Elf64_Phdr)), 432 | 'sections' / Pointer(this.header.e_shoff, 433 | Array(this.header.e_shnum, self.Elf64_Shdr)), 434 | ) 435 | --------------------------------------------------------------------------------