Verifique se um APK foi criado a partir do código-fonte fornecido

10

Para o mesmo aplicativo, eu tenho:

  • um APK de uma loja de aplicativos,
  • o que é reivindicado ser o código fonte da mesma versão. Com um script e estrutura bastante comuns, o Gradle constrói.

Quero verificar se o APK foi realmente criado a partir desse código-fonte ou não.
Como verificar isso?

Notas:

  • O APK não está ofuscado.
  • Não tenho motivos para confiar na assinatura de ninguém. Eu confio apenas no código fonte.
  • Eu já construí o aplicativo para mim, mas agora quero saber se o APK está bom ou não.
  • De preferência com ferramentas de linha de comando do Linux, mas qualquer ferramenta está OK.
Nicolas Raoul
fonte
2
Eu não tentei isso, mas você deve poder usar o Apktool para esta finalidade: faça engenharia reversa dos dois .apkarquivos e execute uma comparação nos diretórios resultantes. A única diferença então deve ser a assinatura (que não pode corresponder por razões óbvias). Pensando nisso: simplesmente descompactar os .apkarquivos e fazer uma comparação binária deve fazer o mesmo. Ambos seria, evidentemente exigem ter usado as mesmas versões de bibliotecas etc. durante a compilação, em primeiro lugar :)
Izzy
@ Izzy: " mesmas versões da biblioteca ": a versão da API está escrita no manifesto e na versão das bibliotecas no script Gradle, de modo que essa parte deve estar OK, eu acho. Uma lista de arquivos / pastas que podem ser ignorados tornaria essa uma ótima resposta (bônus para as linhas de comando reais).
Nicolas Raoul
11
Eu poderia fazer isso se estivesse no meu computador em casa, o que não estou atualmente. Mas para que isso seja uma "resposta honrosa", eu precisaria tentar primeiro primeiro :) Caso eu esqueça (e ninguém mais o fez antes de mim), sinta-se à vontade para me enviar outro ping (por exemplo, no bate-papo) em aproximadamente 8h10h :)
Izzy
@ Izzy O diffmétodo parece legal ... mas e se os caras da loja de aplicativos ofuscarem o APK durante a compilação?
Grimoire
IMHO é onde o Apktool entra em cena. Você verificou o link? Também dê uma olhada no LibRadar que usa isso. AFAIR ajuda a tirar o ofuscamento (algo deve, ou o LibRadar teria um trabalho árduo na detecção dessas bibliotecas).
Izzy

Respostas:

2

Você só pode fazer isso com construções reproduzíveis:

"Uma construção é reproduzível se for fornecido o mesmo código fonte, ambiente de construção e instruções de construção, qualquer parte pode recriar cópias idênticas bit a bit de todos os artefatos especificados."

Portanto, o desenvolvedor do aplicativo ou a loja de aplicativos precisa estar a bordo para que ele funcione.
Caso contrário, sua única opção é construir você mesmo.

Um exemplo de desenvolvedor que atualmente faz isso é o Open Whisper Systems: https://github.com/WhisperSystems/Signal-Android/wiki/Reproducible-Builds

andDevW
fonte
Muito interessante! Então, você tem certeza de que a comparação não pode ser feita sem que o desenvolvedor esteja a bordo? Infelizmente (mas compreensivelmente) a maioria dos aplicativos de código aberto não usa o Docker ou semelhante para compilações, eles são construídos apenas em qualquer sistema que o mantenedor execute.
Nicolas Raoul
Não precisa ser o desenvolvedor, desde que quem crie o aplicativo a partir da fonte permita recriar exatamente o ambiente de criação. Dependências podem ser um grande problema ao configurar esses tipos de builds.
precisa saber é o seguinte
"recrie exatamente o ambiente de construção": é possível adivinhar? Por exemplo, se, por algum motivo, a criação no Mac ou Linux produzir um APK diferente, posso adivinhar se o APK da loja de aplicativos foi construído no Mac ou Linux?
Nicolas Raoul
Não é possível adivinhar e ter resultados significativos. Eventualmente, isso ficará mais fácil de implementar e você verá mais e mais projetos de código aberto fazendo isso.
precisa saber é
1

Uma grande coisa sobre java e APKs é que você pode descompilar completamente o APK para o código-fonte java.

No entanto, não é garantido que o código fonte resultante seja idêntico.

Uma boa maneira de tentar combinar o código-fonte resultante com uma revisão conhecida é verificar quais modificações foram feitas diretamente antes e depois da confirmação conhecida no repositório e ver se essas modificações também estão presentes na fonte descompilada.

Para descompilar, use dex2jar e JD-Gui .

edit Acabei de notar que você queria ferramentas linux. Minha única experiência é com o Windows, mas tenho certeza que existem ferramentas semelhantes para o Linux.

Mark Ch
fonte
Se bem entendi, seu método é verificar qual foi a alteração mais recente no repositório do código-fonte, descompilar o APK e verificar manualmente se a alteração mais recente também é encontrada no código descompilado, certo? Abordagem interessante, mas isso não indica se um anúncio de call home ou incorporado foi adicionado à versão APK, certo?
Nicolas Raoul
11
Essa é uma abordagem que utilizei no escritório para tentar comparar um APK desconhecido a uma revisão de origem, o que foi bom o suficiente se você souber que pode confiar nos desenvolvedores. Mas, como você diz, provavelmente ainda é possível que uma parte não confiável oculte algo. Espero que alguém forneça uma resposta mais definitiva, que também seja útil para mim.
Mark Ch
Que tal você mesmo compilar a fonte no APK e depois descompilar novamente no código-fonte e compará-lo com a fonte descompilada do Play Store APK? Alguém já tentou isso?
Sergiy Belozorov 25/02/19
11
@SergiyBelozorov desculpe, eu não posso responder isso, eu realmente não trabalho mais com o Android, mas parece uma ótima idéia.
Mark Ch