1

I'm trying to swizzle some methods in an application made with Objective-C. I'm getting this error:

Symbol not found: _OBJC_CLASS_$_IASAvatarViewController

After opening the executable in Hopper, I see that all of the classes are prefixed with objc_class_ instead. So the class name of the method I'm trying to swizzle is objc_class_IASAvatarViewController. First off, I'm dying to know how the class identifiers have turned out that way (some sort of name mangling?). And second, I'd like to know if it's possible to have my dylib reference the correct identifier.

DylibTest.h:

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@interface IASBaseViewController : UIViewController

@end

@interface IASAvatarViewController : IASBaseViewController

@end

@interface IASAvatarViewController (Swizzle)

@end

DylibTest.m

#import "DylibTest.h"
#import <dlfcn.h>

@implementation IASAvatarViewController (Swizzle)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(viewDidLoad);
        SEL swizzledSelector = @selector(xxx_viewDidLoad);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
 }


 - (void)xxx_viewDidLoad {
    [[[UIAlertView alloc] initWithTitle:@"Swizzled method" message:@"Ya swizzle" delegate:nil cancelButtonTitle:@"Yeah. Okay" otherButtonTitles:nil] show];

    [self xxx_viewDidLoad];
 }

 @end

And a screen shot of Hopper with the Objective-C classes: Screen shot of Hopper

Edit: Got enough reputation to directly post image.

Edit2: class-dump of the file: http://pastebin.com/DcUD5AL5

Borys Verebskyi
  • 4,160
  • 6
  • 28
  • 42
Vetle Økland
  • 80
  • 1
  • 8
  • I had no idea swizzling was an actual term before seeing this question. Thanks! – Emil Jan 11 '15 at 00:31
  • Oh, yeah! I had some problems finding out how to do this at first, because I was was looking for "interposing," which you do in C/C++. Took me a while to figure out the "equivalent" in Obj-C is "swizzling." – Vetle Økland Jan 11 '15 at 00:38
  • Swizzling happens at run-time, after the application has loaded and is executing. Your error is occurring long before that, so it's unlikely that swizzling is the cause of the problem. I presume you have no @implementation of `IASAvatarViewController`, which causes the linker/loader error. – Darren Jan 11 '15 at 01:55
  • No, I don't have that implementation. It's not my own application... – Vetle Økland Jan 11 '15 at 01:56
  • The implementation for `IASAvatarViewController` doesn't exist. That's what the loader error is telling you. – Darren Jan 11 '15 at 01:59
  • Well, I know that's what it's telling me, but obviously it must exist somewhere? – Vetle Økland Jan 11 '15 at 01:59
  • It's not at all obvious that `IASAvatarViewController` must exist somewhere. From what you've posted, I think it does not. – Darren Jan 11 '15 at 02:09
  • Using `class-dump`, shows that there is a class called `IASAvatarViewController`. I've tried swizzling other classes instead, but none of them seems to "exist" to my Dynamic Library. Is it possible that it is compiled with another compiler or with some sort of compiler flag? – Vetle Økland Jan 11 '15 at 11:17

0 Answers0