275 lines
8.6 KiB
Python
275 lines
8.6 KiB
Python
|
from ctypes import *
|
||
|
from ..constants import EI_NIDENT
|
||
|
|
||
|
# Obtained from /usr/lib/elf.h
|
||
|
|
||
|
# Type for a 16-bit quantity.
|
||
|
Elf32_Half = c_uint16
|
||
|
Elf64_Half = c_uint16
|
||
|
|
||
|
# Types for signed and unsigned 32-bit quantities.
|
||
|
Elf32_Word = c_uint32
|
||
|
Elf32_Sword = c_int32
|
||
|
Elf64_Word = c_uint32
|
||
|
Elf64_Sword = c_int32
|
||
|
|
||
|
# Types for signed and unsigned 64-bit quantities.
|
||
|
Elf32_Xword = c_uint64
|
||
|
Elf32_Sxword = c_int64
|
||
|
Elf64_Xword = c_uint64
|
||
|
Elf64_Sxword = c_int64
|
||
|
|
||
|
# Type of addresses.
|
||
|
Elf32_Addr = c_uint32
|
||
|
Elf64_Addr = c_uint64
|
||
|
|
||
|
# Type of file offsets.
|
||
|
Elf32_Off = c_uint32
|
||
|
Elf64_Off = c_uint64
|
||
|
|
||
|
# Type for section indices, which are 16-bit quantities.
|
||
|
Elf32_Section = c_uint16
|
||
|
Elf64_Section = c_uint16
|
||
|
|
||
|
# Type for version symbol information.
|
||
|
Elf32_Versym = Elf32_Half
|
||
|
Elf64_Versym = Elf64_Half
|
||
|
|
||
|
# The ELF file header. This appears at the start of every ELF file.
|
||
|
|
||
|
Elf_IdentT = c_char * EI_NIDENT
|
||
|
|
||
|
Elf_Cmd = c_int
|
||
|
|
||
|
class _ElfStructure(Structure):
|
||
|
def __str__(self):
|
||
|
return self.__class__.__name__ + '(' + \
|
||
|
','.join([field[0] + '=' + str(getattr(self, field[0])) for field in self._fields_]) + ')'
|
||
|
|
||
|
class _ElfUnion(Union):
|
||
|
def __str__(self):
|
||
|
return self.__class__.__name__ + '(' + \
|
||
|
','.join([field[0] + '=' + str(getattr(self, field[0])) for field in self._fields_]) + ')'
|
||
|
|
||
|
# Libelf opaque handles
|
||
|
class Elf(_ElfStructure):
|
||
|
_fields_ = []
|
||
|
class Elf_Scn(_ElfStructure):
|
||
|
_fields_ = []
|
||
|
|
||
|
class Elf_Data(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('d_buf', c_void_p),
|
||
|
('d_type', c_int),
|
||
|
('d_size', c_size_t),
|
||
|
('d_off', c_size_t),
|
||
|
('d_align', c_size_t),
|
||
|
('d_version', c_uint)
|
||
|
]
|
||
|
|
||
|
ElfP = POINTER(Elf)
|
||
|
Elf_ScnP = POINTER(Elf_Scn)
|
||
|
Elf_DataP = POINTER(Elf_Data)
|
||
|
|
||
|
class Elf32_Ehdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('e_ident', Elf_IdentT ), # Magic number and other info
|
||
|
('e_type', Elf32_Half ), # Object file type
|
||
|
('e_machine', Elf32_Half ), # Architecture
|
||
|
('e_version', Elf32_Word ), # Object file version
|
||
|
('e_entry', Elf32_Addr ), # Entry point virtual address
|
||
|
('e_phoff', Elf32_Off), # Program header table file offset
|
||
|
('e_shoff', Elf32_Off), # Section header table file offset
|
||
|
('e_flags', Elf32_Word ), # Processor-specific flags
|
||
|
('e_ehsize', Elf32_Half ), # ELF header size in bytes
|
||
|
('e_phentsize', Elf32_Half ), # Program header table entry size
|
||
|
('e_phnum', Elf32_Half ), # Program header table entry count
|
||
|
('e_shentsize', Elf32_Half ), # Section header table entry size
|
||
|
('e_shnum', Elf32_Half ), # Section header table entry count
|
||
|
('e_shstrndx', Elf32_Half ), # Section header string table index
|
||
|
]
|
||
|
|
||
|
class Elf64_Ehdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('e_ident', Elf_IdentT ), # Magic number and other info
|
||
|
('e_type', Elf64_Half ), # Object file type
|
||
|
('e_machine', Elf64_Half ), # Architecture
|
||
|
('e_version', Elf64_Word ), # Object file version
|
||
|
('e_entry', Elf64_Addr ), # Entry point virtual address
|
||
|
('e_phoff', Elf64_Off), # Program header table file offset
|
||
|
('e_shoff', Elf64_Off), # Section header table file offset
|
||
|
('e_flags', Elf64_Word ), # Processor-specific flags
|
||
|
('e_ehsize', Elf64_Half ), # ELF header size in bytes
|
||
|
('e_phentsize', Elf64_Half ), # Program header table entry size
|
||
|
('e_phnum', Elf64_Half ), # Program header table entry count
|
||
|
('e_shentsize', Elf64_Half ), # Section header table entry size
|
||
|
('e_shnum', Elf64_Half ), # Section header table entry count
|
||
|
('e_shstrndx', Elf64_Half ), # Section header string table index
|
||
|
]
|
||
|
|
||
|
class Elf32_Shdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('sh_name', Elf32_Word), # Section name (string tbl index)
|
||
|
('sh_type', Elf32_Word), # Section type
|
||
|
('sh_flags', Elf32_Word), # Section flags
|
||
|
('sh_addr', Elf32_Addr), # Section virtual addr at execution
|
||
|
('sh_offset', Elf32_Off), # Section file offset
|
||
|
('sh_size', Elf32_Word), # Section size in bytes
|
||
|
('sh_link', Elf32_Word), # Link to another section
|
||
|
('sh_info', Elf32_Word), # Additional section information
|
||
|
('sh_addralign', Elf32_Word), # Section alignment
|
||
|
('sh_entsize', Elf32_Word), # Entry size if section holds table
|
||
|
]
|
||
|
|
||
|
class Elf64_Shdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('sh_name', Elf64_Word), # Section name (string tbl index)
|
||
|
('sh_type', Elf64_Word), # Section type
|
||
|
('sh_flags', Elf64_Xword), # Section flags
|
||
|
('sh_addr', Elf64_Addr), # Section virtual addr at execution
|
||
|
('sh_offset', Elf64_Off), # Section file offset
|
||
|
('sh_size', Elf64_Xword), # Section size in bytes
|
||
|
('sh_link', Elf64_Word), # Link to another section
|
||
|
('sh_info', Elf64_Word), # Additional section information
|
||
|
('sh_addralign', Elf64_Xword), # Section alignment
|
||
|
('sh_entsize', Elf64_Xword), # Entry size if section holds table
|
||
|
]
|
||
|
|
||
|
class Elf32_Phdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('p_type', Elf32_Word), # Segment type
|
||
|
('p_offset', Elf32_Off), # Segment file offset
|
||
|
('p_vaddr', Elf32_Addr), # Segment virtual address
|
||
|
('p_paddr', Elf32_Addr), # Segment physical address
|
||
|
('p_filesz', Elf32_Word), # Segment size in file
|
||
|
('p_memsz', Elf32_Word), # Segment size in memory
|
||
|
('p_flags', Elf32_Word), # Segment flags
|
||
|
('p_align', Elf32_Word), # Segment alignment
|
||
|
]
|
||
|
|
||
|
class Elf64_Phdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('p_type', Elf64_Word), # Segment type
|
||
|
('p_flags', Elf64_Word), # Segment flags
|
||
|
('p_offset', Elf64_Off), # Segment file offset
|
||
|
('p_vaddr', Elf64_Addr), # Segment virtual address
|
||
|
('p_paddr', Elf64_Addr), # Segment physical address
|
||
|
('p_filesz', Elf64_Xword), # Segment size in file
|
||
|
('p_memsz', Elf64_Xword), # Segment size in memory
|
||
|
('p_align', Elf64_Xword), # Segment alignment
|
||
|
]
|
||
|
|
||
|
# /* Symbol table entry. */
|
||
|
class Elf32_Sym(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('st_name', Elf32_Word), # Symbol name (string tbl index)
|
||
|
('st_value', Elf32_Addr), # Symbol value
|
||
|
('st_size', Elf32_Word), # Symbol size
|
||
|
('st_info', c_char), # Symbol type and binding
|
||
|
('st_other', c_char), # Symbol visibility
|
||
|
('st_shndx', Elf32_Section), # Section index
|
||
|
]
|
||
|
|
||
|
class Elf64_Sym(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('st_name', Elf64_Word), # Symbol name (string tbl index)
|
||
|
('st_info', c_char), # Symbol type and binding
|
||
|
('st_other', c_char), # Symbol visibility
|
||
|
('st_shndx', Elf64_Section), # Section index
|
||
|
('st_value', Elf64_Addr), # Symbol value
|
||
|
('st_size', Elf64_Xword), # Symbol size
|
||
|
]
|
||
|
|
||
|
#/* The syminfo section if available contains additional information about
|
||
|
# every dynamic symbol. */
|
||
|
|
||
|
class Elf32_Syminfo(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('si_boundto', Elf32_Half), # Direct bindings, symbol bound to
|
||
|
('si_flags', Elf32_Half), # Per symbol flags
|
||
|
]
|
||
|
|
||
|
class Elf64_Syminfo(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('si_boundto', Elf64_Half), # Direct bindings, symbol bound to
|
||
|
('si_flags', Elf64_Half), # Per symbol flags
|
||
|
]
|
||
|
|
||
|
# /* Relocation table entry without addend (in section of type SHT_REL). */
|
||
|
|
||
|
class Elf32_Rel(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('r_offset', Elf32_Addr), # Address
|
||
|
('r_info', Elf32_Word), # Relocation type and symbol index
|
||
|
]
|
||
|
|
||
|
class Elf64_Rel(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('r_offset', Elf64_Addr), # Address
|
||
|
('r_info', Elf64_Xword), # Relocation type and symbol index
|
||
|
]
|
||
|
|
||
|
# # Relocation table entry with addend (in section of type SHT_RELA).
|
||
|
|
||
|
class Elf32_Rela(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('r_offset', Elf32_Addr), # Address
|
||
|
('r_info', Elf32_Word), # Relocation type and symbol index
|
||
|
('r_addend', Elf32_Sword), # Addend
|
||
|
]
|
||
|
|
||
|
class Elf64_Rela(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('r_offset', Elf64_Addr), # Address
|
||
|
('r_info', Elf64_Xword), # Relocation type and symbol index
|
||
|
('r_addend', Elf64_Sxword), # Addend
|
||
|
]
|
||
|
|
||
|
time_t = c_int64
|
||
|
uid_t = c_int32
|
||
|
gid_t = c_int32
|
||
|
mode_t = c_int32
|
||
|
off_t = c_int64
|
||
|
|
||
|
class Elf_Arhdr(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('ar_name', c_char_p),
|
||
|
('ar_date', time_t),
|
||
|
('ar_uid', uid_t),
|
||
|
('ar_gid', gid_t),
|
||
|
('ar_mode', mode_t),
|
||
|
('ar_size', off_t),
|
||
|
('ar_fmag', POINTER(c_char)),
|
||
|
]
|
||
|
|
||
|
class _Elf64_DynUnion(_ElfUnion):
|
||
|
_fields_ = [
|
||
|
('d_val', Elf64_Xword),
|
||
|
('d_ptr', Elf64_Addr),
|
||
|
]
|
||
|
|
||
|
class Elf64_Dyn(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('d_tag', Elf64_Xword),
|
||
|
('d_un', _Elf64_DynUnion),
|
||
|
]
|
||
|
|
||
|
# GNU Extensions
|
||
|
class Elf64_Verneed(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('vn_version', Elf64_Half),
|
||
|
('vn_cnt', Elf64_Half),
|
||
|
('vn_file', Elf64_Word),
|
||
|
('vn_aux', Elf64_Word),
|
||
|
('vn_next', Elf64_Word),
|
||
|
]
|
||
|
|
||
|
class Elf64_Vernaux(_ElfStructure):
|
||
|
_fields_ = [
|
||
|
('vna_hash', Elf64_Word),
|
||
|
('vna_flags', Elf64_Half),
|
||
|
('vna_other', Elf64_Half),
|
||
|
('vna_name', Elf64_Word),
|
||
|
('vna_next', Elf64_Word),
|
||
|
]
|