Compare commits

..

No commits in common. "1762c8c43542c0aab1807ce5b7168ead063b2531" and "fd650d3dff2e542524c7fd7055dab14f7e35ff5c" have entirely different histories.

2 changed files with 23 additions and 52 deletions

View File

@ -33,8 +33,6 @@ class elf_symbol():
name: Name of the symbol
section: section where the symbol data is placed
index: Absolut index in the symbol table
info: Type of the symbol
@ -57,8 +55,6 @@ class elf_symbol():
else:
self.name = ''
self.section: elf_section | None = self.file.sections[self['st_shndx']] if self['st_shndx'] < len(self.file.sections) else None
self.index = index
self.info, self.description = fdat.st_info_values[fields['st_info'] & 0x0F]
@ -72,11 +68,7 @@ class elf_symbol():
Returns:
Symbol data
"""
assert self.section, 'This symbol is not associated to a data section'
if self.section.type == 'SHT_NOBITS':
return b'\x00' * self['st_size']
else:
offset = self.section['sh_offset'] + self['st_value']
offset = self.file.sections[self['st_shndx']]['sh_offset'] + self['st_value']
return self.file.read_bytes(offset, self['st_size'])
def read_data_hex(self) -> str:
@ -84,7 +76,7 @@ class elf_symbol():
def get_relocations(self) -> 'relocation_list':
"""List all relocations that are pointing to this symbol.
The symbol section must be of type SHT_PROGBITS (program code). Therefore
The symbol must be of type SHT_PROGBITS (program code). Therefore
this function lists typically all relocations that will be
applied to the function represented by the symbol.
@ -92,9 +84,10 @@ class elf_symbol():
List of relocations
"""
ret: list[elf_relocation] = list()
assert self.section and self.section.type == 'SHT_PROGBITS'
section = self.file.sections[self.fields['st_shndx']]
assert section.type == 'SHT_PROGBITS'
for reloc in self.file.get_relocations():
if reloc.target_section == self.section:
if reloc.target_section == section:
offset = reloc['r_offset'] - self['st_value']
if 0 <= offset < self['st_size']:
ret.append(reloc)
@ -112,7 +105,7 @@ class elf_symbol():
f'name {self.name}\n' +\
f'stb {self.stb} ({self.stb_description})\n' +\
f'info {self.info} ({self.description})\n' +\
'\n'.join(f"{k:18} {v:4} {fdat.symbol_fields[k]}" for k, v in self.fields.items()) + '\n'
'\n'.join(f'{k:18} {v:4}' for k, v in self.fields.items()) + '\n'
class elf_section():
@ -163,19 +156,8 @@ class elf_section():
Returns:
Data of the section
"""
if self.type == 'SHT_NOBITS':
return b'\x00' * self['sh_size']
else:
return self.file.read_bytes(self['sh_offset'], self['sh_size'])
def get_symbols(self) -> 'symbol_list':
"""Lists all ELF symbols associated with this section
Returns:
Symbol list
"""
return symbol_list(self.file._list_symbols(self.index))
def get_data_hex(self) -> str:
data = self.file.read_bytes(self['sh_offset'], self['sh_size'])
return ' '.join(f'{d:02X}' for d in data)
@ -338,9 +320,9 @@ class symbol_list(elf_list[elf_symbol]):
"""A class for representing a list of ELF symbols
"""
def _compact_table(self) -> tuple[list[str], list[list[int | str]], list[str]]:
columns = ['index', 'name', 'info', 'size', 'stb', 'section', 'description']
columns = ['index', 'name', 'info', 'size', 'stb', 'description']
data: list[list[str | int]] = [[item.index, item.name, item.info, item.fields['st_size'],
item.stb, item.section.name if item.section else '', item.description] for item in self]
item.stb, item.description] for item in self]
return columns, data, ['index', 'size']
@ -387,15 +369,14 @@ class elf_file:
string_table_section: The string table section (first section with
the name .strtab)
"""
def __init__(self, data: bytes | bytearray):
assert isinstance(data, (bytes, bytearray)), 'Binary ELF data must be provided as bytes or bytearray.'
def __init__(self, data: bytes):
self._data = data
# Defaults required for function _read_int_from_elf_field
self.bit_width = 32
self.byteorder: Literal['little', 'big'] = 'little'
assert self._read_bytes_from_elf_field('e_ident[EI_MAG]') == b'\x7fELF', 'Not an ELF file'
assert self._read_bytes_from_elf_field('e_ident[EI_MAG]') == bytes([0x7F, 0x45, 0x4c, 0x46]), 'Not an ELF file'
self.bit_width = {1: 32, 2: 64}[self._read_int_from_elf_field('e_ident[EI_CLASS]')]
@ -433,7 +414,7 @@ class elf_file:
offs = self.fields['e_shoff'] + i * self.fields['e_shentsize']
yield {fn: self._read_from_sh_field(offs, fn) for fn in fdat.section_header.keys()}
def _list_symbols(self, section_index: int | None = None) -> Generator[elf_symbol, None, None]:
def _list_symbols(self) -> Generator[elf_symbol, None, None]:
if self.symbol_table_section:
offs = self.symbol_table_section['sh_offset']
@ -453,7 +434,6 @@ class elf_file:
ret['st_value'] = self.read_int(i + 8, 8)
ret['st_size'] = self.read_int(i + 16, 8)
if section_index is None or section_index == ret['st_shndx']:
yield elf_symbol(self, ret, j)
def get_relocations(self, reloc_section: elf_section | str | list[str] | None = None) -> relocation_list:

View File

@ -271,7 +271,7 @@ section_header = {
},
"sh_size": {
"32": "0x14", "64": "0x20", "size32": "4", "size64": "8", "field_name": "sh_size",
"description": "Size in bytes of the section in memory or 0. May be equal to size in file."
"description": "Size in bytes of the section in the file image. May be 0."
},
"sh_link": {
"32": "0x18", "64": "0x28", "size32": "4", "size64": "4", "field_name": "sh_link",
@ -316,25 +316,16 @@ section_header_types_ex = {0x60000000: 'OS-specific',
0x70000000: 'Processor-specific',
0x80000000: 'Application-specific'}
symbol_fields = {
"st_name": "Index into the string table for the symbol's name",
"st_info": "Encodes the symbol's type and its binding attribute",
"st_other": "Defines symbol visibility within and outside the object file",
"st_shndx": "Specifies which section this symbol is associated with",
"st_value": "Holds the symbol's address or offset, depending on context",
"st_size": "Specifies the size of the symbol (e.g., function length or variable size)"
}
st_info_values = {
0: ("STT_NOTYPE", "Type is unspecified"),
1: ("STT_OBJECT", "Data object"),
2: ("STT_FUNC", "Code object"),
3: ("STT_SECTION", "Section associated"),
4: ("STT_FILE", "File name"),
5: ("STT_COMMON", "Common data object"),
6: ("STT_TLS", "Thread-local data object"),
0: ("STT_NOTYPE", "Symbol type is unspecified"),
1: ("STT_OBJECT", "Symbol is a data object"),
2: ("STT_FUNC", "Symbol is a code object"),
3: ("STT_SECTION", "Symbol associated with a section"),
4: ("STT_FILE", "Symbol's name is file name"),
5: ("STT_COMMON", "Symbol is a common data object"),
6: ("STT_TLS", "Symbol is thread-local data object"),
7: ("STT_NUM", "Number of defined types"),
10: ("STT_GNU_IFUNC", "Indirect code object")
10: ("STT_GNU_IFUNC", "Symbol is indirect code object")
}
stb_values = {