For the complete documentation index, see llms.txt. This page is also available as Markdown.

Dyld Shared Cache

This page walks through how IDA 9.4 lets you analyse a Dyld Shared Cache: opening one, navigating its contents from the DSC Index, loading the bits you actually care about, and locating things across the cache without having to load everything first.

Opening a DSC

When IDA loads a Dyld Shared Cache, the loader's only job is to map the cache header into the database and prepare the internal data structures needed to navigate the cache. Every image, branch mapping, GOT and gap is left for the user to load on demand, through the workflow described below.

DSC open dialog
The initial DSC open dialog

The DSC Index

The DSC Index is the entry point to everything else. It is a tree showing every region of the cache (images, branch islands, branch mappings, GOTs, gaps) along with their sizes, addresses, and whether they're currently loaded.

DSC Index widget, all regions collapsed
The DSC Index widget, top-level kinds visible

If you ever close the panel, reopen it through the Dyld Shared Cache (DSC) index action under View > Open subviews.

Region kinds

  • Images — the actual dylibs and frameworks. By far the most interesting set of regions in the cache, and typically what reversers will look at first.

  • Branch islands — trampolines for long branches. They are an artefact of older caches; recent caches don't use them, so you will likely never encounter any (the screenshot above shows none for that very reason).

  • Branch mappings__stubs shared between subcaches. The modern equivalent of branch islands: just trampolines, vastly uninteresting to a reverser. IDA may need to auto-load some of them to satisfy an image's dependencies, so don't be surprised to see branch mappings get loaded without you explicitly asking.

  • GOTs — global offset tables (iOS 16+ on arm64). Mostly pointers and jumps, mostly uninteresting; like branch mappings, may be auto-loaded as needed.

  • Gaps — regions the DSC loader couldn't classify when it scanned the cache.

Once expanded, every region carries its address, size, and loaded state:

DSC Index widget, expanded with addresses and sizes
The DSC Index with /usr/lib/system expanded; libxpc.dylib loaded

On-demand loading

The whole workflow is built on the assumption that any address may or may not be backed by loaded bytes at any given moment. Cross-references to unmapped addresses do not break, decompilation does not abort, and the user is free to load more whenever they want. Several entry points trigger a load:

  • the DSC Index context menu (described in Loading images below);

  • in-listing prompts — when navigating the disassembly, unmapped targets are decorated with a marker. Double-clicking, or pressing Enter on, such a span prompts to load the target image.

In-listing arrow (disassembly)
The "⇗" marker in disassembly, on a pointer targeting an unmapped library

The same arrow appears in the decompiler — here on a thunk whose only purpose is to call a routine in another (still-unmapped) image:

In-listing arrow (decompiler)
The "↗" marker in the decompiler, on a thunk to an unmapped library

The purpose, throughout, is to give the user a hook (a double-click, an Enter key) and have IDA offer to load whatever needs to be loaded, seamlessly.

Loading images

The DSC Index context menu offers three actions to load regions:

  • Selected modules — load whatever is selected, as-is.

  • Selection with dependencies... — load the selection plus its dependencies, with a dialog to control depth and per-dependency inclusion.

  • From external Mach-O... — match the load commands of an off-cache Mach-O against this DSC and load the matching dependencies. See the action page for the full walkthrough.

In addition to the in-listing prompts mentioned in On-demand loading, the normal navigation actions of the disassembly and the decompiler may invite the user to load further images as needed.

Load with dependencies dialog
The dependencies picker dialog

Double-clicking and reload prompts

Double-clicking a region in the DSC Index jumps to its start address; if the region is not yet loaded, a confirmation dialog asks whether to load it first.

If you ask to load something that is already loaded, IDA prompts with <region> is already loaded. Do you want to load it again? (default: No).

Locating important information

Depending on the user's workflow, you may need to look up a symbol or a string literal coming from a log, a stack trace, an external tool. IDA provides three locator actions for that, all under the DSC Index context menu, all working across the entire cache without loading anything first:

  • Symbol — substring search across the cache's local symbol table and per-image export tables.

  • String — substring search across the cache's bytes, scoped to images or full files.

  • Region by address — given an address, highlight the matching region in the index.

The two substring locators work the same way: choosing the action first opens a query prompt (with a history of past queries and a collapsible Options group); confirming opens the DSC symbols / DSC strings results panel. The panel keeps the same query field and Options, so further searches can be refined in place — press Enter or click the Search button. The two prompts and panels look near-identical; the DSC strings prompt and panel below illustrate both. See each action page for the result tree's specifics.

DSC strings query prompt
The query prompt, with the Options group expanded
DSC strings panel
The DSC strings panel after a search

Scripting (dscu_svc_t API)

The entire DSC workflow is driven by a public C++ service, dscu_svc_t, exposed through the <dscu.h> SDK header and the ida_dscu Python module. The same calls the UI makes are available to scripts and plugins: enumerate regions, query symbols, find strings, load images.

A worked IDAPython example shipping with IDA — dscu_query.py (under python/examples/disassembler/) — touches the main highlights: cache layout, image lookup, dependency walk, symbol search, string search.

Last updated

Was this helpful?