Como diagnosticar problemas de integração do SDK. A experiência da equipe de desenvolvimento do Yandex Mobile Ads SDK

Olá pessoal! Meu nome é Dmitry Fisko, estou desenvolvendo o SDK do Yandex Mobile Ads. Nossa biblioteca foi projetada para gerar receita com aplicativos móveis nas plataformas Android e iOS. Hoje, quero falar sobre como simplificamos a análise de erros complexos de integração do SDK em aplicativos Android. Talvez nossa experiência seja útil para você.

Nossos usuários - desenvolvedores de aplicativos móveis - nem sempre leem a documentação; portanto, às vezes, eles apresentam maneiras complexas de usar o SDK. A integração incorreta pode reduzir a eficácia da publicidade e, portanto, reduzir a receita do desenvolvedor. Para ajudar os desenvolvedores a monetizar melhor os aplicativos, criamos um sistema de monitoramento proativo que analisa o desempenho de um aplicativo móvel. Se aprendermos sobre o problema por meio do monitoramento, entraremos em contato com os desenvolvedores e ajudá-los a encontrar a fonte do problema e resolvê-lo.

Infelizmente, nem todos os erros de integração do SDK podem ser identificados pelo monitoramento. Se tal situação surgir, recorremos ao parceiro para esclarecer os detalhes da integração. Em seguida, tentamos determinar a causa dos problemas e ajudar a resolvê-los. Se mesmo essas informações não forem suficientes para determinar a causa dos erros, solicitamos ao parceiro permissão para fazer a engenharia reversa do aplicativo. Após a permissão, começamos a ver o trabalho do SDK de publicidade no aplicativo como uma caixa preta. Visualizamos a atividade da rede por meio de um proxy, verificamos a exibição de exibições de publicidade por meio do Inspetor de layout etc.

A visualização da atividade de rede de um aplicativo a partir do Android 7.0 é problemática, pois o sistema, por padrão, não confia nos certificados definidos pelo usuário. A instalação do certificado é necessária para visualizar o tráfego SSL do aplicativo através de um proxy. Isso resolverá o problema iniciando o aplicativo nas versões do Android anteriores à 7.0 ou adicionando network_security_config ao aplicativo, por exemplo, através do Apktool. Você pode exibir a exibição de exibições de publicidade por meio do utilitário Layout Inspector executando o aplicativo em um emulador ou em um dispositivo. Nesse caso, você precisa modificar o arquivo AndroidManifest.xml adicionando o atributo debuggable = true por meio do Apktool.

Se o método da caixa preta não for suficiente e o problema não puder ser reproduzido, você poderá examinar a lógica do aplicativo. Para fazer isso, você pode usar os utilitários de descompilação do APK, como JADX , Bytecode Viewer . Mas muitas vezes essa abordagem leva muito tempo e nem sempre leva a um resultado. Portanto, para entender rapidamente como o aplicativo usa o SDK de dentro para fora, criamos um script para substituir uma nova implementação do SDK em um aplicativo já criado.

Instalando uma nova implementação do SDK em um aplicativo


A alteração do código do SDK permite incorporar o código arbitrário no aplicativo por meio das classes da versão modificada do SDK e, por exemplo, ativar o modo de log adicional. O algoritmo de operação é o seguinte. Script:

  1. desmonta arquivos DEX de aplicativos em pequenas empresas;
  2. converte o arquivo JAR da nova versão do SDK em smali;
  3. substitui a implementação de arquivos smali SDK nos arquivos de aplicativos smali;
  4. Remonta o aplicativo com a nova versão do SDK.


Desmontar arquivos DEX de aplicativos em pequenas empresas


Você precisa decompor o aplicativo, dividi-lo em unidades menores, para poder alterar o código das classes do SDK sem alterar o código do aplicativo. Como abordar o aplicativo montado? Desmonte o DEX em arquivos smali.

No Android, o aplicativo armazena o código nos arquivos DEX. Você pode extraí-los do aplicativo por meio do utilitário descompactar, pois o APK é um arquivo comum com conteúdo estruturado. Os arquivos DEX têm um formato binário para empacotamento de código mais denso em comparação aos JARs. Devido à natureza binária do DEX, ele é desumano, portanto, alterar o próprio DEX é irracional. A primeira coisa que vem à mente é descompilar o DEX em Java. Essa conversão é possível, mas não é trivial e ocorre com a perda de funcionalidade do código. Portanto, usaremos a tradução para o código smali. A conversão para smali permite transferir com precisão as instruções do DEX de forma legível por humanos, com a possibilidade de conversão subsequente em código viável.

Chamar o utilitário smali converte o DEX em um conjunto de classes no código smali. Nesse caso, o arranjo inicial de classes por subpacotes é preservado.


Convertendo o novo SDK em smali


Vamos preparar uma versão de substituição do SDK. Para garantir a reprodutibilidade do problema, criaremos uma versão do SDK com o log ativado com base na mesma versão que já está integrada ao aplicativo. Uma das maneiras mais fáceis de descobrir a versão conectada do SDK de anúncios para celular do Yandex no aplicativo é exibir o conteúdo do método na classe MobileAds.getLibraryVersion () por meio do Apk Analizer no Android Studio. Depois de descobrir a versão usada do SDK de publicidade, passamos para o ramo desta versão e coletamos a versão da biblioteca com log adicional. Como resultado, obtemos um arquivo AAR. Ele contém recursos e código da biblioteca. No arquivo AAR, estamos interessados ​​apenas no código no arquivo JAR, pois não há recursos externos em nosso SDK: todos os recursos são incorporados diretamente ao código ou são provenientes do back-end. A falta de arquivos de recursos simplifica a integração do SDK no IDE sem o suporte de sistemas de compilação modernos.

Para alterar a versão do SDK no aplicativo para um novo, trazemos o AAR para o mesmo estado que o aplicativo desmontado, ou seja, a partir do AAR, obtemos um conjunto de arquivos smali. A conversão ocorre ao longo da cadeia: AAR → JAR → DEX → SMALI:

  1. do AAR usando o utilitário descompactar, extraímos o JAR com o código;
  2. Convertemos JAR em DEX por meio do utilitário dxdump do Android SDK Tools;
  3. obtemos os arquivos no código smali usando o utilitário smali com o arquivo DEX como parâmetro.


Implementação do SDK


Depois de recebermos os pequenos arquivos do aplicativo e do SDK com os logs, substituímos a implementação do SDK por uma nova. Em seguida, reconstruímos o aplicativo. Ao transmitir para smali, as classes resultantes mantêm sua localização por subpacotes. Portanto, se o pacote em que as classes do SDK estão localizadas for conhecido, será fácil distinguir a classe da biblioteca das classes do aplicativo. As classes SDK podem ser distribuídas por vários DEXs. Portanto, o algoritmo pelo qual a implementação do SDK é substituída difere de um aplicativo com um ou vários arquivos DEX.

E o algoritmo para substituir a implementação do SDK em um aplicativo por um DEX


Em um único aplicativo DEX, simplesmente copiamos as novas classes smali do SDK sobre todas as classes de aplicativos e geramos um DEX modificado. Você pode gerar um arquivo DEX usando o utilitário baksmali. O diretório com os arquivos de pacote de classes no código smali é alimentado na entrada do utilitário. Depois de passar por baksmali os arquivos smali combinados do aplicativo e o novo SDK, obtemos um arquivo DEX modificado com a lógica do SDK alterada.


E o algoritmo para substituir a implementação do SDK em um aplicativo pelo MultiDex


Para um aplicativo com MultiDex, adicione um SDK separado ao novo DEX e remova a versão anterior do SDK do restante dos arquivos DEX do aplicativo. Adicionar uma nova versão do SDK a DEXs individuais contornará a limitação no número de métodos no formato DEX. O MultiDex carregará automaticamente o arquivo DEX adicionado com o código SDK, se for nomeado corretamente. O MultiDex procura por arquivos DEX por sua vez, usando o índice no final do arquivo: primeiro dex1, depois dex2 - e assim por diante.Se você nomear o arquivo com um índice incremental, o MultiDex o carregará automaticamente na máquina virtual. Assim, por meio do baksmali, geraremos arquivos DEX com base nos arquivos smali de aplicativos recebidos anteriormente, mas com classes excluídas da versão antiga do SDK. E também colete um arquivo DEX adicional com uma versão modificada do SDK, incrementando o índice no nome do arquivo DEX.


Recrie o aplicativo com a nova versão do SDK


Temos arquivos DEX de aplicativos com uma versão modificada do SDK. O problema é pequeno: substituiremos os arquivos DEX no arquivo APK originalmente descompactado do aplicativo pelos arquivos DEX modificados. E, chamando o comando zip, obtemos a versão final do APK, que ainda precisa ser assinada. Assinaremos com a tecla debug via apksigner para que o aplicativo possa ser instalado no dispositivo. O aplicativo com a lógica SDK modificada está pronto.

N Saving


O algoritmo funciona na maioria dos casos, mas às vezes não funciona para substituir a implementação do SDK no aplicativo. As razões para isso:

  1. Ofuscação ProGuard. As regras no arquivo de consumidor da biblioteca impedem o ProGuard de mover as classes do SDK. Mas se o desenvolvedor cancelar essas instruções, parte das classes da biblioteca poderá alterar seu pacote. Nesse caso, o algoritmo não funcionará, pois o script não encontrará o local das classes do antigo SDK.
  2. Limitação do formato DEX. Se todo o código do aplicativo estiver armazenado em um arquivo DEX, que esgotou quase completamente o limite dos métodos usados. Ao substituir uma versão do SDK em um aplicativo por uma versão com log adicional, o número de métodos aumentará. O limite será excedido. No formato DEX, o limite é 2 ^ 16.
  3. Proteja seu aplicativo contra alterações. O aplicativo possui mecanismos internos para combater a modificação. Por exemplo, através da validação da assinatura do aplicativo. Ao alterar o APK, alteramos sua assinatura. Quando o aplicativo é iniciado, ele verifica a assinatura na referência e lança uma exceção. É especialmente difícil remover essa verificação se ela for colocada na parte nativa.

E togas


Automatizamos as etapas descritas no artigo com um script bash simples. O script possui falhas, mas acelera bastante a análise de problemas complexos ao integrar o SDK nos aplicativos parceiros. Porém, raramente usamos essa abordagem, pois geralmente encontramos uma solução em estágios anteriores.

Desde a conversão para smali, você pode obter benefícios adicionais: os arquivos smali permitem depurar o aplicativo sem fonte. Para iniciar a depuração, você precisa gerar um projeto no Android Studio com base nos pequenos arquivos do aplicativo e anexar o depurador ao processo de seu interesse. Mais detalhes estão escritos neste artigo .

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


All Articles