ida_dscu
Apple Dyld Shared Cache (DSC) API.
A DSC: is essentially, a large collection of dylib files (AKA _images_), packed together in an Apple-custom format those are used to limit the amount of overhead at program launch-time, by having a lot of the relocations/resolutions heavylifting already addressed in addition to _images_, the DSC-producing tooling creates specific regions whose purpose is to “link” the various images together. Those regions are known as “branch mappings” (older caches used “branch islands”.) occasionally, you will also find some GOT’s (and possibly “unknown regions”) in the address space of a DSC DSC’s can grow very large in size, and will then be split into multiple _files_ (e.g., iPhone 16 DSC’s have north of 80 files) All-in-all a DSC is an unusual beast, in the sense that hardly makes sense to load it all in an IDA database: you would end up with a a set of mostly-unrelated libraries. Instead, an iterative approach is preferable: load whatever part of the DSC you need, when you need it. This API provides exactly that. # Key concepts/entities images: the dylib files, packed in the DSC unknown regions: portions of the address space that ARE covered by the DSC’s mappings, but are not referred to by any of the known entities. The address space is not missing - it’s our understanding of the content that has a gap. branch islands/branch mappings: stubs, that help stitch together calls between images files: the file(s) that compose the DSC. When a DSC is composed of multiple files, the one that is used as the entrypoint, is called the “toplevel” file. # Secondary concepts/entities file mappings: (to not be confused with branch mappings!) internal, high-level representation of “portions” of a file. Typically files have somewhere between 1…5 mappings region_info_t: a “range”: either a section of an image, or a branch mapping, GOT, unknown region… Typically, an image will have dozens of regions. See below for more info # API Keeping the above concepts in mind, navigating the API should be pretty straightforward: it’s kept simple on-purpose. A couple notes: Use get_dscu_svc() to retrieve the API interface, Initially, the DSC loader will only load the DSC header, Additional images/regions can be loaded through the API, as needed.
Attributes
Invalid. |
|
A subset of an image (segment, section, ...). |
|
A branch island. |
|
The dyld header. |
|
A subcache branch mapping. |
|
A covered cache region whose content we don't (yet) identify. |
|
A Global Offset Table. |
|
Cache-wide named data (e.g. a linkedit subcache mapping). |
|
failure to satisfy any part of the request, will revert everything |
|
should the request create a new undo point (or rely on the last created one and undo to that.) |
|
don't emit loader_finished notification |
|
ask the user's confirmation before performing the load |
|
default set of flags for DSC load requests |
|
Skip export tables of images that have not been loaded yet. |
|
Match needle case-insensitively. |
|
Limit scanning to images. |
|
Scan entire files. |
|
Scope mask. |
|
When FSSF_SCOPE_IMAGES, limit scanning to data sections. |
|
When FSSF_SCOPE_IMAGES, scan all sections. |
|
Images scope mask. |
|
When scanning files, include the .symbols pool. |
|
When scanning files, include branch mapping files. |
|
When scanning files, include other adjacent files. |
|
Match needle case-insensitively. |
|
Perform match operation despite the CPU architecture of the external file & the DSC not matching. |
|
Perform match operation despite the platform of the external file & the DSC not matching. |
|
Perform validation of persisted layout information. |
|
Do a lot more validating (time-consuming). |
|
Dump the DSC's (toplevel) input path. |
|
Dump some additional details about the toplevel file. |
|
Alias. |
|
Dump information about files composing this DSC. |
|
Dump information about high-level mappings described in files composing this DSC. |
|
Dump information about images (i.e., libraries) found in this DSC. |
|
Dump information about each image's dependencies. |
|
Dump information about each image's known regions. |
|
Dump information about branch islands. |
|
Dump information about each branch island's known regions. |
|
Dump information about known GOT's in this DSC. |
|
Dump information about the unknown (covered but unidentified) regions of this DSC. |
|
Dump information about known cache-wide data regions. |
|
Classes
Functions
|
Retrieve the "shared cache services". |
Module Contents
- class ida_dscu.symbol_match_vec_t(*args)
Bases:
object- thisown
- push_back(*args) symbol_match_t &
- swap(r: symbol_match_vec_t) None
- extract() symbol_match_t *
- inject(s: symbol_match_t, len: int) None
- begin(*args) qvector< symbol_match_t >::const_iterator
- end(*args) qvector< symbol_match_t >::const_iterator
- insert(it: symbol_match_t, x: symbol_match_t) qvector< symbol_match_t >::iterator
- erase(*args) qvector< symbol_match_t >::iterator
- find(*args) qvector< symbol_match_t >::const_iterator
- has(x: symbol_match_t) bool
- add_unique(x: symbol_match_t) bool
- append(x: symbol_match_t) None
- extend(x: symbol_match_vec_t) None
- front
- back
- class ida_dscu.string_match_vec_t(*args)
Bases:
object- thisown
- push_back(*args) string_match_t &
- swap(r: string_match_vec_t) None
- extract() string_match_t *
- inject(s: string_match_t, len: int) None
- begin(*args) qvector< string_match_t >::const_iterator
- end(*args) qvector< string_match_t >::const_iterator
- insert(it: string_match_t, x: string_match_t) qvector< string_match_t >::iterator
- erase(*args) qvector< string_match_t >::iterator
- find(*args) qvector< string_match_t >::const_iterator
- has(x: string_match_t) bool
- add_unique(x: string_match_t) bool
- append(x: string_match_t) None
- extend(x: string_match_vec_t) None
- front
- back
- class ida_dscu.region_info_vec_t(*args)
Bases:
object- thisown
- push_back(*args) region_info_t &
- swap(r: region_info_vec_t) None
- extract() region_info_t *
- inject(s: region_info_t, len: int) None
- begin(*args) qvector< region_info_t >::const_iterator
- end(*args) qvector< region_info_t >::const_iterator
- insert(it: region_info_t, x: region_info_t) qvector< region_info_t >::iterator
- erase(*args) qvector< region_info_t >::iterator
- find(*args) qvector< region_info_t >::const_iterator
- has(x: region_info_t) bool
- add_unique(x: region_info_t) bool
- append(x: region_info_t) None
- extend(x: region_info_vec_t) None
- front
- back
- class ida_dscu.mapping_coords_vec_t(*args)
Bases:
object- thisown
- push_back(*args) mapping_coords_t &
- swap(r: mapping_coords_vec_t) None
- extract() mapping_coords_t *
- inject(s: mapping_coords_t, len: int) None
- begin(*args) qvector< mapping_coords_t >::const_iterator
- end(*args) qvector< mapping_coords_t >::const_iterator
- insert(it: mapping_coords_t, x: mapping_coords_t) qvector< mapping_coords_t >::iterator
- erase(*args) qvector< mapping_coords_t >::iterator
- find(*args) qvector< mapping_coords_t >::const_iterator
- has(x: mapping_coords_t) bool
- add_unique(x: mapping_coords_t) bool
- append(x: mapping_coords_t) None
- extend(x: mapping_coords_vec_t) None
- front
- back
- class ida_dscu.dependency_match_entry_vec_t(*args)
Bases:
object- thisown
- push_back(*args) dependency_match_entry_t &
- swap(r: dependency_match_entry_vec_t) None
- extract() dependency_match_entry_t *
- inject(s: dependency_match_entry_t, len: int) None
- begin(*args) qvector< dependency_match_entry_t >::const_iterator
- end(*args) qvector< dependency_match_entry_t >::const_iterator
- insert(it: dependency_match_entry_t, x: dependency_match_entry_t) qvector< dependency_match_entry_t >::iterator
- erase(*args) qvector< dependency_match_entry_t >::iterator
- find(*args) qvector< dependency_match_entry_t >::const_iterator
- has(x: dependency_match_entry_t) bool
- add_unique(x: dependency_match_entry_t) bool
- append(x: dependency_match_entry_t) None
- extend(x: dependency_match_entry_vec_t) None
- front
- back
- ida_dscu.get_dscu_svc() dscu_svc_t *
Retrieve the “shared cache services”. The returned instance is shared, and must not be deleted. Furthermore, the following situations will cause this function to return a nullptr: * we are currently not operating on a shared cache * dscu_bootstrap wasn’t called (by the loader) * an error occurs
- Returns:
the services instance, or nullptr
- ida_dscu.rt_invalid
Invalid.
- ida_dscu.rt_image_entity
A subset of an image (segment, section, …).
- ida_dscu.rt_island
A branch island.
- ida_dscu.rt_header
The dyld header.
- ida_dscu.rt_mapping
A subcache branch mapping.
- ida_dscu.rt_unknown
A covered cache region whose content we don’t (yet) identify.
- ida_dscu.rt_got
A Global Offset Table.
- ida_dscu.rt_cache_data
Cache-wide named data (e.g. a linkedit subcache mapping).
- class ida_dscu.mapping_coords_t
Bases:
object- thisown
- file_index: int16
- mapping_index: int16
the toplevel/subcache to which mapping_index applies. 0 means toplevel file
- static make_invalid() mapping_coords_t
- class ida_dscu.region_info_t
Bases:
object- thisown
- start: ida_idaapi.ea_t
- size: asize_t
Coordinates in address space.
- type: region_type_t
Size in bytes.
- name: char[40]
- swap(r: region_info_t) None
region name (e.g., __text). Not unique
- class ida_dscu.address_info_t
Bases:
object- thisown
- region: region_info_t
Region containing the address (type=rt_invalid if not found).
- mapping: mapping_coords_t
Mapping that backs the address.
- file_offset: uint64
Offset within the on-disk file backing mapping.
- class ida_dscu.dscu_load_request_t(*args)
Bases:
object- thisown
- mappings: eavec_t
branch mappings
- gots: eavec_t
global offset table ranges
- unknown_regions: eavec_t
unknown-region ranges (covered, but unidentified)
- cache_data: eavec_t
cache-wide data ranges (e.g. linkedit subcache mappings)
- add_region(ri: region_info_t) None
- add_regions(ris: region_info_vec_t) None
- ida_dscu.DLRF_UNDO_ON_FAILURE
failure to satisfy any part of the request, will revert everything
- ida_dscu.DLRF_CREATE_UNDO_POINT
should the request create a new undo point (or rely on the last created one and undo to that.)
- ida_dscu.DLRF_SILENT
don’t emit loader_finished notification
- ida_dscu.DLRF_ASK_CONFIRMATION
ask the user’s confirmation before performing the load
- ida_dscu.DLRF_DEFAULT
default set of flags for DSC load requests
- class ida_dscu.symbol_match_t
Bases:
object- thisown
- symbol: std::string_view
Matching symbol name; the view is valid for the lifetime of the dscu_svc_t.
- ea: ida_idaapi.ea_t
Address of the symbol.
- class ida_dscu.string_match_t
Bases:
object- thisown
- ea: ida_idaapi.ea_t
Mapped address; BADADDR for non-image hits.
- image_index: int
Owning image index, or -1 if the hit came from a non-image blob (.symbols, branch mappings, other adjacent files).
- file_offset: uint64
Offset within that file (when image_index == -1).
- class ida_dscu.dependency_match_result_t
Bases:
dependency_match_entry_vec_t- thisown
- class ida_dscu.dscu_svc_t(*args, **kwargs)
Bases:
object- thisown
- get_input_file_path() str | None
Retrieve the path to the dyld_shared_cache file on disk.
- Returns:
true on success
- get_dyld_slide() adiff_t
Return the cumulative ASLR slide applied to the cache.
- update_dyld_slide(delta: adiff_t) None
Apply an additional slide delta and reload the cache.
- Parameters:
delta – slide increment (added to the current slide)
- get_mapping_range(mapping: mapping_coords_t) bool
- locate_address(ea: ida_idaapi.ea_t) address_info_t
- get_region(ri: region_info_t, region_index: int, full: bool = True) bool
- get_region_by_ea(ri: region_info_t, ea: ida_idaapi.ea_t, out_region_index: size_t * = None, full: bool = True) bool
- get_image_mapping(*args) mapping_coords_t
- get_image_address(image_index: int) ida_idaapi.ea_t
- get_image_total_size(*args) uint64
- is_mapping_loaded(mapping_addr: ida_idaapi.ea_t) bool
- is_got_loaded(got_addr: ida_idaapi.ea_t) bool
- is_unknown_region_loaded(ea: ida_idaapi.ea_t) bool
- is_cache_data_loaded(cache_data_addr: ida_idaapi.ea_t) bool
- load_regions(regions: dscu_load_request_t) bool
- query_symbol(ea: ida_idaapi.ea_t) std::string_view
- query_exported_symbol(ea: ida_idaapi.ea_t) std::string_view
- dmc_ok
- dmc_bad_file
- dmc_cpu_mismatch
- dmc_platform_mismatch
- dmc_failed
- ida_dscu.FSF_LOADED_IMAGES_ONLY
Skip export tables of images that have not been loaded yet.
- ida_dscu.FSF_CASE_INSENSITIVE
Match needle case-insensitively.
- ida_dscu.FSSF_SCOPE_IMAGES
Limit scanning to images.
- ida_dscu.FSSF_SCOPE_FILES
Scan entire files.
- ida_dscu.FSSF_SCOPE_MASK
Scope mask.
- ida_dscu.FSSF_IMAGES_SCOPE_DATA_SECTIONS
When FSSF_SCOPE_IMAGES, limit scanning to data sections.
- ida_dscu.FSSF_IMAGES_SCOPE_ALL
When FSSF_SCOPE_IMAGES, scan all sections.
- ida_dscu.FSSF_IMAGES_SCOPE_MASK
Images scope mask.
- ida_dscu.FSSF_FILES_INCLUDE_SYMBOLS
When scanning files, include the .symbols pool.
- ida_dscu.FSSF_FILES_INCLUDE_BRANCH_MAPPINGS
When scanning files, include branch mapping files.
- ida_dscu.FSSF_FILES_INCLUDE_OTHER
When scanning files, include other adjacent files.
- ida_dscu.FSSF_CASE_INSENSITIVE
Match needle case-insensitively.
- ida_dscu.MDF_ALLOW_CPU_MISMATCH
Perform match operation despite the CPU architecture of the external file & the DSC not matching.
- ida_dscu.MDF_ALLOW_PLATFORM_MISMATCH
Perform match operation despite the platform of the external file & the DSC not matching.
- ida_dscu.DLF_VALIDATE
Perform validation of persisted layout information.
- ida_dscu.DLF_VALIDATE_HARD
Do a lot more validating (time-consuming).
- ida_dscu.DLF_TOPLEVEL_INPUT_PATH
Dump the DSC’s (toplevel) input path.
- ida_dscu.DLF_TOPLEVEL_DETAILS
Dump some additional details about the toplevel file.
- ida_dscu.DLF_TOPLEVEL
Alias.
- ida_dscu.DLF_FILES
Dump information about files composing this DSC.
- ida_dscu.DLF_MAPPINGS
Dump information about high-level mappings described in files composing this DSC.
- ida_dscu.DLF_IMAGES
Dump information about images (i.e., libraries) found in this DSC.
- ida_dscu.DLF_IMAGES_DEPENDENCIES
Dump information about each image’s dependencies.
- ida_dscu.DLF_IMAGES_REGIONS
Dump information about each image’s known regions.
- ida_dscu.DLF_ISLANDS
Dump information about branch islands.
- ida_dscu.DLF_ISLANDS_REGIONS
Dump information about each branch island’s known regions.
- ida_dscu.DLF_GOTS
Dump information about known GOT’s in this DSC.
- ida_dscu.DLF_UNKNOWN_REGIONS
Dump information about the unknown (covered but unidentified) regions of this DSC.
- ida_dscu.DLF_CACHE_DATA
Dump information about known cache-wide data regions.
- ida_dscu.DLF_ALL