Question

A developing consensus among the iPhone developer community is that Apple has recently started using a static code analysis tool to detect use of undocumented API calls.

Just for the sake of the argument, I wonder if it would be possible to work around this tool by generating the invocation at runtime like this:

NSString *const aMethod = @"doStuff:withStuff:";
SEL aSelector = NSSelectorFromString(aMethod);
NSMethodSignature *aSignature = [targetObject methodSignatureForSelector:aSelector];
NSInvokation *anInvokation = [NSInvokation invocationWithMethodSignature:aSignature];
[anInvokation setTarget:targetObject];
[anInvokation setSelector:aSelector];
[anInvokation setArgument:&firstArg atIndex:2];
[anInvokation setArgument:&secondArg atIndex:3];
[anInvokation invoke];

This almost seems too easy, so I wonder - what am I missing? How can Apple possibly detect this using static code analysis on the assembly?

A couple of points:

  1. I am aware that the method name will be stored in the binary as a static string. It would however be trivial to generate the method name at runtime as well using stringWithFormat: or other type of slight obfuscation (enough to confuse the static analyzer).
  2. I know that this trick would be revealed by even the most trivial runtime analysis using gdb - my understanding has been that Apple analyses the binary itself, and maybe I'm completely wrong about that.
Was it helpful?

Solution

Why care? You're not supposed to use private API for a good reason: Apple could easily break your application at any time, upsetting your users.

That said, use of NSInvocation, -performSelector: or any other similar technique is probably enough to avoid detection by a static analyzer.

OTHER TIPS

I suppose that you've read this article. Also interesting is this one. My interpretation is that Apple's static analyzer does generate false positives just because some people use methods that have the same name as private methods. This would not have happened if the analyzer had done either a runtime analysis or thorough checking of which classes' selector has been called. So, it seems like they mainly are looking for matching strings or selectors in your binary. I think that using NSInvocation combined with some string obfuscation will get you through. I'd still recommend to not rely on private APIs, though.

There's an easy way to find out!

Make an app that deliberately uses a hidden api through the method in your question and see it if gets accepted!

Sam

PS If you do find out, make sure you tell us; we'd all like to know for sure and Apple surely won't tell us!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top