ELF Backend#

class cle.backends.ELF[source]#

Bases: MetaELF

The main loader class for statically loading ELF executables. Uses the pyreadelf library where useful.

Useful backend options:

  • debug_symbols: Provides the path to a separate file which contains the binary’s debug symbols

  • discard_section_headers: Do not parse section headers. Use this if they are corrupted or malicious.

  • discard_program_headers: Do not parse program headers. Use this if the binary is for a platform whose ELF

    loader only looks at section headers, but whose toolchain generates program headers anyway.

is_default = True#
__init__(*args, addend=None, debug_symbols=None, discard_section_headers=False, discard_program_headers=False, **kwargs)[source]#
Parameters:
  • binary – The path to the binary to load

  • binary_stream – The open stream to this binary. The reference to this will be held until you call close.

  • is_main_bin – Whether this binary should be loaded as the main executable

imports: typing.Dict[str, 'Relocation']#
relocs: List[Relocation]#
close()[source]#
classmethod check_compatibility(spec, obj)[source]#

Performs a minimal static load of spec and returns whether it’s compatible with other_obj

classmethod check_magic_compatibility(stream)[source]#

Check if a stream of bytes contains the same magic number as the main object

static is_compatible(stream)[source]#

Determine quickly whether this backend can load an object from this stream

static extract_arch(reader)[source]#
property initializers#

Stub function. Should be overridden by backends that can provide initializer functions that ought to be run before execution reaches the entry point. Addresses should be rebased.

property finalizers#

Stub function. Like initializers, but with finalizers.

property symbols_by_name#
get_symbol(symid, symbol_table=None)[source]#

Gets a Symbol object for the specified symbol.

Parameters:

symid – Either an index into .dynsym or the name of a symbol.

rebase(new_base)[source]#

Rebase backend’s regions to the new base where they were mapped by the loader

child_objects: List['Backend']#
exception_handlings: List[ExceptionHandling]#
function_hints: List[FunctionHint]#
memory: Clemory#
cached_content: Optional[bytes]#
class cle.backends.elf.ELFCore[source]#

Bases: ELF

Loader class for ELF core files.

One key pain point when analyzing a core dump generated on a remote machine is that the paths to binaries are absolute (and may not exist or be the same on your local machine).

Therefore, you can use the options `remote_file_mapping to specify a dict mapping (easy if there are a small number of mappings) or remote_file_mapper to specify a function that accepts a remote file name and returns the local file name (useful if there are many mappings).

If you specify both remote_file_mapping and remote_file_mapper, remote_file_mapping is applied first, then the result is passed to remote_file_mapper.

Parameters:
  • executable – Optional path to the main binary of the core dump. If not supplied, ELFCore will attempt to figure it out automatically from the core dump.

  • remote_file_mapping – Optional dict that maps specific file names in the core dump to other file names.

  • remote_file_mapper – Optional function that is used to map every file name in the core dump to whatever is returned from this function.

is_default = True#
__init__(*args, executable=None, remote_file_mapping=None, remote_file_mapper=None, **kwargs)[source]#
Parameters:
  • binary – The path to the binary to load

  • binary_stream – The open stream to this binary. The reference to this will be held until you call close.

  • is_main_bin – Whether this binary should be loaded as the main executable

static is_compatible(stream)[source]#

Determine quickly whether this backend can load an object from this stream

property threads#

If this backend represents a dump of a running program, it may contain one or more thread contexts, i.e. register files. This property should contain a list of names for these threads, which should be unique.

thread_registers(thread=None)[source]#

If this backend represents a dump of a running program, it may contain one or more thread contexts, i.e. register files. This method should return the register file for a given thread (as named in Backend.threads) as a dict mapping register names (as seen in archinfo) to numbers. If the thread is not specified, it should return the context for a “default” thread. If there are no threads, it should return an empty dict.

imports: typing.Dict[str, 'Relocation']#
relocs: List[Relocation]#
child_objects: List['Backend']#
exception_handlings: List[ExceptionHandling]#
function_hints: List[FunctionHint]#
memory: Clemory#
cached_content: Optional[bytes]#
addr_to_line: SortedDict[int, Set[Tuple[int, int]]]#
variables: Optional[List[Variable]]#
compilation_units: Optional[List[CompilationUnit]]#
class cle.backends.elf.MetaELF[source]#

Bases: Backend

A base class that implements functions used by all backends that can load an ELF.

__init__(*args, **kwargs)[source]#
Parameters:
  • binary – The path to the binary to load

  • binary_stream – The open stream to this binary. The reference to this will be held until you call close.

  • is_main_bin – Whether this binary should be loaded as the main executable

supported_filetypes = ['elf']#
property plt#

Maps names to addresses.

property reverse_plt#

Maps addresses to names.

property is_ppc64_abiv1#

Returns whether the arch is PowerPC64 ABIv1.

Returns:

True if PowerPC64 ABIv1, False otherwise.

property is_ppc64_abiv2#

Returns whether the arch is PowerPC64 ABIv2.

Returns:

True if PowerPC64 ABIv2, False otherwise.

property ppc64_initial_rtoc#

Get initial rtoc value for PowerPC64 architecture.

static extract_soname(path)[source]#

Extracts the shared object identifier from the path, or returns None if it cannot.

imports: typing.Dict[str, 'Relocation']#
relocs: List[Relocation]#
child_objects: List['Backend']#
exception_handlings: List[ExceptionHandling]#
function_hints: List[FunctionHint]#
memory: Clemory#
cached_content: Optional[bytes]#
class cle.backends.elf.metaelf.Relro[source]#

Bases: Enum

An enumeration.

NONE = 0#
PARTIAL = 1#
FULL = 2#
class cle.backends.elf.symbol.ELFSymbol[source]#

Bases: Symbol

Represents a symbol for the ELF format.

Variables:
  • binding (str) – The binding of this symbol as an ELF enum string

  • section – The section associated with this symbol, or None

  • _subtype – The ELFSymbolType of this symbol

__init__(owner, symb)[source]#

Not documenting this since if you try calling it, you’re wrong.

owner: Backend#
property subtype: ELFSymbolType#

A subclass’ ABI-specific types

class cle.backends.elf.symbol_type.ELFSymbolType[source]#

Bases: SymbolSubType

ELF-specific symbol types

STT_NOTYPE = (0, None)#
STT_OBJECT = (1, None)#
STT_FUNC = (2, None)#
STT_SECTION = (3, None)#
STT_FILE = (4, None)#
STT_COMMON = (5, None)#
STT_TLS = (6, None)#
STT_LOOS = (10, None)#
STT_HIOS = (12, None)#
STT_LOPROC = (13, None)#
STT_HIPROC = (15, None)#
STT_GNU_IFUNC = (10, 'gnu')#
__init__(*args)[source]#
property elf_value#
property os_proc#
property is_custom_os_proc#
class cle.backends.elf.regions.ELFSegment[source]#

Bases: Segment

Represents a segment for the ELF format.

__init__(readelf_seg, relro=False)[source]#
property is_readable#
property is_writable#
property is_executable#
property is_relro#
vaddr: int#
memsize: int#
filesize: int#
class cle.backends.elf.regions.ELFSection[source]#

Bases: Section

SHF_WRITE = 1#
SHF_ALLOC = 2#
SHF_EXECINSTR = 4#
SHF_STRINGS = 32#
SHT_NULL = 'SHT_NULL'#
__init__(readelf_sec, remap_offset=0)[source]#
Parameters:
  • name (str) – The name of the section

  • offset (int) – The offset into the binary file this section begins

  • vaddr (int) – The address in virtual memory this section begins

  • size (int) – How large this section is

property is_readable#

Whether this section has read permissions

property is_active#
property is_writable#

Whether this section has write permissions

property occupies_memory#
property is_executable#

Whether this section has execute permissions

property is_strings#
property only_contains_uninitialized_data#

Whether this section is initialized to zero after the executable is loaded.

vaddr: int#
memsize: int#
filesize: int#
class cle.backends.elf.variable.Variable[source]#

Bases: object

Variable for DWARF from a DW_TAG_variable or DW_TAG_formal_parameter

Variables:
  • name (str) – The name of the variable

  • relative_addr – The relative addr (base addr depends on the type)

  • lexical_block – For a local variable, the lexical block where the variable is declared

__init__(elf_object: ELF)[source]#
Parameters:

elf_object (ELF) –

static from_die(die: DIE, expr_parser, elf_object: ELF, lexical_block: LexicalBlock | None = None)[source]#
Parameters:
  • die (DIE) –

  • elf_object (ELF) –

  • lexical_block (LexicalBlock | None) –

rebased_addr_from_cfa(cfa: int)[source]#

The address of this variable in the global memory.

Parameters:

cfa (int) – The canonical frame address as described by the DWARF standard.

property rebased_addr#
property addr#

Please use ‘relative_addr’ or ‘rebased_addr’ instead.

property type: VariableType#
property sort: str#
class cle.backends.elf.variable.MemoryVariable[source]#

Bases: Variable

This includes all variables that are not on the stack and not in a register. So all global variables, and also local static variables in C!

__init__(elf_object: ELF, relative_addr)[source]#
Parameters:

elf_object (ELF) –

property rebased_addr#
property sort: str#
class cle.backends.elf.variable.StackVariable[source]#

Bases: Variable

Stack Variable from DWARF.

__init__(elf_object: ELF, relative_addr)[source]#
Parameters:

elf_object (ELF) –

rebased_addr_from_cfa(cfa: int)[source]#

The address of this variable in the global memory.

Parameters:

cfa (int) – The canonical frame address as described by the DWARF standard.

property sort: str#
class cle.backends.elf.variable.RegisterVariable[source]#

Bases: Variable

Register Variable from DWARF.

__init__(elf_object: ELF, register_addr)[source]#
Parameters:

elf_object (ELF) –

property sort: str#
class cle.backends.elf.variable_type.VariableType[source]#

Bases: object

Entry class for DW_TAG_xxx_type

Parameters:
  • name (str) – name of the type

  • byte_size (int) – amount of bytes the type take in memory

  • elf_object – elf object to reference to (useful for pointer,…)

Variables:
  • name – name of the type

  • byte_size – amount of bytes the type take in memory

__init__(name: str, byte_size: int, elf_object)[source]#
Parameters:
  • name (str) –

  • byte_size (int) –

static read_from_die(die: DIE, elf_object)[source]#

entry method to read a DW_TAG_xxx_type

Parameters:

die (DIE) –

static supported_die(die: DIE) bool[source]#
Return type:

bool

Parameters:

die (DIE) –

class cle.backends.elf.variable_type.PointerType[source]#

Bases: VariableType

Entry class for DW_TAG_pointer_type. It is inherited from VariableType

Parameters:
  • byte_size (int) – amount of bytes the type take in memory

  • elf_object – elf object to reference to (useful for pointer,…)

  • referenced_offset (int) – type of the referenced as offset in the compilation_unit

__init__(byte_size: int, elf_object, referenced_offset: int)[source]#
Parameters:
  • byte_size (int) –

  • referenced_offset (int) –

classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_pointer_type. return None when there is no byte_size or type attribute.

Parameters:

die (DIE) –

property referenced_type#

attribute to get the referenced type. Return None if the type is not loaded

class cle.backends.elf.variable_type.BaseType[source]#

Bases: VariableType

Entry class for DW_TAG_base_type. It is inherited from VariableType

classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_base_type. return None when there is no byte_size attribute.

Parameters:

die (DIE) –

class cle.backends.elf.variable_type.StructType[source]#

Bases: VariableType

Entry class for DW_TAG_structure_type. It is inherited from VariableType

Parameters:
  • name (str) – name of the type

  • byte_size (int) – amount of bytes the type take in memory

  • elf_object – elf object to reference to (useful for pointer,…)

__init__(name: str, byte_size: int, elf_object, members)[source]#
Parameters:
  • name (str) –

  • byte_size (int) –

classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_structure_type. return None when there is no byte_size attribute.

Parameters:

die (DIE) –

class cle.backends.elf.variable_type.UnionType[source]#

Bases: StructType

Entry class for DW_TAG_union_type. Inherits from StructType to make it trivial.

class cle.backends.elf.variable_type.StructMember[source]#

Bases: object

Entry class for DW_TAG_member. This is not a type but a named member inside a struct. Use the property type to get its variable type.

Parameters:
  • name (str) – name of the member

  • addr_offset (int) – address offset of the member in the struct

  • elf_object – elf object to reference to (useful for pointer,…)

  • type_offset – type as offset in the compilation_unit

Variables:

name – name of the member

__init__(name: str, addr_offset: int, type_offset, elf_object)[source]#
Parameters:
  • name (str) –

  • addr_offset (int) –

classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_member_type. return None when there is no type attribute.

Parameters:

die (DIE) –

property type#

attribute to get the type of the member. Return None if the type is not loaded

class cle.backends.elf.variable_type.ArrayType[source]#

Bases: VariableType

Entry class for DW_TAG_array_type. It is inherited from VariableType

Parameters:
  • byte_size – amount of bytes the type take in memory

  • elf_object – elf object to reference to (useful for pointer,…)

  • element_offset – type of the array elements as offset in the compilation_unit

__init__(byte_size, elf_object, element_offset)[source]#
classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_array_type. return None when there is no type attribute.

Parameters:

die (DIE) –

property element_type#
class cle.backends.elf.variable_type.TypedefType[source]#

Bases: VariableType

Entry class for DW_TAG_typedef. Inherits from VariableType.

Parameters:
  • name (str) – name of the new type

  • elf_object – elf object to reference to (useful for pointer,…)

  • type_offset – type as offset in the compilation_unit

__init__(name: str, byte_size, elf_object, type_offset)[source]#
Parameters:

name (str) –

classmethod read_from_die(die: DIE, elf_object)[source]#

read an entry of DW_TAG_member_type. return None when there is no type attribute.

Parameters:

die (DIE) –

property type#

attribute to get the type of the member. Return None if the type is not loaded

References

class cle.backends.elf.lsda.ExceptionTableHeader[source]#

Bases: object

__init__(lp_start, ttype_encoding, ttype_offset, call_site_encoding, call_site_table_len)[source]#
lp_start#
ttype_encoding#
ttype_offset#
call_site_encoding#
call_site_table_len#
class cle.backends.elf.lsda.CallSiteEntry[source]#

Bases: object

__init__(cs_start, cs_len, cs_lp, cs_action)[source]#
cs_start#
cs_len#
cs_lp#
cs_action#
class cle.backends.elf.lsda.LSDAExceptionTable[source]#

Bases: object

LSDA exception table parser.

TODO: Much of this class should be eventually moved to pyelftools.

__init__(stream, bits, little_endian=True)[source]#
parse_lsda(address, offset)[source]#
class cle.backends.elf.hashtable.ELFHashTable[source]#

Bases: object

Functions to do lookup from a HASH section of an ELF file.

Information: http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-48031.html

__init__(symtab, stream, offset, arch)[source]#
Parameters:
  • symtab – The symbol table to perform lookups from (as a pyelftools SymbolTableSection).

  • stream – A file-like object to read from the ELF’s memory.

  • offset – The offset in the object where the table starts.

  • arch – The ArchInfo object for the ELF file.

get(k)[source]#

Perform a lookup. Returns a pyelftools Symbol object, or None if there is no match.

Parameters:

k – The string to look up.

static elf_hash(key)[source]#
class cle.backends.elf.hashtable.GNUHashTable[source]#

Bases: object

Functions to do lookup from a GNU_HASH section of an ELF file.

Information: https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections

__init__(symtab, stream, offset, arch)[source]#
Parameters:
  • symtab – The symbol table to perform lookups from (as a pyelftools SymbolTableSection).

  • stream – A file-like object to read from the ELF’s memory.

  • offset – The offset in the object where the table starts.

  • arch – The ArchInfo object for the ELF file.

get(k)[source]#

Perform a lookup. Returns a pyelftools Symbol object, or None if there is no match.

Parameters:

k – The string to look up

static gnu_hash(key)[source]#
class cle.backends.elf.subprogram.LexicalBlock[source]#

Bases: object

A lexical block is a sequence of source statements, e.g. a while/for loop or an if statement or some bracketed block.

Corresponds to a DW_TAG_LexicalBlock in DWARF.

Parameters:
  • super_block – The lexical block which contains this block

  • low_pc – The relative start address of the block

  • high_pc – The relative end address of the block

Variables:
  • low_pc – The relative start address of the subprogram

  • high_pc – The relative end address of the subprogram

  • child_blocks – Lexical blocks inside this block (only direct childs)

__init__(low_pc, high_pc) None[source]#
Return type:

None

class cle.backends.elf.subprogram.Subprogram[source]#

Bases: LexicalBlock

DW_TAG_subprogram for DWARF. The behavior is mostly inherited from LexicalBlock to avoid redundancy.

Parameters:
  • name (str) – The name of the function/program

  • low_pc – The relative start address of the subprogram

  • high_pc – The relative end address of the subprogram

Variables:
  • name – The name of the function/program

  • local_variables – All local variables in a Subprogram (they may reside in serveral child blocks)

__init__(name, low_pc, high_pc) None[source]#
Return type:

None

class cle.backends.elf.compilation_unit.CompilationUnit[source]#

Bases: object

CompilationUnit for DWARF See http://dwarfstd.org/doc/DWARF5.pdf page 60

__init__(name, comp_dir, low_pc, high_pc, language, elf_object)[source]#
property min_addr#
property max_addr#