How does Apple know you are using private API?

IphoneObjective CAppstore Approval

Iphone Problem Overview


I submitted a binary file to Apple without any source code.

Apart from manually checking the source code how does Apple know what was used and what APIs you have called?

Iphone Solutions


Solution 1 - Iphone

There are 3 ways I know. These are just some speculation, since I do not work in the Apple review team.

  1. otool -L

This will list all libraries the app has linked to. Something clearly you should not use, like IOKit and WebKit can be detected by this.

  1. nm -u

This will list all linked symbols. This can detect

  • Undocumented C functions such as _UIImageWithName;
  • Objective-C classes such as UIProgressHUD
  • Ivars such as UITouch._phase (which could be the cause of rejection of Three20-based apps last few months.)
  1. Listing Objective-C selectors, or strings

Objective-C selectors are stored in a special region of the binary, and therefore Apple could extract the content from there, and check if you've used some undocumented Objective-C methods, such as -[UIDevice setOrientation:].

Since selectors are independent from the class you're messaging, even if your custom class defines -setOrientation: irrelevant to UIDevice, there will be a possibility of being rejected.


You could use Erica Sadun's APIKit to detect potential rejection due to (false alarms of) private APIs.


(If you really really really really want to workaround these checks, you could use runtime features such as

  • dlopen, dlsym
  • objc_getClass, sel_registerName, objc_msgSend
  • -valueForKey:; object_getInstanceVariable, object_getIvar, etc.

to get those private libraries, classes, methods and ivars. )

Solution 2 - Iphone

You can list the selectors in a Mach-O program using the following one-liner in Terminal:

otool -s __TEXT __objc_methname "$1" |expand -8 | cut -c17- | sed -n '3,$p' | perl -n -e 'print join("\n",split(/\x00/,scalar reverse (reverse unpack("(a4)*",pack("(H8)*",split(/\s/,$_))))))'

Solution 3 - Iphone

Let's say you want to use some private API; objective C allows you to construct any SEL from a string:

   SEL my_sel = NSSelectorFromString([NSString stringWithFormat:\
@"%@%@%@", "se","tOr","ientation:"]);
    [UIDevice performSelector:my_sel ...];

How could a robot or library scan catch this? They would have to catch this using some tool that monitors private accesses at runtime. Even if they constructed such a runtime tool, it is hard to catch because this call may be hidden in some rarely exercised path.

Solution 4 - Iphone

I imagine they look at all symbols your binary's trying to import (info no doubt easily available to them in the symbol table thereof) and ding you if any of those symbols are found in their "private API list". Pretty easy to automate, in fact.

Solution 5 - Iphone

A executable isn't exactly a black box. If you call out to a library, it's an easy thing to find. This is why I lament the loss of the assembly languages in modern CS educations. =] Tools like ldd will tell you what you have linked in, though I don't remember what incarnation of ldd made it to the mac iPhone dev kit.

Solution 6 - Iphone

otool -L somebinary

Solution 7 - Iphone

aside from symbol investigation...

apple could very easily have a version of the sdk that checks each of the private methods stacks when called to make sure it is entered from one of the designated methods.

Solution 8 - Iphone

Even if you're statically linking, at worst, they could take samples of the code from the private APIs on their list, and search your binary against them (also relatively easy to automate).

Knowing Apple, I'd bet they have a comprehensive, automated system, and any uncertainty is probably either denied or reviewed manually.

End of the day, I think it's probably not worth the effort to try and fool Apple.

Solution 9 - Iphone

This desktop application, App Scanner, can scan .app files for private api usage by pulling apart the Mach-O Binary file. If it can, then Apple can too!

Solution 10 - Iphone

There are a lot of tools for reverse engineering that allows inspect a code

  • nm - lists the symbols from object files
  • objdump - display information from object files.
  • otool - view the content of Mach-O[About] executables
  • strings - this will get you all the strings.

You can find examples/representation of using these commands in gists for Objective-C and Swift

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTattatView Question on Stackoverflow
Solution 1 - IphonekennytmView Answer on Stackoverflow
Solution 2 - IphoneRobert DiamondView Answer on Stackoverflow
Solution 3 - IphoneChris McLuvinView Answer on Stackoverflow
Solution 4 - IphoneAlex MartelliView Answer on Stackoverflow
Solution 5 - IphoneSniggerfardimungusView Answer on Stackoverflow
Solution 6 - IphonedvenemaView Answer on Stackoverflow
Solution 7 - IphoneGrady PlayerView Answer on Stackoverflow
Solution 8 - IphonewashView Answer on Stackoverflow
Solution 9 - IphoneAndrewView Answer on Stackoverflow
Solution 10 - IphoneyoAlex5View Answer on Stackoverflow