So diagnostizieren Sie SDK-Integrationsprobleme. Die Erfahrung des SDK-Entwicklungsteams von Yandex Mobile Ads

Hallo allerseits! Mein Name ist Dmitry Fisko, ich entwickle das Yandex Mobile Ads SDK. Unsere Bibliothek wurde entwickelt, um mobile Anwendungen auf den Android- und iOS-Plattformen zu monetarisieren. Heute möchte ich Ihnen erzählen, wie wir die Analyse komplexer SDK-Integrationsfehler in Android-Anwendungen vereinfacht haben. Vielleicht ist unsere Erfahrung für Sie nützlich.

Unsere Benutzer - Entwickler mobiler Anwendungen - lesen die Dokumentation nicht immer, daher finden sie manchmal komplizierte Möglichkeiten zur Verwendung des SDK. Eine falsche Integration kann die Effektivität der Werbung und damit das Einkommen des Entwicklers verringern. Um Entwicklern die Monetarisierung von Anwendungen zu erleichtern, haben wir ein proaktives Überwachungssystem entwickelt, das die Leistung einer mobilen Anwendung analysiert. Wenn wir durch Überwachung etwas über das Problem erfahren, setzen wir uns mit den Entwicklern in Verbindung und helfen ihnen, die Ursache des Problems zu finden und es zu lösen.

Leider können nicht alle SDK-Integrationsfehler durch Überwachung identifiziert werden. In einem solchen Fall wenden wir uns an den Partner, um die Einzelheiten der Integration zu klären. Dann versuchen wir, die Ursache der Probleme zu ermitteln und sie zu lösen. Wenn selbst diese Informationen nicht ausreichen, um die Fehlerursache zu ermitteln, bitten wir den Partner um Erlaubnis, die Anwendung rückentwickeln zu dürfen. Nach der Erlaubnis beginnen wir, die Arbeit des Werbe-SDK in der Anwendung als Black Box zu betrachten. Wir zeigen die Netzwerkaktivität über einen Proxy an, überprüfen die Anzeige von Werbeansichten über den Layout-Inspektor usw.

Das Anzeigen der Netzwerkaktivität einer Anwendung ab Android 7.0 ist problematisch, da das System standardmäßig den vom Benutzer festgelegten Zertifikaten nicht vertraut. Die Installation des Zertifikats ist erforderlich, um den SSL-Verkehr der Anwendung über einen Proxy anzuzeigen. Das Problem wird entweder durch Starten der Anwendung auf Android-Versionen vor 7.0 oder durch Hinzufügen von network_security_config zur Anwendung behoben, z. B. über Apktool. Sie können die Anzeige von Werbeansichten über das Dienstprogramm Layout Inspector anzeigen, indem Sie die Anwendung auf einem Emulator oder einem Gerät ausführen. In diesem Fall müssen Sie die Datei AndroidManifest.xml ändern, indem Sie das Attribut debuggable = true über Apktool hinzufügen.

Wenn die Black-Box-Methode nicht ausreicht und das Problem nicht reproduziert werden kann, können Sie sich die Logik der Anwendung ansehen. Zu diesem Zweck können Sie APK-Dekompilierungsdienstprogramme wie JADX und Bytecode Viewer verwenden . Oft nimmt dieser Ansatz jedoch zu viel Zeit in Anspruch und führt nicht immer zu einem Ergebnis. Um schnell zu verstehen, wie die Anwendung das SDK von innen verwendet, haben wir ein Skript erstellt, um eine neue SDK-Implementierung durch eine bereits erstellte Anwendung zu ersetzen.

Installieren einer neuen SDK-Implementierung in einer Anwendung


Durch Ändern des SDK-Codes können Sie beliebigen Code über die Klassen der geänderten SDK-Version in die Anwendung einbetten und beispielsweise den zusätzlichen Protokollierungsmodus aktivieren. Der Operationsalgorithmus ist wie folgt. Skript:

  1. zerlegt Anwendungs-DEX-Dateien in smali;
  2. konvertiert die JAR-Datei der neuen Version des SDK in smali;
  3. ersetzt die Implementierung von smali SDK-Dateien in smali-Anwendungsdateien;
  4. Setzt die Anwendung mit der neuen Version des SDK wieder zusammen.


D Assemblieren von Anwendungs-DEX-Dateien in smali


Sie müssen die Anwendung zerlegen und in kleinere Einheiten aufteilen, damit Sie den Code der SDK-Klassen ändern können, ohne den Anwendungscode zu ändern. Wie gehe ich mit der zusammengestellten Anwendung um? Zerlegen Sie DEX in kleine Dateien.

In Android speichert die Anwendung den Code in DEX-Dateien. Sie können sie über das Dienstprogramm zum Entpacken aus der Anwendung extrahieren, da APK ein reguläres Archiv mit strukturiertem Inhalt ist. DEX-Dateien haben im Vergleich zu JARs ein Binärformat für dichteres Code-Packaging. Aufgrund der binären Natur von DEX ist es unmenschlich, daher ist es irrational, das DEX selbst zu ändern. Das erste, was mir in den Sinn kommt, ist das Dekompilieren von DEX in Java. Eine solche Konvertierung ist möglich, aber nicht trivial und tritt bei Verlust der Funktionalität des Codes auf. Daher werden wir die Übersetzung in Smali-Code verwenden. Durch die Konvertierung in smali können Sie Anweisungen von DEX in lesbarer Form genau übertragen und anschließend in funktionsfähigen Code konvertieren.

Durch Aufrufen des Dienstprogramms smali wird DEX in eine Reihe von Klassen im smali-Code konvertiert. In diesem Fall bleibt die anfängliche Anordnung der Klassen nach Unterpaketen erhalten.


Konvertieren des neuen SDK in smali


Wir werden eine Ersatz-SDK-Version vorbereiten. Um die Reproduzierbarkeit des Problems zu gewährleisten, erstellen wir eine Version des SDK mit aktivierter Protokollierung, die auf derselben Version basiert, die bereits in die Anwendung integriert ist. Eine der einfachsten Möglichkeiten, die verbundene Version des Yandex Mobile Ads SDK in der Anwendung herauszufinden, besteht darin, den Inhalt der Methode in der Klasse MobileAds.getLibraryVersion () über Apk Analizer in Android Studio anzuzeigen . Nachdem wir die verwendete Version des Werbe-SDK herausgefunden haben, wechseln wir zum Zweig dieser Version und sammeln die Bibliotheksversion mit zusätzlicher Protokollierung. Als Ergebnis erhalten wir eine AAR-Datei. Es enthält Ressourcen und Bibliothekscode. In der AAR-Datei interessiert uns nur der Code in der JAR-Datei, da unser SDK keine externen Ressourcen enthält: Alle Ressourcen werden direkt in den Code eingefügt oder stammen aus dem Backend. Das Fehlen von Ressourcendateien vereinfacht die Integration des SDK in die IDE ohne die Unterstützung moderner Build-Systeme.

Um die Version des SDK in der Anwendung in eine neue zu ändern, bringen wir den AAR in den gleichen Zustand wie die disassemblierte Anwendung, dh, vom AAR erhalten wir eine Reihe von Smali-Dateien. Die Konvertierung erfolgt entlang der Kette: AAR → JAR → DEX → SMALI:

  1. Aus AAR extrahieren wir mit dem Dienstprogramm unzip die JAR mit dem Code.
  2. Wir konvertieren JAR über das Dienstprogramm dxdump aus den Android SDK-Tools in DEX.
  3. Wir erhalten die Dateien im Smali-Code mit dem Dienstprogramm smali mit der DEX-Datei als Parameter.


SDK-Implementierung


Nachdem wir kleine Dateien der Anwendung und des SDK mit Protokollen erhalten haben, ersetzen wir die SDK-Implementierung durch eine neue. Dann erstellen wir die Anwendung neu. Bei der Übertragung an smali behalten die resultierenden Klassen ihren Standort durch Unterpakete bei. Wenn das Paket bekannt ist, in dem sich die SDK-Klassen befinden, ist es daher einfach, die Bibliotheksklasse von den Anwendungsklassen zu unterscheiden. SDK-Klassen können auf mehrere DEXs verteilt werden. Daher unterscheidet sich der Algorithmus, durch den die SDK-Implementierung ersetzt wird, für eine Anwendung mit einer oder mehreren DEX-Dateien.

Und der Algorithmus zum Ersetzen der SDK-Implementierung in einer Anwendung durch ein DEX


In einer einzelnen DEX-Anwendung kopieren wir einfach die neuen SDK-Smali-Klassen über alle Anwendungsklassen und generieren ein modifiziertes DEX. Sie können eine DEX-Datei mit dem Dienstprogramm baksmali erstellen. Das Verzeichnis mit den Paketdateien der Klassen im Smali-Code wird dem Dienstprogramm eingegeben. Nachdem wir die kombinierten smali-Dateien der Anwendung und des neuen SDK durch baksmali durchlaufen haben, erhalten wir eine modifizierte DEX-Datei mit der geänderten SDK-Logik.


Und der Algorithmus zum Ersetzen der SDK-Implementierung in einer Anwendung durch MultiDex


Fügen Sie für eine Anwendung mit MultiDex dem neuen DEX ein separates SDK hinzu und entfernen Sie die vorherige Version des SDK aus den übrigen DEX-Dateien der Anwendung. Durch Hinzufügen einer neuen Version des SDK zu einzelnen DEXs wird die Beschränkung der Anzahl der Methoden im DEX-Format umgangen. MultiDex lädt die hinzugefügte DEX-Datei automatisch mit dem SDK-Code, wenn sie korrekt benannt ist. MultiDex sucht nacheinander nach DEX-Dateien, wobei der Index am Ende der Datei verwendet wird: zuerst dex1, dann dex2 - und so weiter. Wenn Sie die Datei mit einem inkrementellen Index benennen, lädt MultiDex sie automatisch in die virtuelle Maschine. Daher werden wir über baksmali DEX-Dateien basierend auf zuvor empfangenen Anwendungs-smali-Dateien generieren, jedoch mit gelöschten Klassen der alten SDK-Version. Sammeln Sie außerdem eine zusätzliche DEX-Datei mit einer geänderten Version des SDK, indem Sie den Index im Namen der DEX-Datei erhöhen.


Erstellen Sie die Anwendung mit der neuen Version des SDK neu


Wir haben Anwendungs-DEX-Dateien mit einer modifizierten Version des SDK. Die Sache ist klein: Wir werden die DEX-Dateien in der ursprünglich entpackten APK-Datei der Anwendung durch die geänderten DEX-Dateien ersetzen. Durch Aufrufen des Befehls zip erhalten wir die endgültige Version der APK, die noch signiert werden muss. Wir werden mit dem Debug-Schlüssel über apksigner signieren, damit die Anwendung auf dem Gerät installiert werden kann. Die Anwendung mit der geänderten SDK-Logik ist bereit.

N Speichern


Der Algorithmus funktioniert in den meisten Fällen, aber manchmal funktioniert er nicht, um die SDK-Implementierung in der Anwendung zu ersetzen. Die Gründe dafür:

  1. Verschleierung ProGuard. Die Regeln in der Consumer-Datei der Bibliothek verhindern, dass ProGuard die SDK-Klassen verschiebt. Wenn der Entwickler diese Anweisungen jedoch abbricht, kann ein Teil der Bibliotheksklassen ihr Paket ändern. In diesem Fall funktioniert der Algorithmus nicht, da das Skript den Speicherort der Klassen des alten SDK nicht findet.
  2. Einschränkung des DEX-Formats. Wenn der gesamte Code in der Anwendung in einer DEX-Datei gespeichert ist, ist die Grenze der verwendeten Methoden fast vollständig ausgeschöpft. Wenn Sie eine SDK-Version in einer Anwendung durch eine Version mit zusätzlicher Protokollierung ersetzen, erhöht sich die Anzahl der Methoden. Das Limit wird überschritten. Im DEX-Format beträgt das Limit 2 ^ 16.
  3. Schützen Sie Ihre Anwendung vor Änderungen. Die Anwendung verfügt über integrierte Mechanismen zur Bekämpfung von Änderungen. Zum Beispiel durch Validierung der Anwendungssignatur. Durch Ändern der APK ändern wir entsprechend ihre Signatur. Wenn die Anwendung gestartet wird, vergleicht sie die Signatur mit der Referenz und löst eine Ausnahme aus. Es ist besonders schwierig, diese Prüfung zu entfernen, wenn sie im nativen Teil platziert ist.

Und Togas


Wir haben die im Artikel beschriebenen Schritte mit einem einfachen Bash-Skript automatisiert. Das Skript weist Fehler auf, beschleunigt jedoch die Analyse komplexer Probleme bei der Integration des SDK in Partneranwendungen erheblich. Wir verwenden diesen Ansatz jedoch selten, da wir in früheren Phasen häufig eine Lösung finden.

Von der Konvertierung in smali erhalten Sie zusätzliche Vorteile: Mit smali-Dateien können Sie die Anwendung ohne Quelle debuggen. Um mit dem Debuggen zu beginnen, müssen Sie in Android Studio ein Projekt basierend auf den Smali-Dateien der Anwendung generieren und den Debugger an den gewünschten Prozess anhängen. Weitere Details finden Sie in diesem Artikel .

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


All Articles