I need to replace some methods’ implementations of specific Objective-C classes. A set of functions from objc/runtime library is capable of doing that. To simplify the issue I just write a simplest sample code as following:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface MyClass : NSObject
- (void) func;
@end
@implementation MyClass
- (void) func {
NSLog(@"Hello from MyClass!");
}
@end
//Original implementation of the method
static IMP gOriginalFunc = nil;
//Hook function that will take place of the original method
void HookFunc(id self, SEL _cmd)
{
NSLog(@"[MyClass func] is hooked!");
gOriginalFunc(self, _cmd);//EXC_BAD_ACCESS occurs here when ARC is enabled!!
}
int main(int argc, char *argv[])
{
Class clsMyClass = objc_getClass("MyClass");
// Restore the original method implementation:
gOriginalFunc = class_getMethodImplementation(clsMyClass, @selector(func));
Method mtdFunc = class_getInstanceMethod(clsMyClass, @selector(func));
// Replace implementaion of the method of my own:
class_replaceMethod(clsMyClass, @selector(func), IMP(HookFunc), method_getTypeEncoding(mtdFunc));
objc_registerClassPair(clsMyClass);
MyClass* obj = [[MyClass alloc] init];
[obj func];
return 0;
}
I just replace the original implementation of [MyClass func]. When compiler flag -fno-objc-arc is set, this code works just fine:
2014-12-18 11:59:17.524 Hooker[749:72783] [MyClass func] is hooked!
2014-12-18 11:59:20.361 Hooker[749:72783] Hello from MyClass!
But problem occurs when ARC is enabled(by setting compiler flag as -fobjc-arc). A EXC_BAD_ACCESS signal is thrown while invoking gOriginalFunc(as comments say). I don’t know the reason, could anyone tell?