Cómo diagnosticar problemas de integración de SDK. La experiencia del equipo de desarrollo de Yandex Mobile Ads SDK

Hola a todos! Mi nombre es Dmitry Fisko, estoy desarrollando el SDK de Yandex Mobile Ads. Nuestra biblioteca está diseñada para monetizar aplicaciones móviles en las plataformas Android e iOS. Hoy quiero contarles cómo simplificamos el análisis de errores complejos de integración de SDK en aplicaciones de Android. Quizás nuestra experiencia te sea útil.

Nuestros usuarios, desarrolladores de aplicaciones móviles, no siempre leen la documentación, por lo que a veces se les ocurren formas complejas de usar el SDK. La integración incorrecta puede reducir la efectividad de la publicidad y, por lo tanto, reducir los ingresos del desarrollador. Para ayudar a los desarrolladores a monetizar mejor las aplicaciones, hemos creado un sistema de monitoreo proactivo que analiza el rendimiento de una aplicación móvil. Si aprendemos sobre el problema a través del monitoreo, contactamos a los desarrolladores y les ayudamos a encontrar la fuente del problema y resolverlo.

Desafortunadamente, no todos los errores de integración del SDK pueden identificarse mediante monitoreo. Si surge tal situación, recurrimos al socio para aclarar los detalles de la integración. Luego tratamos de determinar la causa de los problemas y ayudar a resolverlos. Si incluso esta información no es suficiente para determinar la causa de los errores, le pedimos permiso al socio para realizar ingeniería inversa de la aplicación. Después del permiso, comenzamos a ver el trabajo del SDK de publicidad en la aplicación como un recuadro negro. Vemos la actividad de la red a través de un proxy, verificamos la visualización de vistas publicitarias a través del Inspector de diseño, etc.

Ver la actividad de red de una aplicación que comienza con Android 7.0 es problemático, ya que el sistema de forma predeterminada no confía en los certificados establecidos por el usuario. Se requiere la instalación del certificado para ver el tráfico SSL de la aplicación a través de un proxy. Resolverá el problema ya sea iniciando la aplicación en versiones de Android anteriores a la 7.0 o agregando network_security_config a la aplicación, por ejemplo, a través de Apktool. Puede ver la visualización de vistas publicitarias a través de la utilidad Layout Inspector ejecutando la aplicación en un emulador o en un dispositivo. En este caso, debe modificar el archivo AndroidManifest.xml agregando el atributo debuggable = true a través de Apktool.

Si el método del recuadro negro no fue suficiente y el problema no se pudo reproducir, puede ver la lógica de la aplicación. Para hacer esto, puede utilizar las utilidades de descompilación de APK, como JADX , Bytecode Viewer . Pero a menudo este enfoque lleva demasiado tiempo y no siempre conduce a un resultado. Por lo tanto, para comprender rápidamente cómo la aplicación usa el SDK desde adentro, creamos un script para sustituir una nueva implementación del SDK en una aplicación ya construida.

Instalar una nueva implementación de SDK en una aplicación


Cambiar el código SDK le permite incrustar código arbitrario en la aplicación a través de las clases de la versión modificada del SDK y, por ejemplo, habilitar el modo de registro adicional. El algoritmo de operación es el siguiente. Guión:

  1. desmonta los archivos DEX de la aplicación en smali;
  2. convierte el archivo JAR de la nueva versión del SDK a smali;
  3. reemplaza la implementación de pequeños archivos SDK en pequeños archivos de aplicación;
  4. Vuelve a ensamblar la aplicación con la nueva versión del SDK.


D es ensamblar archivos DEX de aplicaciones en smali


Debe descomponer la aplicación, dividirla en unidades más pequeñas, de modo que pueda cambiar el código de las clases SDK sin cambiar el código de la aplicación. ¿Cómo abordar la aplicación ensamblada? Desmontar DEX en archivos pequeños.

En Android, la aplicación almacena el código en archivos DEX. Puede extraerlos de la aplicación a través de la utilidad de descompresión, ya que APK es un archivo regular con contenido estructurado. Los archivos DEX tienen un formato binario para un empaquetado de código más denso en comparación con los JAR. Debido a la naturaleza binaria de DEX, es inhumano, por lo que cambiar el DEX en sí es irracional. Lo primero que viene a la mente es descompilar DEX en Java. Tal conversión es posible, pero no es trivial y ocurre con la pérdida de funcionalidad del código. Por lo tanto, utilizaremos la traducción al código pequeño. La conversión a smali le permite transferir con precisión las instrucciones de DEX en una forma legible para humanos con la posibilidad de una conversión posterior a código viable.

Llamar a la utilidad smali convierte DEX en un conjunto de clases en código smali. En este caso, se conserva la disposición inicial de las clases por subpaquetes.


Convertir el nuevo SDK a smali


Prepararemos una versión de reemplazo del SDK. Para garantizar la reproducibilidad del problema, crearemos una versión del SDK con el registro habilitado basado en la misma versión que ya está integrada en la aplicación. Una de las formas más fáciles de descubrir la versión conectada del SDK de Yandex Mobile Ads en la aplicación es ver el contenido del método en la clase MobileAds.getLibraryVersion () a través de Apk Analizer en Android Studio. Después de descubrir la versión usada del SDK publicitario, cambiamos a la rama de esta versión y recopilamos la versión de la biblioteca con un registro adicional. Como resultado, obtenemos un archivo AAR. Contiene recursos y código de biblioteca. En el archivo AAR, solo estamos interesados ​​en el código en el archivo JAR, ya que no hay recursos externos en nuestro SDK: todos los recursos están integrados directamente en el código o provienen del backend. La falta de archivos de recursos simplifica la integración del SDK en el IDE sin el soporte de los sistemas de compilación modernos.

Para cambiar la versión del SDK en la aplicación a una nueva, traemos el AAR al mismo estado que la aplicación desensamblada, es decir, del AAR obtenemos un conjunto de archivos pequeños. La conversión se lleva a cabo a lo largo de la cadena: AAR → JAR → DEX → SMALI:

  1. desde AAR usando la utilidad de descompresión extraemos el JAR con el código;
  2. Convertimos JAR a DEX a través de la utilidad dxdump de las herramientas de Android SDK;
  3. obtenemos los archivos en el código smali usando la utilidad smali con el archivo DEX como parámetro.


Implementación de SDK


Habiendo recibido pequeños archivos de la aplicación y SDK con registros, reemplazamos la implementación del SDK por una nueva. Luego reconstruimos la aplicación. Cuando se transmite a smali, las clases resultantes mantienen su ubicación por subpaquetes. Por lo tanto, si se conoce el paquete donde se encuentran las clases de SDK, es fácil distinguir la clase de biblioteca de las clases de aplicación. Las clases de SDK se pueden distribuir a través de múltiples DEX. Entonces, el algoritmo por el cual se sustituye la implementación del SDK difiere de una aplicación con uno o varios archivos DEX.

Y el algoritmo para reemplazar la implementación del SDK en una aplicación con un DEX


En una sola aplicación DEX, simplemente copiamos las nuevas clases SDK smali sobre todas las clases de aplicaciones y generamos un DEX modificado. Puede generar un archivo DEX utilizando la utilidad baksmali. El directorio con los archivos de paquetes de clases en código pequeño se alimenta a la entrada de la utilidad. Después de pasar por baksmali los archivos pequeños combinados de la aplicación y el nuevo SDK, obtenemos un archivo DEX modificado con la lógica del SDK modificada.


Y el algoritmo para reemplazar la implementación del SDK en una aplicación con MultiDex


Para una aplicación con MultiDex, agregue un SDK separado al nuevo DEX y elimine la versión anterior del SDK del resto de los archivos DEX de la aplicación. Agregar una nueva versión del SDK a DEX individuales evitará la limitación en la cantidad de métodos en el formato DEX. MultiDex cargará automáticamente el archivo DEX agregado con el código SDK si se nombra correctamente. MultiDex busca archivos DEX a su vez, utilizando el índice al final del archivo: primero dex1, luego dex2, y así sucesivamente. Si nombra el archivo con un índice incremental, MultiDex lo cargará automáticamente en la máquina virtual. Por lo tanto, a través de baksmali, generaremos archivos DEX basados ​​en los archivos pequeños de la aplicación recibidos previamente, pero con clases eliminadas de la versión anterior del SDK. Y también recopile un archivo DEX adicional con una versión modificada del SDK, incrementando el índice en el nombre del archivo DEX.


Reconstruya la aplicación con la nueva versión del SDK


Tenemos archivos DEX de aplicaciones con una versión modificada del SDK. La cosa es pequeña: reemplazaremos los archivos DEX en el archivo APK originalmente desempaquetado de la aplicación con los archivos DEX modificados. Y al llamar al comando zip obtenemos la versión final del APK, que queda por firmar. Firmaremos con la clave de depuración a través de apksigner para que la aplicación se pueda instalar en el dispositivo. La aplicación con la lógica SDK modificada está lista.

N ahorro


El algoritmo funciona para la mayoría de los casos, pero a veces no funcionará para reemplazar la implementación del SDK en la aplicación. Las razones de esto:

  1. Ofuscación ProGuard. Las reglas en el archivo del consumidor de la biblioteca evitan que ProGuard mueva las clases SDK. Pero si el desarrollador cancela estas instrucciones, entonces parte de las clases de la biblioteca pueden cambiar su paquete. En este caso, el algoritmo no funcionará, ya que el script no encontrará la ubicación de las clases del SDK anterior.
  2. Limitación del formato DEX. Si todo el código de la aplicación se almacena en un archivo DEX, lo que ha agotado casi por completo el límite de los métodos utilizados. Al reemplazar una versión de SDK en una aplicación con una versión con registro adicional, la cantidad de métodos aumentará. El límite será excedido. En formato DEX, el límite es 2 ^ 16.
  3. Proteja su aplicación del cambio. La aplicación tiene mecanismos incorporados para combatir la modificación. Por ejemplo, a través de la validación de firma de la aplicación. Al cambiar el APK, cambiamos su firma en consecuencia. Cuando se inicia la aplicación, comprueba la firma con la referencia y genera una excepción. Es especialmente difícil eliminar esta verificación si se coloca en la parte nativa.

Y togas


Automatizamos los pasos descritos en el artículo con un simple script bash. El script tiene fallas, pero acelera en gran medida el análisis de problemas complejos al integrar el SDK en aplicaciones asociadas. Aunque, rara vez usamos este enfoque, ya que a menudo encontramos una solución en las etapas anteriores.

De la conversión a smali, puede obtener beneficios adicionales: los archivos smali le permiten depurar la aplicación sin fuente. Para comenzar a depurar, debe generar un proyecto en Android Studio basado en los archivos pequeños de la aplicación y adjuntar el depurador al proceso de interés. Más detalles están escritos en este artículo .

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


All Articles