Thread-local storage#
- class cle.backends.tls.ThreadManager[source]#
Bases:
objectThis class tracks what data is thread-local and can generate thread initialization images
Most of the heavy lifting will be handled in a subclass
- class cle.backends.tls.InternalTLSRelocation[source]#
Bases:
Relocation- AUTO_HANDLE_NONE = True#
- property value#
- property dest_addr#
- property linked_addr#
- property owner_obj#
- property rebased_addr#
The address in the global memory space this relocation would like to write to
- relocate()#
Applies this relocation. Will make changes to the memory object of the object it came from.
This implementation is a generic version that can be overridden in subclasses.
- resolve(obj, **kwargs)#
- resolvedby: Optional[Symbol]#
- resolved: bool#
- class cle.backends.tls.TLSObject[source]#
Bases:
Backend- __init__(loader, arch)[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
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property max_addr: int#
This returns the highest virtual address contained in any loaded segment of the binary.
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
- class cle.backends.tls.ELFThreadManager[source]#
Bases:
ThreadManager- new_thread(insert=True)#
- class cle.backends.tls.ELFCoreThreadManager[source]#
Bases:
ThreadManager
- class cle.backends.tls.PEThreadManager[source]#
Bases:
ThreadManager- __init__(loader, arch, max_modules=256)#
- new_thread(insert=True)#
- class cle.backends.tls.MinidumpThreadManager[source]#
Bases:
ThreadManager
- class cle.backends.tls.tls_object.ThreadManager[source]#
Bases:
objectThis class tracks what data is thread-local and can generate thread initialization images
Most of the heavy lifting will be handled in a subclass
- class cle.backends.tls.tls_object.InternalTLSRelocation[source]#
Bases:
Relocation- AUTO_HANDLE_NONE = True#
- property value#
- property dest_addr#
- property linked_addr#
- property owner_obj#
- property rebased_addr#
The address in the global memory space this relocation would like to write to
- relocate()#
Applies this relocation. Will make changes to the memory object of the object it came from.
This implementation is a generic version that can be overridden in subclasses.
- resolve(obj, **kwargs)#
- resolvedby: Optional[Symbol]#
- resolved: bool#
- class cle.backends.tls.tls_object.TLSObject[source]#
Bases:
Backend- __init__(loader, arch)[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
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property max_addr: int#
This returns the highest virtual address contained in any loaded segment of the binary.
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
This module is used when parsing the Thread Local Storage of an ELF binary. It heavily uses the TLSArchInfo namedtuple from archinfo.
ELF TLS is implemented based on the following documents:
- class cle.backends.tls.elf_tls.ELFThreadManager[source]#
Bases:
ThreadManager- new_thread(insert=True)#
- class cle.backends.tls.elf_tls.ELFTLSObject[source]#
Bases:
TLSObject- __init__(thread_manager: cle.backends.tls.elf_tls.ELFThreadManager)[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
thread_manager (ELFThreadManager) –
- property thread_pointer#
The thread pointer. This is a technical term that refers to a specific location in the TLS segment.
- property user_thread_pointer#
The thread pointer that is exported to the user
- property max_addr#
This returns the highest virtual address contained in any loaded segment of the binary.
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
- class cle.backends.tls.elf_tls.ELFTLSObjectV1[source]#
Bases:
ELFTLSObject- __init__(thread_manager: cle.backends.tls.elf_tls.ELFThreadManager)#
- 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
thread_manager (ELFThreadManager) –
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_addr(module_id, offset)#
basically
__tls_get_addr.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property max_addr#
This returns the highest virtual address contained in any loaded segment of the binary.
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- property thread_pointer#
The thread pointer. This is a technical term that refers to a specific location in the TLS segment.
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- property user_thread_pointer#
The thread pointer that is exported to the user
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
- tcb_offset: int#
- dtv_offset: int#
- tp_offset: int#
- head_offset: int#
- class cle.backends.tls.elf_tls.ELFTLSObjectV2[source]#
Bases:
ELFTLSObject- __init__(thread_manager: cle.backends.tls.elf_tls.ELFThreadManager)#
- 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
thread_manager (ELFThreadManager) –
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_addr(module_id, offset)#
basically
__tls_get_addr.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property max_addr#
This returns the highest virtual address contained in any loaded segment of the binary.
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- property thread_pointer#
The thread pointer. This is a technical term that refers to a specific location in the TLS segment.
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- property user_thread_pointer#
The thread pointer that is exported to the user
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
- tcb_offset: int#
- dtv_offset: int#
- tp_offset: int#
- head_offset: int#
- class cle.backends.tls.pe_tls.PEThreadManager[source]#
Bases:
ThreadManager- __init__(loader, arch, max_modules=256)#
- new_thread(insert=True)#
- class cle.backends.tls.pe_tls.PETLSObject[source]#
Bases:
TLSObjectThis class is used when parsing the Thread Local Storage of a PE binary. It represents both the TLS array and the TLS data area for a specific thread.
In memory the
PETLSObjis laid out as follows:+----------------------+---------------------------------------+ | TLS array | TLS data area | +----------------------+---------------------------------------+
A more detailed description of the TLS array and TLS data areas is given below.
TLS array
The TLS array is an array of addresses that points into the TLS data area. In memory it is laid out as follows:
+-----------+-----------+-----+-----------+ | address | address | ... | address | +-----------+-----------+-----+-----------+ | index = 0 | index = 1 | | index = n | +-----------+-----------+-----+-----------+
The size of each address is architecture independent (e.g. on X86 it is 4 bytes). The number of addresses in the TLS array is equal to the number of modules that contain TLS data. At load time (i.e. in the
finalizemethod), each module is assigned an index into the TLS array. The address of this module’s TLS data area is then stored at this location in the array.TLS data area
The TLS data area directly follows the TLS array and contains the actual TLS data for each module. In memory it is laid out as follows:
+----------+-----------+----------+-----------+-----+ | TLS data | zero fill | TLS data | zero fill | ... | +----------+-----------+----------+-----------+-----+ | module a | module b | ... | +---------------------------------------------------+
The size of each module’s TLS data area is variable and can be found in the module’s
tls_data_sizeproperty. The same applies to the zero fill. At load time (i.e in thefinalizemethod), the initial TLS data values are copied into the TLS data area. Because a TLS index is also assigned to each module, we can access a module’s TLS data area using this index into the TLS array to get the start address of the TLS data.- __init__(thread_manager: cle.backends.tls.pe_tls.PEThreadManager)[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
thread_manager (PEThreadManager) –
- get_tls_data_addr(tls_idx)[source]#
Get the start address of a module’s TLS data area via the module’s TLS index.
From the PE/COFF spec:
The code uses the TLS index and the TLS array location (multiplying the index by the word size and using it as an offset into the array) to get the address of the TLS data area for the given program and module.
- property max_addr#
This returns the highest virtual address contained in any loaded segment of the binary.
- property thread_pointer#
- property user_thread_pointer#
- classmethod check_compatibility(spec, obj) bool#
Performs a minimal static load of
specand returns whether it’s compatible with other_obj- Return type:
- classmethod check_magic_compatibility(stream: BinaryIO) bool#
Check if a stream of bytes contains the same magic number as the main object
- contains_addr(addr)#
Is addr in one of the binary’s segments/sections we have loaded? (i.e. is it mapped into memory ?)
- property entry#
- static extract_soname(path) str | None#
Extracts the shared object identifier from the path, or returns None if it cannot.
- find_loadable_containing(addr)#
- find_section_containing(addr: int) cle.backends.region.Section | None#
Returns the section that contains addr or
None.
- find_segment_containing(addr: int) cle.backends.region.Segment | None#
Returns the segment that contains addr, or
None.
- get_symbol(name: str) cle.backends.symbol.Symbol | None#
Stub function. Implement to find the symbol with name name.
- property image_base_delta#
- initial_register_values()#
Deprecated
- property initializers: List[int]#
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.
- classmethod is_compatible(stream) bool#
Determine quickly whether this backend can load an object from this stream
- Return type:
- is_default = False#
- property min_addr: int#
This returns the lowest virtual address contained in any loaded segment of the binary.
- rebase(new_base)#
Rebase backend’s regions to the new base where they were mapped by the loader
- relocate()#
Apply all resolved relocations to memory.
The meaning of “resolved relocations” is somewhat subtle - there is a linking step which attempts to resolve each relocation, currently only present in the main internal loading function since the calculation of which objects should be available
- set_arch(arch)#
- property symbols_by_addr#
- thread_registers(thread=None) Dict[str, Any]#
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.
- property threads: List#
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.
- symbols: List[Symbol]#
- imports: typing.Dict[str, 'Relocation']#
- relocs: List[Relocation]#
- child_objects: List['Backend']#
- exception_handlings: List[ExceptionHandling]#
- function_hints: List[FunctionHint]#
- memory: Clemory#
- class cle.backends.tls.elfcore_tls.ELFCoreThreadManager[source]#
Bases:
ThreadManager
- class cle.backends.tls.elfcore_tls.ELFCoreThread[source]#
Bases:
object- __init__(loader, arch: archinfo.arch.Arch, threadinfo)[source]#
- Parameters:
arch (Arch) –
- property dtv#
- class cle.backends.tls.minidump_tls.MinidumpThreadManager[source]#
Bases:
ThreadManager