Ingeniería inversa de aplicaciones Android 101

  1. Introducción
  2. Fundamentos de las aplicaciones Android
  3. Cómo empezar a invertir aplicaciones Android
    • Ejercicio 1
  4. Ingeniería inversa de aplicaciones Android – Bytecode DEX
    • Ejercicio 2
    • Ejercicio 3
    • Ejercicio 4
  5. Reverse Engineering Android Apps – Bibliotecas nativas
    • Ejercicio 5
    • Ejercicio 6
  6. Ingeniería inversa de aplicaciones Android – Ofuscación
    • Ejercicio 7
  7. Conclusión

Construir una App

Una de mis mayores sugerencias para la gente que busca hacer ingeniería inversa de cosas, sean lo que sean, es intentar construir lo que quieres revertir. En el caso de Android, tienes suerte porque hay muchos recursos gratuitos disponibles para construir tu primera aplicación. Si nunca has construido una aplicación para Android, te sugiero que empieces por ahí. Elige cualquiera de los tutoriales y vídeos disponibles que despierten tu interés y ponte a construir. Cuando entiendes cómo un desarrollador construye algo, hace que sea mucho más fácil entender cómo hacer ingeniería inversa.

Revisión de fundamentos

¡Genial! Has construido una aplicación o aprendido los principios básicos de desarrollo de aplicaciones Android. Aquí hay un repaso de algunos de los puntos importantes. Esta página «Fundamentos de la aplicación» en los docs de los desarrolladores de Android es una gran revisión.

  • Las aplicaciones de Android están en el formato de archivo APK. APK es básicamente un archivo ZIP. (Puedes renombrar la extensión del archivo a .zip y usar unzip para abrir y ver su contenido.)
  • Contenido del APK (No es exhaustivo)
    • AndroidManifest.xml
    • META-INF/
      • ¡El certificado vive aquí!
    • classes.dex
      • Dalvik bytecode para la aplicación en el formato de archivo DEX. Este es el código Java (o Kotlin) que la aplicación ejecutará por defecto.
    • lib/
      • ¡Las bibliotecas nativas para la aplicación, por defecto, viven aquí! Bajo el directorio lib/, están los directorios específicos de la cpu. Ej: armeabi, mips,
    • assets/
      • Cualquier otro archivo que pueda necesitar la aplicación.
      • Aquí se pueden incluir bibliotecas nativas adicionales o archivos DEX. Esto puede ocurrir especialmente cuando los autores de malware quieren intentar «ocultar» el código adicional, nativo o Dalvik, no incluyéndolo en las ubicaciones por defecto.

Dalvik & Smali

La mayoría de las aplicaciones Android están escritas en Java. Kotlin también es compatible e interoperable con Java. Para facilitar, para el resto de este taller, cuando me refiero a «Java», se puede asumir que me refiero a «Java o Kotlin». En lugar de que el código Java se ejecute en la máquina virtual Java (JVM) como las aplicaciones de escritorio, en Android, el Java se compila en el formato bytecode Dalvik Executable (DEX). En versiones anteriores de Android, el bytecode era traducido por la máquina virtual Dalvik. Para versiones más recientes de Android, se utiliza el Android Runtime (ART).
Si los desarrolladores, escriben en Java y el código se compila a bytecode DEX, para hacer ingeniería inversa, se trabaja en sentido contrario.

Smali es la versión legible para humanos del bytecode Dalvik. Técnicamente, Smali y baksmali son el nombre de las herramientas (ensamblador y desensamblador, respectivamente), pero en Android, a menudo usamos el término «Smali» para referirnos a las instrucciones. Si has hecho ingeniería inversa o arquitectura de ordenadores sobre código C/C++ compilado. SMALI es como el lenguaje ensamblador: entre el código fuente de nivel superior y el bytecode.

Para el siguiente código Hello World Java:

public static void printHelloWorld() {System.out.println("Hello World")}

El código Smali sería:

.method public static printHelloWorld()V.registers 2sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;const-string v1, "Hello World"invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)Vreturn-void.end method

El conjunto de instrucciones Smali está disponible aquí.

La mayoría de las veces, cuando se hace ingeniería inversa de aplicaciones Android, no será necesario trabajar en Smali. La mayoría de las aplicaciones pueden ser elevadas a un nivel aún más alto, descompilando Java. Como todas las herramientas, los descompiladores de Java pueden tener errores. Mi sugerencia es que siempre que la salida descompilada de Java parezca cuestionable, mire la salida de Smali. Trabaje línea por línea con la referencia de la instrucción para averiguar lo que el código está haciendo.

Para obtener el Smali de DEX, puede utilizar la herramienta baksmali (desensamblador) disponible en https://github.com/JesusFreke/smali/wiki. La herramienta smali le permitirá ensamblar smali de nuevo a DEX.

Puntos de entrada de la aplicación

Uno de los puntos más importantes de la ingeniería inversa es saber dónde comenzar su análisis y los puntos de entrada para la ejecución del código es una parte importante de eso.

Actividad del lanzador

La actividad del lanzador es lo que la mayoría de la gente piensa que es el punto de entrada a una aplicación Android. La actividad del lanzador es la actividad que se inicia cuando un usuario hace clic en el icono de una aplicación. Puedes determinar la actividad del lanzador mirando el manifiesto de la aplicación. La actividad de lanzamiento tendrá los siguientes intentos MAIN y LAUNCHER listados.

Tenga en cuenta que no todas las aplicaciones tendrán una actividad de lanzamiento, especialmente las aplicaciones sin una UI. Ejemplos de aplicaciones sin una UI (y por lo tanto una actividad de lanzamiento) son las aplicaciones preinstaladas que realizan servicios en segundo plano, como el buzón de voz.

<activity android:name=".LauncherActivity"><intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity>

Servicios

Los servicios se ejecutan en segundo plano sin una UI. Hay un sinfín de formas en las que se pueden iniciar y, por tanto, son un punto de entrada para las aplicaciones. La forma predeterminada en que un servicio puede iniciarse como punto de entrada a una aplicación es a través de Intents.

Cuando se llama a la API startService para iniciar un Servicio, se ejecuta el método onStart del Servicio.

Receptores de difusión

Las difusiones pueden pensarse como un sistema de mensajería y los receptores de difusión son los oyentes. Si una aplicación ha registrado un receptor para una emisión específica, el código en ese receptor se ejecuta cuando el sistema envía la emisión. Hay dos maneras en que una aplicación puede registrar un receptor: en el Manifiesto de la aplicación o registrado dinámicamente en el código de la aplicación utilizando la llamada a la API registerReceiver().

En ambos casos, para registrar el receptor, se establecen los filtros de intención para el receptor. Estos filtros de intención son las emisiones que deben desencadenar el receptor.

Cuando se envían las emisiones específicas para las que está registrado el receptor, se ejecuta onReceive en la clase BroadcastReceiver.

Componentes exportados (Servicios & Actividades)

Los servicios y las actividades también se pueden «exportar», lo que permite que otros procesos del dispositivo inicien el servicio o lancen la actividad. Los componentes se exportan estableciendo un elemento en el manifiesto como el siguiente. Por defecto, android:exported="false" a menos que este elemento se establezca como verdadero en el manifiesto o se definan filtros de intención para la Actividad o Servicio.

<service android:name=".ExampleExportedService" android:exported="true"/><activity android:name=".ExampleExportedActivity" android:exported="true"/>

Subclase de Aplicación

Las aplicaciones Android pueden definir una subclase de Aplicación. Las aplicaciones pueden, pero no tienen que definir una subclase personalizada de Aplicación. Si una aplicación Android define una subclase de Application, esta clase se instanciará antes que cualquier otra clase de la aplicación.

Si el método attachBaseContext se define en la subclase de Application, se llamará primero, antes que el método onCreate.

NEXT > 3. Introducción a la inversión de aplicaciones Android

Deja una respuesta

Tu dirección de correo electrónico no será publicada.