En el artículo anterior revisamos cómo extraer un fichero APK, en esta ocasión explicaremos cómo parchear las Apps de Android.
Una vez tenemos el fichero APK de la aplicación a analizar, es posible que detectemos una serie de comportamientos o restricciones que presenta la aplicación y que nos dificulta su análisis. Para evadir estas restricciones hay varias opciones:

  • Instrumentación dinámica de la aplicación
  • Parcheo del código Smali

Según la naturaleza de la restricción puede ser más interesante una opción que la otra, aunque desde Sidertia solemos preferir el parcheo del código Smali.
Las aplicaciones Android contienen ficheros .dex (Dalvik Executable). Estos ficheros se pueden descompilar para obtener un código de bajo nivel llamado Dalvik Bytecode. Utilizando smali/baksmali (ensamblador/desensamblador) se puede obtener una representación en un lenguaje de bajo nivel con el que se puede trabajar más fácilmente, al cual llamaremos código Smali.

Las aplicaciones Android contienen ficheros .dex (Dalvik Executable). Estos ficheros se pueden descompilar para obtener un código de bajo nivel llamado Dalvik Bytecode. Utilizando smali/baksmali (ensamblador/desensamblador) se puede obtener una representación en un lenguaje de bajo nivel con el que se puede trabajar más fácilmente, al cual llamaremos código Smali. Para este ejemplo, vamos a utilizar la APP InsecureBankv2, descargable desde: 

La cual cuenta con detección de rooteo del dispositivo y es la restricción que vamos a parchear:

El primer paso es ejecutar la utilidad apktool para desempaquetar el fichero APK y la utilidad enjarify para obtener una aproximación del código fuente de la aplicación (desde Sidertia recomendamos enjarify frente a dex2jar). Para realizar esta operación usamos el siguiente comando:

				
					apktool d <FICHERO_APK> && enjarify <FICHERO_APK>
				
			

Utilidad apktool

 

Se utiliza la opción “d” de apktool para desempaquetar la aplicación. Apktool creará una carpeta llamada como el fichero, en este caso base y enjarify creará un fichero llamado base-enjarify.jar:

 

En este caso vamos a buscar la cadena que aparece en la pantalla, aunque hay que saber que el hecho de encontrar el punto donde se produce el comportamiento o restricción puede llegar a ser más difícil que el propio parcheo. Para buscar esta cadena, ejecutamos el siguiente comando dentro del directorio que se creó por la ejecución de apktool:

				
					grep -iR "<CADENA_A_BUSCAR> "
				
			

 

Se utiliza la opción -iR de grep para que se realice una búsqueda recursiva por los diferentes subdirectorios y que la búsqueda no discrimine entre mayúsculas y minúsculas. En este punto ya sabemos que la cadena está escrita tal cual en el código (no se usa el fichero strings.xml para referenciar la cadena) y sabemos también qué fichero la contiene.

Con la utilidad JD-GUI y el fichero resultado de enjarify podemos ver el código fuente de la clase PostLogin:

 

Aunque enjarify ha dado un fallo en la función showRootStatus, se observan las siguientes cuestiones:

  • En la línea 7 se llama a la función doesSuperuserApkExist() que comprueba si está instalado el apk.
  • En la línea 16 se llama a la función doesSUexist() que comprueba si el comando “su” está disponible en el sistema

La representación de esta función en el código Smali es la siguiente:

En la imagen anterior se detalla en rojo la función doesSuperuserApkExist() y en caso de que esta función devuelva un resultado verdadero, envía la ejecución a la sección “cond_0”, donde se establece el valor de la variable local v0 al valor de v1, que es 1, por tanto v0 tomará el valor 1 y a continuación la ejecución entra en la sección “goto_0”.

Se detalla en amarillo la función doesSUexist() y en caso de que el resultado sea falso, envía la ejecución a la sección “cond_1”, donde se establece la variable local v0 con el valor 0 y se envía la ejecución a la sección “goto_0” (detallado en naranja).

En la sección “goto_0” se comprueba si el valor de la variable local v0 es igual al valor de v1. En caso de no ser igual, la ejecución va a la sección “cond_2” y se establece el mensaje de que el dispositivo no está rooteado. En caso de ser igual, la ejecución continúa y se establece el mensaje de que el dispositivo sí está rooteado.

En este momento, cuando ya tenemos un conocimiento de las operaciones que se ejecutan, aparecen varias opciones para modificar el comportamiento, en este caso vamos a optar por la modificación más sencilla que consiste en introducir un salto de ejecución al principio de la función, directamente a la sección “cond_2”. Por tanto, el inicio de la función cambia de la siguiente forma:

Llegados a este punto, lo que queda es volver a empaquetar la aplicación, firmarla, instalarla y comprobar si la modificación ha surtido el efecto que buscábamos.

Estas operaciones se explicarán en otra entrada.