1

I have some great troubles overriding some functions in an external App that I use SIMBL to hook in to.

In this app, there is a class - let's call it "AppClass". In this class there is a function,

-(void)doSomething;

I got this from class-dumping the Binary. the whole interface is defined as:

@interface AppClass : NSObject
{
}

I'm trying to override this function with jr_swizzleMethod:withMethod:error:

With the lack of documentation, this is what I have come up with:

    #import "JRSwizzle.h"
    #import "AppClass.h"

@interface AppClass (MyPlugin)
- (void)myPlugin_doSomething;
@end

@implementation AppClass (MyPlugin)

- (void)myPlugin_doSomething {
 NSLog(@"lol?");
}

@end

@implementation MyPlugin

+ (void) load {
 Mylugin* plugin = [MyPlugin sharedInstance];

 NSError *err = nil;
 BOOL result = [NSClassFromString(@"AppClass") jr_swizzleMethod:@selector(doSomething) withMethod:@selector(myPlugin_doSomething) error:&err];

 if(!result)
  NSLog(@"<Plugin> Could not install events filter (error: %@)", err);

 NSLog(@"Plugin installed");
}



+ (MyPlugin *)sharedInstance {
 static MyPlugin* plugin = nil;

 if(plugin == nil)
  plugin = [[MyPlugin alloc] init];

 return plugin;
}

@end

That should be enough right? But I get this error on compile:

Undefined symbols:
  "_OBJC_CLASS_$_AppClass", referenced from:
      l_OBJC_$_CATEGORY_AppClass_$_MyPlugin in MyPlugin.o
      objc-class-ref-to-AppClass in MyPlugin.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

How do I solve this?

Yuji
  • 34,103
  • 3
  • 70
  • 88

1 Answers1

2

You're creating a plugin, which refers to symbols in a binary (the app you're trying to extend). Therefore, you need to tell the linker where to look for those symbols (In your case, that's _OBJC_CLASS_$_AppClass, i.e. AppClass that's defined in the binary. ).

This is done by passing the option -bundle_loader executable_name to the linker. See the man page for ld.

Yuji
  • 34,103
  • 3
  • 70
  • 88
  • Thank you for the reply. I tried adding this to OTHER_LDFLAGS -bundle_loader /Path/To/Binary Same error. Is it the wrong place to put this ld in XCode? – John Williams Nov 14 '10 at 17:19
  • Actually, the error was that the library was being compiled as x86_64 when the binary linked was x86 – John Williams Nov 14 '10 at 20:03
  • I'm having some other problems at the moment. I'm trying to override a class method, but jr_swizzleMethod returns: Error Domain=NSCocoaErrorDomain Code=-1 UserInfo=0x13911f90 "+[NSObject(JRSwizzle) jr_swizzleMethod:withMethod:error:]: original method notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext: not found for class GrowlApplicationBridge". The definition is there, just that it's a class method: + (void)notifyWithTitle:.... – John Williams Nov 15 '10 at 17:22
  • Class methods are instance methods of the metaclass. You should replace `NSClassFromString(@"SomeClass")` with `objc_getMetaClass("SomeClass")`. You need to include ``. To learn more, read http://cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html . – Yuji Nov 16 '10 at 00:30