Verifique que se haya creado un APK a partir del código fuente dado

10

Para la misma aplicación, tengo:

  • un APK de una tienda de aplicaciones,
  • lo que se afirma que es el código fuente de la misma versión. Con un guión y estructura de construcción de Gradle bastante habitual.

Quiero verificar si el APK realmente se creó a partir de ese código fuente o no.
¿Cómo verificar eso?

Notas:

  • El APK no está ofuscado.
  • No tengo motivos para confiar en la firma de nadie. Solo confío en el código fuente.
  • Ya construí la aplicación para mí, pero ahora quiero saber si el APK estaba bien o no.
  • Preferiblemente con herramientas de línea de comandos de Linux, pero cualquier herramienta está bien.
Nicolas Raoul
fuente
2
No lo he intentado, pero debería poder usar Apktool para este propósito: aplique ingeniería inversa a ambos .apkarchivos, luego ejecute un diff contra los directorios resultantes. La única diferencia debería ser la firma (que no puede coincidir por razones obvias). Pensando en ello: simplemente descomprimir los .apkarchivos y hacer una diferencia binaria debería hacer lo mismo. Por supuesto, ambos requerirían haber usado las mismas versiones de biblioteca, etc. al compilar en primer lugar :)
Izzy
@Izzy: "las mismas versiones de la biblioteca ": la versión de la API está escrita en el manifiesto y la versión de las bibliotecas en el script de Gradle, por lo que esa parte debería estar bien, supongo. Una lista de archivos / carpetas que pueden ignorarse sería una excelente respuesta (bonificación por las líneas de comando reales).
Nicolas Raoul
1
Podría hacerlo si estuviera en mi computadora en casa, lo que no estoy haciendo actualmente. Pero para que esa sea una "respuesta honorable", primero tendría que intentarlo yo mismo :) En caso de que lo olvide (y nadie más lo hizo antes que yo), siéntase libre de enviarme otro ping (por ejemplo, en el chat) 8..10h :)
Izzy
@Izzy El diffmétodo parece ordenado ... pero ¿qué pasa si los chicos de la tienda de aplicaciones ofuscaron el APK mientras lo compilaban?
Grimorio
En mi humilde opinión, ahí es donde entra en juego Apktool. ¿Has revisado el enlace? También eche un vistazo a LibRadar que usa esto. AFAIR ayuda a des-ofuscar (algo debe, o LibRadar tendría un trabajo difícil para detectar esas bibliotecas).
Izzy

Respuestas:

2

Solo puede hacer esto con compilaciones reproducibles:

"Una compilación es reproducible si se le da el mismo código fuente, entorno de compilación e instrucciones de compilación, cualquier parte puede recrear copias idénticas bit a bit de todos los artefactos especificados".

Por lo tanto, el desarrollador de la aplicación o la tienda de aplicaciones deben estar a bordo para que funcione.
De lo contrario, su única opción es construirlo usted mismo.

Un ejemplo de un desarrollador que actualmente hace esto es Open Whisper Systems: https://github.com/WhisperSystems/Signal-Android/wiki/Reproducible-Builds

andDevW
fuente
¡Muy interesante! Entonces, ¿estás seguro de que la comparación no se puede hacer sin que el desarrollador esté a bordo? Desafortunadamente (pero es comprensible) la mayoría de las aplicaciones de código abierto no usan Docker o similar para las compilaciones, solo están construidas en cualquier sistema que el mantenedor ejecute.
Nicolas Raoul
No tiene que ser el desarrollador, siempre y cuando quien construya la aplicación desde la fuente haga posible recrear su entorno de compilación exactamente. Las dependencias pueden ser un dolor enorme al configurar este tipo de compilaciones.
andDevW
"recrear su entorno de construcción exactamente": ¿Es posible adivinar? Por ejemplo, si por alguna razón construir en Mac o Linux produce un APK diferente, ¿puedo adivinar si el APK de la tienda de aplicaciones se ha creado en Mac o Linux?
Nicolas Raoul
No es posible adivinar y obtener resultados significativos. Eventualmente, esto será más fácil de implementar y verá más y más proyectos de código abierto que lo hacen.
andDevW
1

Una gran cosa acerca de Java y APK es que puedes descompilar completamente el código fuente de APK a Java.

Sin embargo, no se garantiza que el código fuente resultante sea idéntico.

Una buena forma de intentar hacer coincidir el código fuente resultante con una revisión conocida es verificar qué modificaciones se realizaron directamente antes y después de la confirmación conocida en el repositorio, y ver si esas modificaciones también están presentes en la fuente descompilada.

Para descompilar, use dex2jar y JD-Gui .

editar Acabo de notar que querías herramientas de Linux. Mi única experiencia es con Windows, pero estoy seguro de que existen herramientas similares para Linux.

Mark Ch
fuente
Si entiendo correctamente, su método es verificar cuál fue el último cambio en el repositorio del código fuente, luego descompilar el APK y verificar manualmente si el último cambio también se encuentra en el código descompilado, ¿verdad? Enfoque interesante, pero eso no me dirá si se ha agregado un anuncio de llamada o incrustado a la versión APK, ¿verdad?
Nicolas Raoul
1
Este es un enfoque que he usado en la oficina para tratar de hacer coincidir un APK desconocido con una revisión de origen, que ha sido lo suficientemente bueno si sabes que puedes confiar en los desarrolladores. Pero como usted dice, es probable que una parte no confiable pueda colarse. Espero que alguien proporcione una respuesta más definitiva, también sería útil para mí.
Mark Ch
¿Qué tal compilar la fuente en el APK usted mismo, luego descompilarlo nuevamente en el código fuente y compararlo con la fuente descompilada del APK de Play Store? ¿Alguien ha intentado esto?
Sergiy Belozorov
1
@SergiyBelozorov lo siento, no puedo responder esto, ya no trabajo con Android, pero parece una muy buena idea.
Mark Ch