Comment Apple sait-il que vous utilisez une API privée?


109

J'ai soumis un fichier binaire à Apple sans aucun code source.

Outre la vérification manuelle du code source, comment Apple sait-il ce qui a été utilisé et quelles API vous avez appelées?


titre changé - je suppose que vous vouliez dire "Comment Apple sait-il ..."
Anurag

Réponses:


173

Il y a 3 façons dont je sais. Ce ne sont que des spéculations, car je ne travaille pas dans l'équipe d'examen Apple.

1. otool -L

Cela répertorie toutes les bibliothèques auxquelles l'application est liée. Quelque chose de clair que vous ne devriez pas utiliser, comme IOKit et WebKit peut être détecté par cela.

2. nm -u

Cela listera tous les symboles liés. Cela peut détecter

  • Fonctions C non documentées telles que _UIImageWithName;
  • Classes Objective-C telles que UIProgressHUD
  • Ivars tels que UITouch._phase(qui pourraient être la cause du rejet des applications basées sur Three20 ces derniers mois.)

3. Liste des sélecteurs Objective-C, ou strings

Les sélecteurs Objective-C sont stockés dans une région spéciale du binaire, et par conséquent Apple pourrait en extraire le contenu et vérifier si vous avez utilisé des méthodes Objective-C non documentées, telles que -[UIDevice setOrientation:].

Étant donné que les sélecteurs sont indépendants de la classe que vous envoyez, même si votre classe personnalisée définit comme -setOrientation:non pertinent pour UIDevice, il y aura une possibilité d'être rejeté.


Vous pouvez utiliser l'APIKit d'Erica Sadun pour détecter un rejet potentiel en raison de (fausses alarmes de) API privées.


(Si vous voulez vraiment vraiment contourner ces vérifications, vous pouvez utiliser des fonctionnalités d'exécution telles que

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

pour obtenir ces bibliothèques privées, classes, méthodes et ivars. )


Très bonne réponse. J'ajouterai simplement que si votre application fait quelque chose qui est extrêmement difficile à faire sans utiliser une API privée, je suis sûr que votre application fait l'objet d'un examen plus approfondi.
Matthew Frederick

Je suis curieux de savoir comment contourner l'appel des méthodes privées. Je pense que le compilateur générera un appel à objc_msgSend (foo, @selector (privateMethod)) pour [foo privateMethod], donc si Apple peut détecter l'appel direct de privateMethod, ils peuvent également détecter l'appel indirect via objc_msgSend (ou performSelector :).
un0

Je me demande pourquoi vous dites que vous ne devriez pas établir de lien avec IOKit et WebKit?
hjaltij

2
Sur quoi exécutez-vous otool? Le fichier .app?
Rob

1
@Eric, ils pourraient , même si une telle version instrumentée aurait probablement un impact sur les performances. Quoi qu'il en soit, en voyant des API privées pénétrer à plusieurs reprises dans l'App Store, il est clair qu'elles ne le font pas , ou du moins ne le font pas tout le temps.
Nate

26

Vous pouvez lister les sélecteurs dans un programme Mach-O en utilisant le one-liner suivant dans 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/,$_))))))'

+1, @Robert Diamond, pouvez-vous en décrire plus pour la même chose. Je dois vérifier que Google Analytics utilise l'appel UDID ou non. Merci
Mangesh

13

Supposons que vous souhaitiez utiliser une API privée; l'objectif C vous permet de construire n'importe quel SEL à partir d'une chaîne:

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

Comment un robot ou un scanner de bibliothèque pourrait-il détecter cela? Ils devraient attraper cela en utilisant un outil qui surveille les accès privés au moment de l'exécution. Même s'ils ont construit un tel outil d'exécution, il est difficile de l'attraper car cet appel peut être caché dans un chemin rarement utilisé.


user1203764 commente que ce type d'appels peut effectivement être détecté
Rup

@Rup veut donner un avis sur ma question ici sur l'utilisation de valueForKey, s'il vous plaît? stackoverflow.com/questions/11923597/…
Dan Rosenstark

1
@Yar question intéressante! Mais je ne suis pas assez expert pour commenter désolé. Ce que Farcaller a dit me semble raisonnable
Rup

Merci @Rup, personne n'est apparemment assez expert dans ce domaine :)
Dan Rosenstark

Quelqu'un que je connais dit qu'il vient de recevoir un appel comme celui-ci dans l'App Store.
bugloaf

7

J'imagine qu'ils regardent tous les symboles que votre binaire essaie d'importer (info sans doute facilement disponibles pour eux dans la table des symboles) et vous ding si l'un de ces symboles se trouve dans leur "liste API privée". Assez facile à automatiser, en fait.


1
En fait, je peux dire avec certitude que ce n'est pas le cas (du moins, ce n'est pas tout ce qu'ils font), sur la base de l'utilisation privée d'API que je sais qu'elle a réussi. Si cela est tout ce qui était nécessaire, l' utilisation de l' API privée ne serait pas glisser à travers. Mon expérience suggère que la réponse de KennyTM est presque certainement correcte. C'est un domaine où Objective-C est fondamentalement différent des autres langages, comme C.
Nate

1

Un exécutable n'est pas exactement une boîte noire. Si vous appelez une bibliothèque, c'est une chose facile à trouver. C'est pourquoi je déplore la perte des langages d'assemblage dans les formations CS modernes. =] Des outils comme ldd vous diront ce que vous avez lié, bien que je ne me souvienne pas de quelle incarnation de ldd a été intégrée au kit de développement Mac iPhone.


1
Je me suis souvent demandé: si vous deviez écrire votre binaire pour qu'il s'auto-modifie, ne générant le code pour importer une API privée qu'après que certains critères aient été remplis (par exemple, après la date de publication de votre application) si Apple l'attraperait. Ils nous rapportent certainement des statistiques intéressantes, comme le nombre de nos jeux exécutés sur des téléphones jailbreakés.
Sniggerfardimungus

@ user30997, Le code privilégié n'est probablement accessible que par un appel système; le thread en cours d'exécution bascule sur un privilège supérieur et vérifie si le privilège précédent dispose des autorisations pour exécuter le code ou non. Ce n'est qu'un exemple cependant, il existe d'autres façons de le faire, mais je doute fortement que les développeurs aient été assez naïfs pour laisser de côté un mécanisme de vérification des privilèges d'exécution de base comme celui-ci, il aurait certainement été rendu public maintenant.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳


1

en dehors de l'enquête sur les symboles ...

apple pourrait très facilement avoir une version du sdk qui vérifie chacune des piles de méthodes privées lorsqu'elle est appelée pour s'assurer qu'elle est entrée à partir de l'une des méthodes désignées.


Cela ne suffira pas, car le programme ne peut appeler cet appel privé qu'à un moment arbitraire dans le futur, en fonction d'une autre logique. Pour effectuer cet examen, Apple doit en fait bloquer complètement les API privées, ou demander aux frameworks de signaler automatiquement les appels d'API privés à Apple, ce qui nuit considérablement aux performances.
Motti Shneor le

0

Même si vous liez statiquement, au pire, ils pourraient prendre des échantillons du code des API privées de leur liste et rechercher votre binaire contre eux (également relativement facile à automatiser).

Connaissant Apple, je parierais qu'ils ont un système complet et automatisé, et toute incertitude est probablement soit niée, soit revue manuellement.

En fin de compte, je pense que cela ne vaut probablement pas la peine d'essayer de tromper Apple.


4
Connaître Apple son processus de révision en cas d'incertitude implique de lancer une série de dés pour un maximum de fantaisie.
JUSTE MON AVIS correct

0

Cette application de bureau, App Scanner , peut analyser les fichiers .app pour une utilisation privée de l'API en séparant le fichier binaire Mach-O. Si c'est possible, Apple le peut aussi!


0

Il existe de nombreux outils de rétro-ingénierie qui permettent d'inspecter un code

  • nm - répertorie les symboles des fichiers objets
  • objdump - afficher les informations des fichiers objets.
  • otool- afficher le contenu des exécutables Mach-O [About]
  • strings - cela vous donnera toutes les cordes.

Vous pouvez trouver des exemples / représentation de l'utilisation de ces commandes dans gists pour Objective-C et Swift

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.