Comment diagnostiquer les problèmes d'intégration du SDK. L'expérience de l'équipe de développement du SDK Yandex Mobile Ads

Bonjour à tous! Je m'appelle Dmitry Fisko, je développe le SDK Yandex Mobile Ads. Notre bibliothèque est conçue pour monétiser les applications mobiles sur les plateformes Android et iOS. Aujourd'hui, je veux vous expliquer comment nous avons simplifié l'analyse des erreurs complexes d'intégration du SDK dans les applications Android. Peut-être que notre expérience vous sera utile.

Nos utilisateurs - les développeurs d'applications mobiles - ne lisent pas toujours la documentation, donc parfois ils trouvent des façons complexes d'utiliser le SDK. Une intégration incorrecte peut réduire l'efficacité de la publicité, et donc réduire les revenus du développeur. Pour aider les développeurs à mieux monétiser les applications, nous avons créé un système de surveillance proactif qui analyse les performances d'une application mobile. Si nous découvrons le problème grâce à la surveillance, nous contactons les développeurs et les aidons à trouver la source du problème et à le résoudre.

Malheureusement, toutes les erreurs d'intégration du SDK ne peuvent pas être identifiées par la surveillance. Si une telle situation se présente, nous nous tournons vers le partenaire pour clarifier les détails de l'intégration. Ensuite, nous essayons de déterminer la cause des problèmes et d'aider à les résoudre. Si même ces informations ne suffisent pas à déterminer la cause des erreurs, nous demandons au partenaire l'autorisation de procéder à une rétro-ingénierie de l'application. Après autorisation, nous commençons à regarder le travail du SDK publicitaire dans l'application comme une boîte noire. Nous visualisons l'activité du réseau via un proxy, vérifions l'affichage des vues publicitaires via l'inspecteur de mise en page, etc.

L'affichage de l'activité réseau d'une application commençant par Android 7.0 est problématique, car le système par défaut ne fait pas confiance aux certificats définis par l'utilisateur. L'installation du certificat est requise pour visualiser le trafic SSL de l'application via un proxy. Il résoudra le problème soit en lançant l'application sur les versions Android antérieures à 7.0, soit en ajoutant network_security_config à l'application, par exemple via Apktool. Vous pouvez afficher l'affichage des vues publicitaires via l'utilitaire Layout Inspector en exécutant l'application sur un émulateur ou sur un appareil. Dans ce cas, vous devez modifier le fichier AndroidManifest.xml en ajoutant l' attribut debuggable = true via Apktool.

Si la méthode de la boîte noire n'était pas suffisante et que le problème ne pouvait pas être reproduit, vous pouvez regarder la logique de l'application. Pour ce faire, vous pouvez utiliser des utilitaires de décompilation APK, tels que JADX , Bytecode Viewer . Mais souvent cette approche prend trop de temps et ne conduit pas toujours à un résultat. Par conséquent, pour comprendre rapidement comment l'application utilise le SDK de l'intérieur, nous avons créé un script pour remplacer une nouvelle implémentation du SDK par une application déjà construite.

Installation d'une nouvelle implémentation SDK dans une application


La modification du code du SDK vous permet d'incorporer du code arbitraire dans l'application via les classes de la version modifiée du SDK et, par exemple, d'activer le mode de journalisation supplémentaire. L'algorithme de fonctionnement est le suivant. Script:

  1. désassemble les fichiers DEX d'application dans smali;
  2. convertit le fichier JAR de la nouvelle version du SDK en smali;
  3. remplace l'implémentation des fichiers SDK smali dans les fichiers d'application smali;
  4. Réassemble l'application avec la nouvelle version du SDK.


Assemblage de fichiers DEX d'application en smali


Vous devez décomposer l'application, la diviser en unités plus petites, afin de pouvoir changer le code des classes SDK sans changer le code de l'application. Comment aborder l'application assemblée? Démontez DEX en fichiers smali.

Sous Android, l'application stocke le code dans des fichiers DEX. Vous pouvez les extraire de l'application via l'utilitaire de décompression, car l'APK est une archive régulière avec un contenu structuré. Les fichiers DEX ont un format binaire pour un empaquetage de code plus dense que les fichiers JAR. En raison de la nature binaire du DEX, il est inhumain, donc changer le DEX lui-même est irrationnel. La première chose qui me vient à l'esprit est de décompiler DEX en Java. Une telle conversion est possible, mais elle n'est pas anodine et se produit avec une perte de fonctionnalité du code. Par conséquent, nous utiliserons la traduction en code smali. La conversion en smali vous permet de transférer avec précision les instructions de DEX sous une forme lisible par l'homme avec la possibilité d'une conversion ultérieure en code exploitable.

L'appel de l' utilitaire smali convertit DEX en un ensemble de classes en code smali. Dans ce cas, la disposition initiale des classes par sous-packages est conservée.


Conversion du nouveau SDK en smali


Nous préparerons une version de remplacement du SDK. Pour garantir la reproductibilité du problème, nous allons créer une version du SDK avec la journalisation activée basée sur la même version qui est déjà intégrée dans l'application. L'un des moyens les plus simples de découvrir la version connectée du SDK Yandex Mobile Ads dans l'application consiste à afficher le contenu de la méthode dans la classe MobileAds.getLibraryVersion () via Apk Analizer dans Android Studio. Après avoir découvert la version utilisée du SDK publicitaire, nous passons à la branche de cette version et collectons la version de la bibliothèque avec une journalisation supplémentaire. En conséquence, nous obtenons un fichier AAR. Il contient des ressources et un code de bibliothèque. Dans le fichier AAR, nous nous intéressons uniquement au code dans le fichier JAR, car il n'y a pas de ressources externes dans notre SDK: toutes les ressources sont intégrées directement dans le code ou proviennent du backend. L'absence de fichiers de ressources simplifie l'intégration du SDK dans l'EDI sans la prise en charge des systèmes de génération modernes.

Pour changer la version du SDK dans l'application en une nouvelle, nous amenons l'AAR au même état que l'application désassemblée, c'est-à-dire qu'à partir de l'AAR, nous obtenons un ensemble de fichiers smali. La conversion a lieu le long de la chaîne: AAR → JAR → DEX → SMALI:

  1. de l'AAR en utilisant l'utilitaire de décompression, nous extrayons le JAR avec le code;
  2. Nous convertissons JAR en DEX via l'utilitaire dxdump des outils du SDK Android;
  3. nous obtenons les fichiers dans le code smali en utilisant l'utilitaire smali avec le fichier DEX comme paramètre.


Implémentation du SDK


Après avoir reçu des fichiers smali de l'application et du SDK avec des journaux, nous remplaçons l'implémentation du SDK par une nouvelle. Ensuite, nous reconstruisons l'application. Lors de la diffusion vers smali, les classes résultantes conservent leur emplacement par sous-packages. Par conséquent, si le package où se trouvent les classes SDK est connu, il est facile de distinguer la classe de bibliothèque des classes d'application. Les classes SDK peuvent être distribuées sur plusieurs DEX. Ainsi, l'algorithme par lequel l'implémentation SDK est substituée diffère pour une application avec un ou plusieurs fichiers DEX.

Et l' algorithme pour remplacer l'implémentation du SDK dans une application par un DEX


Dans une seule application DEX, nous copions simplement les nouvelles classes smali du SDK au-dessus de toutes les classes d'application et générons un DEX modifié. Vous pouvez générer un fichier DEX à l'aide de l'utilitaire baksmali. Le répertoire contenant les fichiers de package des classes en code smali est envoyé à l'entrée de l'utilitaire. Après avoir traversé baksmali les fichiers smali combinés de l'application et du nouveau SDK, nous obtenons un fichier DEX modifié avec la logique du SDK modifiée.


Et l' algorithme pour remplacer l'implémentation du SDK dans une application avec MultiDex


Pour une application avec MultiDex, ajoutez un SDK distinct au nouveau DEX et supprimez la version précédente du SDK du reste des fichiers DEX de l'application. L'ajout d'une nouvelle version du SDK aux DEX individuels contournera la limitation du nombre de méthodes au format DEX. MultiDex chargera automatiquement le fichier DEX ajouté avec le code SDK s'il est correctement nommé. MultiDex recherche les fichiers DEX à son tour, en utilisant l'index à la fin du fichier: d'abord dex1, puis dex2 - et ainsi de suite. Si vous nommez le fichier avec un index incrémentiel, MultiDex le chargera automatiquement dans la machine virtuelle. Ainsi, via baksmali, nous générerons des fichiers DEX basés sur des fichiers smali d'application reçus précédemment, mais avec des classes supprimées de l'ancienne version du SDK. Et collectez également un fichier DEX supplémentaire avec une version modifiée du SDK, incrémentant l'index au nom du fichier DEX.


Reconstruisez l'application avec la nouvelle version du SDK


Nous avons obtenu des fichiers d'application DEX avec une version modifiée du SDK. La chose est petite: nous remplacerons les fichiers DEX dans le fichier APK initialement décompressé de l'application par les fichiers DEX modifiés. Et en appelant la commande zip, nous obtenons la version finale de l'APK, qui reste à signer. Nous signerons avec la clé de débogage via apksigner afin que l'application puisse être installée sur l'appareil. L'application avec la logique SDK modifiée est prête.

N Saving


L'algorithme fonctionne dans la plupart des cas, mais parfois il ne fonctionnera pas pour remplacer l'implémentation du SDK dans l'application. Les raisons de ceci:

  1. Obfuscation ProGuard. Les règles du fichier consommateur de la bibliothèque empêchent ProGuard de déplacer les classes SDK. Mais si le développeur annule ces instructions, une partie des classes de bibliothèque peut changer de package. Dans ce cas, l'algorithme ne fonctionnera pas, car le script ne trouvera pas l'emplacement des classes de l'ancien SDK.
  2. Limitation du format DEX. Si tout le code de l'application est stocké dans un fichier DEX, ce qui a presque complètement épuisé la limite des méthodes utilisées. Lorsque vous remplacez une version du SDK dans une application par une version avec une journalisation supplémentaire, le nombre de méthodes augmente. La limite sera dépassée. Au format DEX, la limite est de 2 ^ 16.
  3. Protégez votre application du changement. L'application dispose de mécanismes intégrés pour lutter contre la modification. Par exemple, via la validation de signature d'application. En modifiant l'APK, nous modifions en conséquence sa signature. Lorsque l'application démarre, elle vérifie la signature par rapport à la référence et lève une exception. Il est particulièrement difficile de supprimer ce contrôle s'il est placé dans la partie native.

Et toges


Nous avons automatisé les étapes décrites dans l'article avec un simple script bash. Le script présente des défauts, mais il accélère considérablement l'analyse des problèmes complexes lors de l'intégration du SDK dans les applications partenaires. Cependant, nous utilisons rarement cette approche, car nous trouvons souvent une solution à des stades antérieurs.

De la conversion à smali, vous pouvez obtenir des avantages supplémentaires: les fichiers smali vous permettent de déboguer l'application sans source. Pour commencer le débogage, vous devez générer un projet dans Android Studio basé sur les fichiers smali de l'application et attacher le débogueur au processus qui vous intéresse. Plus de détails sont écrits dans cet article .

Source: https://habr.com/ru/post/fr460597/


All Articles