Anyone who’s submitted an application to Apple’s app store knows that your app will be rejected if it uses any undocumented APIs.  Which is a shame, since there is lots of useful stuff in there.

I recently had to resubmit an app because of a forbidden API, and started wondering if there were a way to detect these things automatically, and save a bunch of heartache.

My thought was, get the names of all the forbidden selectors* and grep ’em out of the executable, so I can list the ones that can’t be used.

Great, we need two things then.  First, we need to know enough about the layout of the executable to be able to find the selectors, and we need to know which selectors are bad so we can list them.

I started my journey right at the horse’s mouth, Bill Bumgarner’s blog.  Under the hood, all objective-c method calls are translated to plain old C calls.  For example,

your declaration

@implementation foo
- (NSInteger)bar:(NSWhatever *)bazInstance {...}
@end

is compiled as (approximately)

int foo$bar(void *self, SEL _cmd, NSWhatever *bazInstance) {...}

and the method call

NSInteger biz = [foo bar:baz];

becomes

int biz = objc_msgSend(foo,@selector(bar:),baz);

So I thought that understanding the language’s most-called function would be in order. After reading all four blog posts (take your time, I’ll wait), I fired up xcode, put a hello world app on my iPhone, and started the debugger.

I enabled the assembly language pane in the debugger window (Run→Debugger Display→Source and Disassembly), put a breakpoint at the first source line of my method and hit Build and Run.

I think at this point I’ll close this blog, both to leave you on a cliffhanger so you’ll come back for part 2, and to encourage you to read the references and do some of your own experimentation.  If you don’t have a Mac, you can install gcc_objc and gdb, and get the same benefits.

References

Bill Bumgarner’s Weblog-o-mat

Apple’s Mach-O file format reference

* I assume working knowledge of objective-c, btw.

Advertisements