mirror of https://github.com/Nonannet/pelfy.git
Compare commits
No commits in common. "1762c8c43542c0aab1807ce5b7168ead063b2531" and "fd650d3dff2e542524c7fd7055dab14f7e35ff5c" have entirely different histories.
1762c8c435
...
fd650d3dff
|
@ -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:
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue