LavenderExample Objective-C

To demonstrate how to use Substrate to build an extension, we will now walk through the implementation of a concrete example: an extension that modifies the color of numerous interface components to become shades of lavender. This extension is useless, but has the advantage of being immediately noticeable.

This example uses MSHookInterface, an Objective-C interface to Substrate's hook functionality. More complicated hooks would instead use either Logos (a popular preprocessor) or Substrate's runtime API.

Step 1: Filter Configuration

The code for UIColor is in a library called UIKit, which has the bundle identifier com.apple.UIKit.

See Also:

Code Deployment: iOS / Darwin
Property Lists

Filter = {
    Bundles = ("com.apple.UIKit");
};
$ plutil -convert binary1 LavenderExample.plist

Step 2: Modify Implementation

The implementation of the method is replaced in a manner similar to using an Objective-C category, only "super" has been mapped to allow the new code to call the previous implementation.

The first argument to the MSHookInterface macro is the name of the class we are hooking, and the second is the (unique) name of our new interface.

The third argument is the subclass base for "self", which allows us to get better warnings from the compiler. In this case we are able to use UIColor.

Finally, we call through to the original and modify the result, removing all green from the color and jacking up the red (yielding shades of lavender).

See Also:

C API: MSHookInterface

#include <CydiaSubstrate/CydiaSubstrate.h>

MSHookInterface(UIColor, LavenderHookUIColor, UIColor)

@implementation LavenderHookUIColor

- (id) initWithRed:(CGFloat)red
             green:(CGFloat)green
              blue:(CGFloat)blue
             alpha:(CGFloat)alpha
{
    return [super initWithRed:1 green:0 blue:blue alpha:alpha];
}

@end