1

Is there a way to replace the implementation of an Objective-C Foundation function, such as the NSClassFromString function for example? I am of course aware of class_replaceMethod, but it seems to work only for class methods and not general functions.

Tarek
  • 2,372
  • 2
  • 23
  • 35
  • Possibly related: http://stackoverflow.com/q/3229991 – Robert Harvey Aug 21 '13 at 18:16
  • Not related actually. – Tarek Aug 21 '13 at 18:19
  • 1
    I think [this](http://stackoverflow.com/questions/16579688/is-it-possible-to-swap-c-functions?lq=1) is related, though? – Carl Veazey Aug 21 '13 at 18:24
  • You can use `dyld` to load libraries containing alternate implementations of library functions _I believe_. Try `man dyld`. If you want to get more complicated, you could perhaps dynamically find the function pointer of the original implementation so you can tail/head call it. – nielsbot Aug 21 '13 at 18:42
  • @nielsbot assuming the function he wants to replace wasn't inlined. – Dave Aug 21 '13 at 18:44
  • possible duplicate of [Interposing of OS X system calls](http://stackoverflow.com/questions/11526882/interposing-of-os-x-system-calls) – jscs Aug 21 '13 at 18:47
  • 1
    I suppose if you were in full hacker mode you could overwrite the installed system function with machine instructions to jump to your implementation of the function you are replacing. You would also need to copy the replaced function's instructions somewhere else, fix up its jumps etc, and call that copy before/after your replacement function runs... But that sounds complicated. (Although it might be cool to develop a library that implements patching like that, i.e. http://en.wikipedia.org/wiki/Application_Enhancer) – nielsbot Aug 21 '13 at 18:53

1 Answers1

3

Those functions are just C functions and/or macros (Objective C is built on C), and you can't replace a C function.

However, you can use a define to mask the name:

Class MyNSClassFromString( NSString* blah ) {
    return whatever;
}

#define NSClassFromString MyNSClassFromString

Now from that point on, calling NSClassFromString(@"hi") will call the custom function. Note this has several limitations: It will not change any code which is above the define (or any code within libraries you're using), it will often make intellisense unhappy, and it won't work if NSClassFromString is defined as a macro in the first place (you can add #undef NSClassFromString before the define in that case).

Generally, I wouldn't recommend this, but if you really want to do it, the possibility is there.

Dave
  • 44,275
  • 12
  • 65
  • 105
  • 1
    You can indeed replace functions; it's called [interposing](http://www.jayconrod.com/cgi/view_post.py?23) or interpositioning. – jscs Aug 21 '13 at 18:43
  • 1
    @JoshCaswell nice, but as I said to nielsbot, that only applies if the function wasn't inlined, which could make for some difficult code to maintain as Apple update the API implementation. It also doesn't apply if the function is a macro in the first place, which Apple says some of those functions can be. – Dave Aug 21 '13 at 18:48