返回

依赖于其他库的Objective-C方法hook实现方式

IOS

在Objective-C中,通常使用category的方式来hook方法,但是这种方式会使debug工具依赖于被hook的库,这在某些情况下是不希望发生的。例如,我们正在编写一个debug工具,该工具需要hook NSURLSessionConfiguration 类的方法,但是我们不希望debug工具依赖于 NSURLSession 库。

为了解决这个问题,我们可以使用一种不依赖于其他库的方法来hook NSURLSessionConfiguration 类的方法。这种方法是通过创建一个新的类,并在这个类中重写被hook的方法。然后,我们将这个类注册到 objc_getClassList() 函数中,这样就可以在运行时hook NSURLSessionConfiguration 类的方法了。

下面是一个示例代码,演示如何使用这种方法来hook NSURLSessionConfiguration 类的方法:

#import <objc/runtime.h>

@interface NSURLSessionConfiguration (Hook)

- (void)hook_setHTTPAdditionalHeaders:(NSDictionary<NSString *, NSString *> *)headers;

@end

@implementation NSURLSessionConfiguration (Hook)

- (void)hook_setHTTPAdditionalHeaders:(NSDictionary<NSString *, NSString *> *)headers {
    NSLog(@"hooked! %@", headers);
    [self hook_setHTTPAdditionalHeaders:headers];
}

+ (void)load {
    Class cls = objc_getClass("NSURLSessionConfiguration");
    Method originalMethod = class_getInstanceMethod(cls, @selector(setHTTPAdditionalHeaders:));
    Method hookMethod = class_getInstanceMethod(cls, @selector(hook_setHTTPAdditionalHeaders:));
    method_exchangeImplementations(originalMethod, hookMethod);
}

@end

在这个示例代码中,我们首先创建了一个新的类 NSURLSessionConfiguration (Hook),在这个类中重写了 setHTTPAdditionalHeaders: 方法。然后,我们在 +load 方法中将这个类注册到 objc_getClassList() 函数中,这样就可以在运行时hook NSURLSessionConfiguration 类的方法了。

当我们运行这个代码时,NSURLSessionConfiguration 类的 setHTTPAdditionalHeaders: 方法就会被hook,每次调用这个方法时,都会在控制台输出一条日志。

这种方法可以用于hook任何Objective-C类的方法,并且不依赖于其他库。这使得它非常适合用于编写debug工具。