To understand this API, I encourage developers to first read the documentation for MSHookMessageEx. The goal of this API is to allow multiple methods to be hooked at a single time using high-level declarative Objective-C syntax (one compatible with existing syntax highlighers).

Similar to other Substrate APIs, this function takes a target, a replacement implementation, and somewhere to store a pointer to the original implementation. Rather than working with a single method or function, this API works on all of the methods of an Objective-C class at once.

Each method declared on the replacement "hook" class will be used to instrument methods on a target class being hooked. The stub function that is normally generated to call the original implementation is then added as a method on a third class, which is used as storage for the old interface.

This API was designed around a use case where the "old" class, the one storing stubs to call the original implementations, is a superclass of the hook class, the one with the new replacement implementations. This allows the usage of Objective-C's super keyword for original calls.

Note: Generally, this API will not be called directly: instead, the macro MSHookInterface is used to setup all of the required classes.

void MSHookClassPair(Class _class, Class hook, Class old);
Parameter Description
_class Objective-C class interface to be instrumented. (Unlike with MSHookMessageEx, this must not be a meta-class.)
hook Objective-C class interface which directly implements replacements for messages (potentially class or instance messages) defined on the instrumented class.
old Objective-C class interface which will be filled in with stubs that may be used to call the original implementations of messages hooked on the instrumented interface. This can be nil if you do not proceed to the original. This class will normally be a super class of the hook target.
@interface HookOld : NSObject
@end

@implementation HookOld
@end

@interface HookNew : NSObject
@end

@implementation HookNew
- (NSString *) description {
    IMP old = class_getMethodImplementation(
        [HookOld class], _cmd);
    NSString *description;
    description = ((NSString *(*)(id, SEL)) old)(self, _cmd);
    description = [description stringByAppendingString:@"!"];
    return description;
}
@end

MSHookClassPair([NSObject class],
    [HookNew class], [HookOld class]);