Skip to content

macho ¤

Classes:

Functions:

Attributes:

  • T

T module-attribute ¤

T = TypeVar('T')

Trie ¤

Trie(ptr: int, ty: Callable[[int, int], T])

Bases: _RawTrie, Generic[T]

Prefix Tree

The Mach-O format makes extensive use of prefix trees for any operation that involves string-based loookup.

Methods:

  • get

    Get the data associated with the node of given name, if it exists.

  • entries

    List all the entries in the trie, along with their associated data.

  • keys

    List the name of all nodes in the trie.

get ¤

get(name: bytes) -> T | None

Get the data associated with the node of given name, if it exists.

entries ¤

entries() -> Generator[tuple[bytes, T]]

List all the entries in the trie, along with their associated data.

keys ¤

keys() -> Generator[bytes]

List the name of all nodes in the trie.

DyldSharedCacheMapping ¤

DyldSharedCacheMapping(
    addr: int, size: int, file_offset: int, max_prot: int, init_prot: int
)

Attributes:

addr instance-attribute ¤

addr = addr

size instance-attribute ¤

size = size

file_offset instance-attribute ¤

file_offset = file_offset

max_prot instance-attribute ¤

max_prot = max_prot

init_prot instance-attribute ¤

init_prot = init_prot

DyldSharedCacheHashSet ¤

DyldSharedCacheHashSet(ptr: int)

A hash set from the DyLD Shared Cache.

The DyLD Shared Cache uses hash sets in all structures related to Objective-C Optimization. This class is an interface to them.

Methods:

  • lookup

    Look up the given key in the hash set.

  • keys

    Returns an iterator over all the keys present in the hash set.

Attributes:

capacity instance-attribute ¤

capacity = u32(_ptr + 4)

shift instance-attribute ¤

shift = u32(_ptr + 12)

mask instance-attribute ¤

mask = u32(_ptr + 16)

salt instance-attribute ¤

salt = u64(_ptr + 24)

lookup ¤

lookup(key: bytes) -> int | None

Look up the given key in the hash set.

Returns a pointer to the key if it is present, None otherwise.

keys ¤

keys() -> Generator[bytes]

Returns an iterator over all the keys present in the hash set.

DyldSharedCache ¤

DyldSharedCache(addr: int)

Handle to the DyLD Shared Cache in the address space of the inferior.

The shared cache format handling code in libmacho has multiple paths for gathering the same information, depending on a value that is near the beggining of the header, which indicates that the format has likely evolved quite a bit since its first intoduction.

The way the version of a given shared cache is determined isn't exactly straighforward, and relies on a combination of the magic and mappingOffset values. Fortunately for us, however, when mappingOffset is used for this purpose, it follows the fairly widely used pattern of using the size of the struct to denote its version.

Methods:

Attributes:

  • addr
  • slide (int) –

    The slide value of the DyLD Shared Cache, in bytes.

  • image_count
  • base (int) –

    The base virtual address of the DyLD Shared Cache.

  • size (int) –

    The mapped size, in bytes, of the DyLD Shared Cache.

  • image_index_trie (Trie[int] | None) –

    The trie of image indices, if available.

  • images (Generator[tuple[bytes, int]]) –
  • images_sorted (Generator[tuple[bytes, int]]) –

    Same as images, but guaranteed to be sorted by increasing base address

addr instance-attribute ¤

addr = addr

slide instance-attribute ¤

slide: int = _slide()

The slide value of the DyLD Shared Cache, in bytes.

image_count instance-attribute ¤

image_count = u32(addr + images_offset + 4)

base property ¤

base: int

The base virtual address of the DyLD Shared Cache.

size property ¤

size: int

The mapped size, in bytes, of the DyLD Shared Cache.

image_index_trie property ¤

image_index_trie: Trie[int] | None

The trie of image indices, if available.

images property ¤

images: Generator[tuple[bytes, int]]

images_sorted property ¤

images_sorted: Generator[tuple[bytes, int]]

Same as images, but guaranteed to be sorted by increasing base address

mappings ¤

mappings() -> Generator[DyldSharedCacheMapping]

Generate the list of memory mappings in the shared cache.

image_base ¤

image_base(index: int)

image_name ¤

image_name(index: int)

is_address_in_shared_cache ¤

is_address_in_shared_cache(addr: int) -> int

Whether the given address is in the shared cache.

objc_builtin_selectors ¤

objc_builtin_selectors() -> DyldSharedCacheHashSet

Looks up the hash table of builtin Objective-C selectors and returns it.

shared_cache ¤

shared_cache() -> DyldSharedCache | None

Base address of the Darwin shared cache.

In Darwin, the way the Objective-C Runtime queries for this value is to call _dyld_get_shared_cache_range from libdyld1, which then calls a routine that lives inside dyld itself, and that returns the values after poking into internal C++ structures.

From our perspective, that kind of sucks. Calling routines from debuggers can be quite unreliable, and so ideally we'd always be peeking into the data structures directly. But, in this case, even for Apple these are considered entirely private to dyld2, and so there's even less of a stability guarantee for the layout of these structures than normal.

Because of this, a level of care must be taken before calling this function, as it must be assumed that the state of the inferior can be changed by it.