我正在尝试使用方法交换技术(method swizzling),并希望在执行method_exchangeImplementations
后调用原始函数。我已经为此设置了两个项目。
第一个项目是应用程序的主要项目,包括应用所有逻辑。请注意,在视图加载时调用了originalMethodName
。
@implementation ViewController
- (void)originalMethodName
{
NSLog(@"REAL %s", __func__);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"REAL %s", __func__);
[self originalMethodName];
}
@end
第二个项目仅包含混淆代码。我有一个名为swizzle_originalMethodName
的方法,其中包含我想要注入到主应用程序中的代码,并在调用originalMethodName
函数时执行。
第二个项目只包括关于交换函数的代码。我有一个名为swizzle_originalMethodName
的方法,其中包含了我希望注入到主应用程序中的代码,该代码会在调用originalMethodName
函数时运行。
@implementation swizzle_ViewController
- (void)swizzle_originalMethodName
{
NSLog(@"FAKE %s", __func__);
}
__attribute__((constructor)) static void initializer(void)
{
NSLog(@"FAKE %s", __func__);
Class c1 = objc_getClass("ViewController");
Class c2 = [swizzle_ViewController class];
Method m1 = class_getInstanceMethod(c1, @selector(originalMethodName));
Method m2 = class_getInstanceMethod(c2, @selector(swizzle_originalMethodName));
method_exchangeImplementations(m1, m2);
}
@end
目前看来,混淆已经正常工作(如下面的输出所示),但现在我希望能够从swizzle_originalMethodName
中调用originalMethodName
2016-08-17 14:18:51.765 testMacOS[7295:1297055] FAKE initializer
2016-08-17 14:18:51.822 testMacOS[7295:1297055] REAL -[ViewController viewDidLoad]
2016-08-17 14:18:51.822 testMacOS[7295:1297055] FAKE -[swizzle_ViewController swizzle_originalMethodName]
我尝试使用NSInvocation
,但是没有成功。你有什么想法我做错了什么吗?
Class c1 = objc_getClass("ViewController");
Method m1 = class_getInstanceMethod(c1, @selector(originalMethodName));
NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding( m1)];
NSInvocation *originalInvocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[originalInvocation invoke];
[self swizzle_originalMethodName];
怎么样?该选择器应该在交换后指向原始实现。 - Phillip Mills-[ViewController swizzle_originalMethodName]: 无法识别的选择器发送至实例0x7ff72974a670
- Corey Gagnon