Mach-O¶
- class cle.backends.macho.macho.MachO[source]¶
Bases:
Backend
Mach-O binaries for CLE¶
The Mach-O format is notably different from other formats. Specifically:
Sections are always part of a segment, so self.sections will be empty.
Symbols cannot be categorized like in ELF.
Symbol resolution must be handled by the binary.
Rebasing in dyld is implemented by adding a small slide to addresses inside the binary, instead of changing the base address of the binary. Consequently, the addresses are absolute rather than relative. CLE requires relative addresses, leading to numerous AT.from_lva().to_rva() calls in this backend.
- is_default = True¶
- MH_MAGIC_64 = 4277009103¶
- MH_CIGAM_64 = 3489328638¶
- MH_MAGIC = 4277009102¶
- MH_CIGAM = 3472551422¶
- __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
- ncmds: int¶
- sizeofcmds: int¶
- property min_addr¶
This returns the lowest virtual address contained in any loaded segment of the binary.
- classmethod check_compatibility(spec, obj)[source]¶
Performs a minimal static load of
spec
and returns whether it’s compatible with other_obj
- classmethod is_compatible(stream)[source]¶
Determine quickly whether this backend can load an object from this stream
- is_thumb_interworking(address)[source]¶
Returns true if the given address is a THUMB interworking address
- parse_lc_str(f, start, limit: int | None = None)[source]¶
Parses a lc_str data structure
- Parameters:
limit (int | None)
- S = ~S¶
- get_symbol_by_address_fuzzy(address)[source]¶
Locates a symbol by checking the given address against sym.addr, sym.bind_xrefs and sym.symbol_stubs
- get_symbol(name, include_stab=False, fuzzy=False)[source]¶
Returns all symbols matching name.
Note that especially when include_stab=True there may be multiple symbols with the same name, therefore this method always returns an array.
- Parameters:
name – the name of the symbol
include_stab – Include debugging symbols NOT RECOMMENDED
fuzzy – Replace exact match with “contains”-style match
- get_symbol_by_insertion_order(idx: int) AbstractMachOSymbol [source]¶
- Parameters:
idx (
int
) – idx when this symbol was inserted- Return type:
- Returns:
- class cle.backends.macho.macho.SymbolList[source]¶
Bases:
SortedKeyList
Special data structure that extends SortedKeyList to allow looking up a MachO library by name and ordinal quickly without having to iterate over the whole list
- __init__(**kwargs)[source]¶
Initialize sorted-key list instance.
Optional iterable argument provides an initial iterable of values to initialize the sorted-key list.
Optional key argument defines a callable that, like the key argument to Python’s sorted function, extracts a comparison key from each value. The default is the identity function.
Runtime complexity: O(n*log(n))
>>> from operator import neg >>> skl = SortedKeyList(key=neg) >>> skl SortedKeyList([], key=<built-in function neg>) >>> skl = SortedKeyList([3, 1, 2], key=neg) >>> skl SortedKeyList([3, 2, 1], key=<built-in function neg>)
- Parameters:
iterable – initial values (optional)
key – function used to extract comparison key (optional)
- add(value: AbstractMachOSymbol)[source]¶
Add value to sorted-key list.
Runtime complexity: O(log(n)) – approximate.
>>> from operator import neg >>> skl = SortedKeyList(key=neg) >>> skl.add(3) >>> skl.add(1) >>> skl.add(2) >>> skl SortedKeyList([3, 2, 1], key=<built-in function neg>)
- Parameters:
value (
AbstractMachOSymbol
) – value to add to sorted-key list
- class cle.backends.macho.symbol.AbstractMachOSymbol[source]¶
Bases:
Symbol
Base class for Mach-O symbols. Defines the minimum common properties all types of mach-o symbols must have
- __init__(owner: Backend, name: str, relative_addr: int, size: int, sym_type: SymbolType)[source]¶
Not documenting this since if you try calling it, you’re wrong.
- Parameters:
owner (Backend)
name (str)
relative_addr (int)
size (int)
sym_type (SymbolType)
- property library_ordinal¶
- property is_stab¶
- class cle.backends.macho.symbol.SymbolTableSymbol[source]¶
Bases:
AbstractMachOSymbol
“Regular” symbol. Made to be (somewhat) compatible with backends.Symbol. A SymbolTableSymbol is an entry in the binary’s symbol table.
Note that ELF-specific fields from backends.Symbol are not used and semantics of the remaining fields differ in many cases. As a result most stock functionality from Angr and related libraries WILL NOT WORK PROPERLY on MachOSymbol.
Much of the code below is based on heuristics as official documentation is sparse, consider yourself warned!
The relevant struct with documentation is nlist_64 defined in mach-o/nlist.h
- __init__(owner: MachO, symtab_offset, n_strx, n_type, n_sect, n_desc, n_value)[source]¶
Not documenting this since if you try calling it, you’re wrong.
- Parameters:
owner (MachO)
- property segment_name¶
- property section_name¶
- property value¶
- property referenced_symbol_index¶
For indirect symbols n_value contains an index into the string table indicating the referenced symbol’s name
- is_weak()[source]¶
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
- property is_function¶
Whether this symbol is a function
- property is_stab¶
- property is_private_external¶
- property is_external¶
- property sym_type¶
- property is_common¶
bool(x) -> bool
Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
- property common_align¶
- property reference_type¶
- property library_ordinal¶
- property is_no_dead_strip¶
- property is_desc_discarded¶
- property is_weak_referenced¶
- property is_weak_defined¶
- property is_reference_to_weak¶
- property is_thumb_definition¶
- property is_symbol_resolver¶
- property is_alt_entry¶
- class cle.backends.macho.symbol.DyldBoundSymbol[source]¶
Bases:
AbstractMachOSymbol
The new kind of symbol handling introduced with ios15
- property library_name¶
- property is_function¶
Whether this symbol is a function
- property library_ordinal¶
- class cle.backends.macho.symbol.BindingSymbol[source]¶
Bases:
AbstractMachOSymbol
“Binding” symbol. Made to be (somewhat) compatible with backends.Symbol. A BindingSymbol is an imported symbol discovered during the binding process.
Note that ELF-specific fields from backends.Symbol are not used and semantics of the remaining fields differ in many cases. As a result most stock functionality from Angr and related libraries WILL NOT WORK PROPERLY on MachOSymbol.
Much of the code below is based on heuristics as official documentation is sparse, consider yourself warned!
- __init__(owner, name, lib_ordinal)[source]¶
Not documenting this since if you try calling it, you’re wrong.
- property library_name¶
- property is_function¶
Whether this symbol is a function
- property library_ordinal¶
- class cle.backends.macho.section.MachOSection[source]¶
Bases:
Section
Mach-O Section, only defined within the context of a Mach-O Segment.
offset is the offset into the file the region starts
vaddr (or just addr) is the virtual address
filesize (or just size) is the size of the region in the file
memsize (or vsize) is the size of the region when loaded into memory
segname is the corresponding segment’s name without padding
sectname is the section’s name without padding
align is the sections alignment as a power of 2
reloff is the file offset to the section’s relocation entries
nreloc is the number of relocation entries for this section
flags is a bit vector containing per-section flags
r1 and r2 are values for the reserved1 and reserved2 fields respectively
- __init__(offset, vaddr, size, vsize, segname, sectname, align, reloff, nreloc, flags, r1, r2, parent_segment: MachOSegment | None = None)[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
parent_segment (MachOSegment | None)
- property type¶
- property attributes¶
- property is_readable¶
Always true, because sections should always be readable :return:
- property is_writable¶
Returns the permission of the parent segment, because MachO sections simply inherit that :return:
- property is_executable¶
Returns the permission of the parent segment, because MachO sections simply inherit that :return:
- property only_contains_uninitialized_data¶
I actually don’t know if this is true, but it seems like a saner assumption than true :return:
- class cle.backends.macho.segment.MachOSegment[source]¶
Bases:
Segment
Mach-O Segment
offset is the offset into the file the region starts
vaddr (or just addr) is the virtual address
filesize (or just size) is the size of the region in the file
memsize (or vsize) is the size of the region when loaded into memory
segname is the segment’s name without padding
nsect is the number of sections contained in this segment
sections is an array of MachOSections
flags is a bit vector containing per-segment flags
initprot and maxprot are initial and maximum permissions respectively
- get_section_by_name(name)[source]¶
Searches for a section by name within this segment :type name: :param name: Name of the section :return: MachOSection or None
- property is_readable¶
- property is_writable¶
- property is_executable¶
- cle.backends.macho.binding.read_uleb(blob: bytes, offset: int) tuple[int, int] [source]¶
Reads a number encoded as uleb128
- class cle.backends.macho.binding.BindingState[source]¶
Bases:
object
State object
- class cle.backends.macho.binding.BindingHelper[source]¶
Bases:
object
Factors out binding logic from MachO. Intended to work in close conjunction with MachO not for standalone use
- do_normal_bind(blob: bytes)[source]¶
Performs non-lazy, non-weak bindings :type blob:
bytes
:param blob: Blob containing binding opcodes- Parameters:
blob (bytes)
- do_rebases(blob: bytes)[source]¶
Handles the rebase blob Implementation based closely on ImageLoaderMachOCompressed::rebase from dyld https://github.com/apple-opensource/dyld/blob/e3f88907bebb8421f50f0943595f6874de70ebe0/src/ImageLoaderMachOCompressed.cpp#L382-L463
- Parameters:
blob (
bytes
)- Returns:
- cle.backends.macho.binding.n_opcode_done(s: BindingState, _b: MachO, _i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
_i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_set_dylib_ordinal_imm(s: BindingState, _b: MachO, i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_set_dylib_ordinal_uleb(s: BindingState, _b: MachO, _i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
_i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_set_dylib_special_imm(s: BindingState, _b: MachO, i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_set_trailing_flags_imm(s: BindingState, _b: MachO, i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_set_type_imm(s: BindingState, _b: MachO, i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_set_addend_sleb(s: BindingState, _b: MachO, _i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
_i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_set_segment_and_offset_uleb(s: BindingState, b: MachO, i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
i (int)
blob (bytes)
- cle.backends.macho.binding.l_opcode_set_segment_and_offset_uleb(s: BindingState, b: MachO, i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_add_addr_uleb(s: BindingState, _b: MachO, _i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
_b (MachO)
_i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_do_bind(s: BindingState, b: MachO, _i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
_i (int)
_blob (bytes)
- cle.backends.macho.binding.l_opcode_do_bind(s: BindingState, b: MachO, _i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
_i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_do_bind_add_addr_uleb(s: BindingState, b: MachO, _i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
_i (int)
blob (bytes)
- cle.backends.macho.binding.n_opcode_do_bind_add_addr_imm_scaled(s: BindingState, b: MachO, i: int, _blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
i (int)
_blob (bytes)
- cle.backends.macho.binding.n_opcode_do_bind_uleb_times_skipping_uleb(s: BindingState, b: MachO, _i: int, blob: bytes) BindingState [source]¶
- Return type:
- Parameters:
s (BindingState)
b (MachO)
_i (int)
blob (bytes)
- class cle.backends.macho.binding.MachOSymbolRelocation[source]¶
Bases:
Relocation
Generic Relocation for MachO. It handles relocations that point to symbols
- __init__(owner: MachO, symbol: AbstractMachOSymbol, relative_addr: int, data)[source]¶
- Parameters:
owner (MachO)
symbol (AbstractMachOSymbol)
relative_addr (int)
- property dest_addr¶
- property value¶
- class cle.backends.macho.binding.MachOPointerRelocation[source]¶
Bases:
Relocation
A relocation for a pointer without any associated symbol These are either generated while handling the rebase blob, or while parsing chained fixups
- property value¶
- cle.backends.macho.binding.default_binding_handler(state: BindingState, binary: MachO)[source]¶
Binds location to the symbol with the given name and library ordinal
- Parameters:
state (BindingState)
binary (MachO)
- class cle.backends.macho.structs.HelperStruct[source]¶
Bases:
Structure
Subclass of ctypes.Structure that adds a helpful repr method for debugging
- class cle.backends.macho.structs.DyldImportFormats[source]¶
Bases:
IntEnum
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L249-L254
- DYLD_CHAINED_IMPORT = 1¶
- DYLD_CHAINED_IMPORT_ADDEND = 2¶
- DYLD_CHAINED_IMPORT_ADDEND64 = 3¶
- __new__(value)¶
- class cle.backends.macho.structs.DyldChainedPtrFormats[source]¶
Bases:
IntEnum
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L89-L104
- DYLD_CHAINED_PTR_ARM64E = 1¶
- DYLD_CHAINED_PTR_64 = 2¶
- DYLD_CHAINED_PTR_32 = 3¶
- DYLD_CHAINED_PTR_32_CACHE = 4¶
- DYLD_CHAINED_PTR_32_FIRMWARE = 5¶
- DYLD_CHAINED_PTR_64_OFFSET = 6¶
- DYLD_CHAINED_PTR_ARM64E_KERNEL = 7¶
- DYLD_CHAINED_PTR_64_KERNEL_CACHE = 8¶
- DYLD_CHAINED_PTR_ARM64E_USERLAND = 9¶
- DYLD_CHAINED_PTR_ARM64E_FIRMWARE = 10¶
- DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE = 11¶
- DYLD_CHAINED_PTR_ARM64E_USERLAND24 = 12¶
- __new__(value)¶
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_auth_rebase[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L128-L138
- addrDiv¶
Structure/Union member
- auth¶
Structure/Union member
- bind¶
Structure/Union member
- diversity¶
Structure/Union member
- key¶
Structure/Union member
- next¶
Structure/Union member
- target¶
Structure/Union member
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_auth_bind[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L140-L151
- addrDiv¶
Structure/Union member
- auth¶
Structure/Union member
- bind¶
Structure/Union member
- diversity¶
Structure/Union member
- key¶
Structure/Union member
- next¶
Structure/Union member
- ordinal¶
Structure/Union member
- zero¶
Structure/Union member
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_rebase[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L107-L115
- auth¶
Structure/Union member
- bind¶
Structure/Union member
- high8¶
Structure/Union member
- next¶
Structure/Union member
- target¶
Structure/Union member
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_bind[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L117-L126
- addend¶
Structure/Union member
- auth¶
Structure/Union member
- bind¶
Structure/Union member
- next¶
Structure/Union member
- ordinal¶
Structure/Union member
- zero¶
Structure/Union member
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_bind24[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L164-L173
- class cle.backends.macho.structs.dyld_chained_ptr_arm64e_auth_bind24[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L175-L186
- addrDiv¶
Structure/Union member
- auth¶
Structure/Union member
- bind¶
Structure/Union member
- diversity¶
Structure/Union member
- key¶
Structure/Union member
- next¶
Structure/Union member
- ordinal¶
Structure/Union member
- zero¶
Structure/Union member
- class cle.backends.macho.structs.Arm64e[source]¶
Bases:
Union
named after the Union Arm64e from dyld MachOLoaded.h https://github.com/apple-opensource/dyld/blob/852.2/dyld3/MachOLoaded.h#L89-L103
-
authRebase:
dyld_chained_ptr_arm64e_auth_rebase
¶ Structure/Union member
-
authBind:
dyld_chained_ptr_arm64e_auth_bind
¶ Structure/Union member
-
rebase:
dyld_chained_ptr_arm64e_rebase
¶ Structure/Union member
-
bind:
dyld_chained_ptr_arm64e_bind
¶ Structure/Union member
-
bind24:
dyld_chained_ptr_arm64e_bind24
¶ Structure/Union member
-
authBind24:
dyld_chained_ptr_arm64e_auth_bind24
¶ Structure/Union member
- property sign_extended_addend¶
- property unpack_target¶
- static check_valid_pointer_format(pointer_format: DyldChainedPtrFormats) bool [source]¶
helper to check if a pointer format is relevant for this :type pointer_format:
DyldChainedPtrFormats
:param pointer_format: :rtype:bool
:return:- Parameters:
pointer_format (DyldChainedPtrFormats)
- Return type:
-
authRebase:
- class cle.backends.macho.structs.dyld_chained_ptr_64_rebase[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L153-L161
- property unpackedTarget¶
- class cle.backends.macho.structs.dyld_chained_ptr_64_bind[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L189-L197
- class cle.backends.macho.structs.Generic64[source]¶
Bases:
Union
named after the Union Generic64 from dyld MachOLoaded.h https://github.com/apple-opensource/dyld/blob/852.2/dyld3/MachOLoaded.h#L105-L111
-
rebase:
dyld_chained_ptr_64_rebase
¶ Structure/Union member
-
bind:
dyld_chained_ptr_64_bind
¶ Structure/Union member
- static check_valid_pointer_format(pointer_format: DyldChainedPtrFormats) bool [source]¶
- Return type:
- Parameters:
pointer_format (DyldChainedPtrFormats)
-
rebase:
- class cle.backends.macho.structs.ChainedFixupPointerOnDisk[source]¶
Bases:
Union
the ChainedFixupPointerOnDisk union from dyld MachOLoaded.h https://github.com/apple-opensource/dyld/blob/852.2/dyld3/MachOLoaded.h#L87-L141
- isBind(pointer_format: DyldChainedPtrFormats) tuple[int, int] | None [source]¶
Port of ChainedFixupPointerOnDisk::isBind(uint16_t pointerFormat, uint32_t& bindOrdinal, int64_t& addend) https://github.com/apple-opensource/dyld/blob/852.2/dyld3/MachOLoaded.cpp#L1098-L1147 Returns None if not a bind (so if struct.isBind() works), :rtype:
tuple
[int
,int
] |None
:return:- Parameters:
pointer_format (DyldChainedPtrFormats)
- Return type:
- isRebase(pointer_format: DyldChainedPtrFormats, preferredLoadAddress: int) int | None [source]¶
port of ChainedFixupPointerOnDisk::isRebase( uint16_t pointerFormat, uint64_t preferedLoadAddress, uint64_t& targetRuntimeOffset) https://github.com/apple-opensource/dyld/blob/852.2/dyld3/MachOLoaded.cpp#L1046-L1096 :type pointer_format:
DyldChainedPtrFormats
:param pointer_format: :type preferredLoadAddress:int
:param preferredLoadAddress: I think that’s just the requested base address :rtype:int
|None
:return:- Parameters:
pointer_format (DyldChainedPtrFormats)
preferredLoadAddress (int)
- Return type:
int | None
- class cle.backends.macho.structs.DyldImportStruct[source]¶
Bases:
HelperStruct
Meta Struct for the different kind of import structs and the fields they are all guaranteed to have
- static get_struct(pointer: DyldImportFormats) type[DyldImportStruct] [source]¶
- Return type:
- Parameters:
pointer (DyldImportFormats)
- class cle.backends.macho.structs.dyld_chained_import[source]¶
Bases:
DyldImportStruct
Struct for symbol format DYLD_CHAINED_IMPORT
- class cle.backends.macho.structs.dyld_chained_import_addend[source]¶
Bases:
DyldImportStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L264-L271
- class cle.backends.macho.structs.dyld_chained_import_addend64[source]¶
Bases:
DyldImportStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L273-L281
- reserved¶
Structure/Union member
- class cle.backends.macho.structs.dyld_chained_fixups_header[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L36-L46
-
imports_format:
DyldImportFormats
¶ Structure/Union member
-
imports_format:
- class cle.backends.macho.structs.dyld_chained_starts_in_image[source]¶
Bases:
Structure
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L48-L54
-
seg_info_offset:
Array
¶ Structure/Union member
-
seg_info_offset:
- class cle.backends.macho.structs.dyld_chained_starts_in_segment[source]¶
Bases:
HelperStruct
https://github.com/apple-opensource/dyld/blob/852.2/include/mach-o/fixup-chains.h#L56-L72
- property pointer_format: DyldChainedPtrFormats¶