Installation Path

Substrate extensions are compiled to dynamic libraries (using the extension .dylib) and are placed in the Substrate Dynamic Libraries folder.

/Library/MobileSubstrate/DynamicLibraries

Property Lists

Configuration for the extension is provided using Cocoa "property lists", a serialization format for common Objective-C data structures (dictionaries, arrays, numbers, strings, and data). This is a file with the same name as the .dylib, but with the extension .plist.

Property lists can be stored on disk in one of three formats: XML, binary, or "OpenStep" (a format more similar to encodings such as JSON). For more information on these files and how they are stored, we provide a guide to the various property list formats.

# ls -la /Library/MobileSubstrate/DynamicLibraries
total 48
drwxr-xr-x 2 root wheel   136 Jan 26 16:32 ./
drwxr-xr-x 4 root wheel   238 Jan 26 16:32 ../
-rwxr-xr-x 1 root wheel 33216 Oct 12 20:14 Veency.dylib*
-rw-r--r-- 1 root wheel    49 Sep 11 02:41 Veency.plist

# cd /Library/MobileSubstrate/DynamicLibraries
# cat Veency.plist 
Filter = {Bundles = ("com.apple.springboard");};

Configuration Structure

At the top-level of the configuration property list is a dictionary with a single key, Filter, the value of which is itself a dictionary.

Under this key are a number of different ways to limit the scope of your extension, each of which will be documented below.

Filter "Mode"

When Substrate first gained multiple forms of filters, these filters were implemented in a manner that required each present filter type to match at least once for the extension to match as a whole. In hindsight, this was a serious mistake, and has caused many issues. A new key was therefore added to the filter configuration called Mode that should be set to the string Any to fix this behavior. Simple extensions that use a single form of filter will not be affected.

Standard Filters

Most uses of Substrate come down to a need to modify the code of a specific library or set of classes. The configuration system therefore provides a way to specify the set of such injection targets.

This is done using a set of arrays that are linked under the Filter key, each of which considers to "match" if any one of the elements in that set matches.

As an example, if your extension modifies the code of UIKit (the standard iOS library dealing with graphics and interface) and the background "launch services" daemon (used to lookup applications and load icons), you would use the "Any" Mode and two filters: Bundles (to match UIKit) and Executables (to match "lsd").

Key Example Description
Bundles com.apple.UIKit Apple often uses "bundles" (typically a reversed-hostname identifier) to organize their projects. These bundle identifiers are the most stable way to reference a specific library or process, and are recommended to be used whenever possible.
Classes MMTrackingMgr Sometimes, you will need to hook an Objective-C class that exists in many projects, but is always statically linked. This is quite common with advertisement frameworks on iOS, due to Apple's restrictions on dynamic code deployment.
Executables mediaserverd Many daemons do not have an associated bundle: they are instead fairly simple Unix processes that might not use any of Apple's higher-level APIs. These can be matched using the last component of the pathname of their executable image.

Filtering on OS Version

An additional filter that is often requested is "this only works on iOS 3.x". Substrate exposes functionality similar to this through a CoreFoundationVersion filter.

This value is checked using kCFCoreFoundationVersionNumber, and the values are described in Apple's CFBase.h in the form kCFCoreFoundationVersionNumber_iPhoneOS_3_0.

The contents of this filter is an array containing either one or two numbers; the first being the "lower bound" and the latter being the "upper bound". The upper bound is optional.

Note: As the OpenStep property list format does not support storing numbers, to use this feature you must store your property list using the XML (discouraged) or binary (recommended) format.

<key>CoreFoundationVersion</key>
<array>
    <real>478.47</real>
    <real>550.32</real>
</array>
iOS CFVersion
2.0 478.23
2.1 478.26
2.2 478.29
iOS CFVersion
3.0 478.47
3.1 478.52
3.2 478.61
iOS CFVersion
4.0 550.32
4.1 550.38
4.2 550.52
4.3 550.58
iOS CFVersion
5.0 675.00
5.1 690.10
iOS CFVersion
6.x 793.00
iOS CFVersion
7.0 847.20
7.1 847.24
iOS CFVersion
8.0 1140.10
8.1 1141.14
8.2 1142.16
8.3 1144.17
8.4 1145.15
iOS CFVersion
9.0 1240.10
9.1 1241.11
9.2 1242.13
9.3 1280.38
9.3.2+ 1290.11
iOS CFVersion
10.0b1 1333.20
10.[01] 1348.00
10.2 1348.22