Let’s say you have an app that misbehaves. As in, it raises an exception mentioning an unrecognized selector.
Of course, it’s third party and closed-source.
But you are an enterprising young developer and you really want to patch this app.
I will not identify the app that I patched, to avoid any impression that I’m cracking the app. (It’s a popular app and I’ve run into pretty nice anti piracy protection blocking gdb on multiple layers. Since I’m not familiar with cracking and was not even attempting that, I’ve decided that it’s best to simply avoid mentioning the app name.)
Makefile
all: misbehavingappfixer.dylib misbehavingappfixer.dylib: misbehavingappfixer.o gcc \ -dynamiclib \ -undefined suppress -flat_namespace \ misbehavingappfixer.o \ -framework Cocoa -o misbehavingappfixer.dylib run: DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=`pwd`/misbehavingappfixer.dylib /Applications/Misbehaving\ App.app/Contents/MacOS/Misbehaving\ App
misbehavingappfixer.c
#include#include static CFStringRef nameImp(id self, SEL _cmd) { return CFSTR("IVFlawedClass"); } void inject_init(void) __attribute__((constructor)); void inject_init(void) { Class _IVFlawedClass = objc_getClass("IVFlawedClass"); if(!_IVFlawedClass) { printf("Could not find IVFlawedClass"); return; } SEL nameSel = sel_registerName("name"); class_addMethod(_IVFlawedClass, nameSel, (IMP)nameImp, "@@:"); }
I avoided using Objective-C because I had some issues when I tried going that route. It should work, but I didn’t want to spend any more time on this than I already have.
Now, to use this:
make make run
This will compile the fix dylib, and then launch the Misbehaving App while first preloading our fix dylib.
For more information, see these:
- Apple’s Objective-C Runtime Reference
- TL Robinson’s tutorial on replacing fopen() using DL_INSERT_LIBRARIES and flat-namespace
- Mike Ash’s code injection using gdb, dlopen() and the ((__constructor__)) attribute
Note: from comments on Mike Ash’s post, it seems that since I’m not overwriting symbols, I don’t need to (and, more importantly, *should* not) be using flat namespace. That means, I should not be using DYLD_FORCE_FLAT_NAMESPACE and -flat_namespace.
But, it works for me, so what the hell. 🙂
–
via blog.vucica.net