Hook in CLLocationManagerDelegate protocol

2019-01-25 01:31发布

I have a problem from 3 days :( I want to hook in CLLocationManagerDelegate protocol this method:

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations

I tried everything but without success. I know how to hook into class or framework but I can't find a solution to hook a Delegate. Please help me! Thanks

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-25 01:35

Hooking requires you to provide objective-C class you would like to hook. This is what Class type is for. One way to get obj-c class is by name via objc_getClass function. But in your case as I understand it correctly you don't have the name. You want to hook every class that conforms to CLLocationManagerDelegate protocol and implements specific method. Here is what you can do.

You can obtain every registered obj-C class and search for those which conform toCLLocationManagerDelegate protocol like this:

static IMP original_didUpdateLocations;
void replaced_didUpdateLocations(id self, SEL _cmd, CLLocationManager* manager, NSArray* locations)
{
    NSLog(@"%@ did update locations to %@", manager, locations);

    original_didUpdateLocations(self, _cmd, manager, locations);
}

...

#import <objc/runtime.h>

int numClasses = objc_getClassList(NULL, 0);

Class* list = (Class*)malloc(sizeof(Class) * numClasses);
objc_getClassList(list, numClasses);    

for (int i = 0; i < numClasses; i++)
{
    if (class_conformsToProtocol(list[i], @protocol(CLLocationManagerDelegate)) && 
        class_getInstanceMethod(list[i], @selector(locationManager:didUpdateLocations:)))
    {
        MSHookMessageEx(list[i], @selector(locationManager:didUpdateLocations:), (IMP)replaced_didUpdateLocations, (IMP*)&original_didUpdateLocations);
    }
}

free(list);
  1. We need to know how many classes there is. objc_getClassList(NULL, 0) returns number of all registered classes.

  2. Allocating memory with malloc(sizeof(Class) * numClasses) and filling it with objects of type Class using objc_getClassList(list, numClasses).

  3. Searching through all these classes for those which conform to CLLocationManagerDelegate protocol and implement locationManager:didUpdateLocations: method. If we found one we are hooking it with our own implementation.

  4. In our own implementation we are printing some debug message and calling original implementation before returning. Of course, you can do whatever you what, this is just an example.

  5. Freeing allocated memory using free(list).

查看更多
登录 后发表回答