
El marco de instrumentación binaria Redexer para bytecode Dalvik
Redexer es una herramienta de reingeniería que manipula binarios de aplicaciones Android. Esta herramienta es capaz de analizar un archivo DEX en una estructura de datos en memoria; inferir con qué parámetros la aplicación usa ciertos permisos (nombramos esta característica RefineDroid); modificar y volcar esa estructura de datos para producir un archivo DEX de salida (nombramos estas características Dr. Android, que significa Dalvik Rewriting for Android).
Esta herramienta está probada bajo OCaml 4.09.0 y Ruby 1.8.6(7), así que necesitas instalarlos (o versiones superiores de ellos).
Para manipular una firma SHA-1 (hash) en el formato DEX, utilizamos la biblioteca OCaml SHA a través de ocamlfind/findlib, un gestor de bibliotecas de OCaml. La forma más fácil de instalar ambos es usando OPAM, un gestor de paquetes de OCaml, que tiene ambos paquetes: OPAM ocamlfind y OPAM sha.
También puedes compilar y/o instalar ambos paquetes directamente. Si usas una máquina Linux, puedes encontrar fácilmente distribuciones.
Si no, por ejemplo, usando una Mac, necesitas compilarlo por ti mismo.
Puedes encontrar los códigos fuente originales aquí.
Compílalo ejecutando make, y enlaza el directorio resultante en el directorio
root site-lib de ocamlfind; o sudo make install.
Si usas un PC, necesitas instalar ocamlfind/findlib y FlexDLL primero. Asegúrate de que tus variables de entorno estén configuradas correctamente de la siguiente manera:
OCAMLLIB=C:\OCaml\lib
CAML_LD_LIBRARY_PATH=%OCAMLLIB%\stublibs
FLEXLINKFLAGS=-L%MinGW%\lib -L%MinGW%\lib\gcc\mingw32\N.N.N
Paquetes OPAM:
Android SDK (o fuentes)
Para desempaquetar y reempaquetar archivos apk, usamos apktool, una herramienta
de reingeniería de APK de código abierto. Como usa aapt, Android Asset Packaging Tool,
necesitas instalar Android SDK o fuentes. Además, usamos
zipalign, que también viene de Android SDK, para optimizar aplicaciones reescritas.
Puedes establecer las rutas a las herramientas base de Android agregando lo siguiente a tu perfil:
ANDROID_HOME=$HOME/android-sdk # tu propia ruta aquí!
export ANDROID_HOME
PATH=$PATH:$ANDROID_HOME/tools
PATH=$PATH:$ANDROID_HOME/platform-tools
PATH=$PATH:$ANDROID_HOME/build-tools/19.0.0 # número de versión instalada
export PATH
Los scripts principales están escritos en Ruby y requieren RubyGems, un gestor de paquetes de Ruby, y Nokogiri, una biblioteca XML para manipular archivos de manifiesto.
Si quieres ver gráficos (por ejemplo, grafo de llamadas, grafo de flujo de control, árbol de dominadores, etc.), necesitas instalar graphviz dot.
Para compilar redexer, ¡simplemente make! Puedes ver el binario redexer en el nivel superior.
$ make (clean)
Antes de usar la herramienta, la instalación del archivo de plataforma más reciente para apktool depende del usuario. Por ejemplo, necesitas hacer algo como
$ java -jar tools/apktool.jar if [archivo de plataforma adecuado]
También puedes generar documentos de la API en formato html.
$ make api
Puedes ver todas las opciones que proporciona la herramienta:
$ ruby scripts/cmd.rb -h
$ ruby scripts/cmd.rb --help
Al igual que dexdump en Android SDK, redexer te permite ver el interior del archivo dex dado en formato YAML.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd unparse [--to blah.yml]
Esta opción vuelca instrucciones para un método especificado.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dump_method --mtd cls.mtd
Esta característica sirve para probar los módulos de análisis y volcado de redexer. Probablemente genera un archivo dex idéntico.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd id [--to blah.dex]
También puedes ver estadísticas básicas sobre el archivo dex, por ejemplo, # instr.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd info
Esta opción imprime todos los nombres de clases definidos en el archivo dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes
Puede ser útil para buscar bibliotecas de terceros específicas, por ejemplo,
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes | egrep 'apache'
Esta opción imprime el uso de API en el archivo dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api [--sdk android.]
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api --sdk com.facebook.
¿No tienes curiosidad de cuán raramente se usan algunos opcodes en los bytecodes de Dalvik? Te mostrará el histograma de todos los opcodes, o puedes buscar con qué frecuencia se usa el opcode exacto en la aplicación dada.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd opstat [--op opcode1,opcode2,...]
Por ejemplo,
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat --op div-int/lit16,nop
Esta opción realiza un análisis de resolución de intenciones basado en propagación, e imprime las transiciones entre clases Activity.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd intent
Esta opción genera un archivo pdf que representa un grafo de llamadas del archivo dado. Si no especificas el nombre del pdf, se usará cg.pdf.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cg [--to blah.pdf] [--no-pdf]
Esta opción genera un archivo pdf que muestra un grafo de flujo de control del método dado. Agrega un nombre de método a un nombre de clase con punto: nombre_clase.nombre_método
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cfg --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Esta opción es similar a la característica anterior, excepto que representa el árbol de dominadores (post).
$ ruby scripts/cmd.rb target.(apk|dex) --cmd (p)dom --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Esta opción realiza un análisis clásico de flujo de datos hacia atrás.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd live --mtd cls.mtd
Esta opción realiza un análisis clásico de flujo de datos hacia adelante.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd const --mtd cls.mtd
Esta opción realiza un análisis clásico de flujo de datos hacia adelante.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd reach --mtd cls.mtd
Esta opción encuentra dependencias de clases.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dependants --mtd cls.mtd
Esta opción imprime el nombre de la actividad lanzadora del apk dado.
$ ruby scripts/cmd.rb target.apk --cmd launcher
Esta opción te permite saber qué componentes están expuestos al exterior.
$ ruby scripts/cmd.rb target.apk --cmd exported
Estas opciones imprimen los componentes básicos de Android declarados en el manifiesto.
$ ruby scripts/cmd.rb target.apk --cmd [activity | service | provider | receiver]
Esta opción explora las definiciones de diseño en los recursos e imprime vistas personalizadas.
$ ruby scripts/cmd.rb target.apk --cmd custom_views
Esta opción explora las definiciones de diseño en los recursos e imprime elementos Fragment.
$ ruby scripts/cmd.rb target.apk --cmd fragments
Esta opción explora las definiciones de diseño en los recursos e imprime Botones, junto con su id (o texto) así como el método de devolución de llamada (si existe).
$ ruby scripts/cmd.rb target.apk --cmd buttons
Esta opción imprime los permisos que usa el apk.
$ ruby scripts/cmd.rb target.apk --cmd permissions
Esta opción imprime qué versión SDK requiere el apk.
$ ruby scripts/cmd.rb target.apk --cmd sdk
Si no quieres desempaquetar el archivo apk, en realidad, puedes hacer lo mismo con una combinación de comandos:
$ aapt dump badging target.apk | grep 'targetSdkVersion' | tr -dc 0-9.\\n
Esta opción generaría un archivo dex que imprime un mensaje simple. Ese archivo dex se hace solo usando las API de redexer.
$ ruby scripts/cmd.rb --cmd hello
Comprueba su interior.
$ dexdump -d results/classes.dex
Si estás interesado, puedes probar ese archivo dex de la siguiente manera. Asume que la ruta a ANDROID_SDK está configurada.
// crear un jar temporal adecuado para la máquina virtual Dalvik
$ aapt add temp.jar results/classes.dex
// (opcional) si no creaste un avd, créalo.
$ android create avd -n myAVD1 -t android-8
// lanza tu emulador
$ emulator -avd myAVD1 &
// empuja el jar temporal
$ adb push temp.jar /data
// conéctate al shell adb
$ adb shell
// por último, ejecuta el dex
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar \
-classpath /data/temp.jar Hello
Hello, DEX
#
Esta es una variante de la característica de reescritura. Usando esta característica, puedes registrar
el comportamiento de las aplicaciones desde puntos de vista específicos. El archivo dex precompilado
para la biblioteca de registro se proporciona: data/logging.dex. Si quieres agregar más
características o utilidades, compílalo de la siguiente manera:
$ cd logging
$ gradle copyDex
$ cd ..
Luego, usa el siguiente comando:
$ ruby scripts/cmd.rb target.apk --cmd logging
trim.py puede capturar las secuencias de llamada-retorno de la aplicación instrumentada. (Deberías instrumentar primero la aplicación bajo prueba usando redexer.)
Si esos registros son lo suficientemente cortos, es decir, el teléfono (o emulador) puede contener toda la información en la memoria, puedes usar el modo fuera de línea del script:
$ ./scripts/trim.py -d
Ten en cuenta que todos los parámetros de línea de comandos se pasarán a adb logcat, y
por defecto, se pasa org.umd.logging:I *:S para filtrar registros irrelevantes.
Si los registros desbordan, debes usar el modo en línea:
$ ./scripts/trim.py
El script captura la interrupción de tecla, por lo que puedes finalizar el registro con Ctrl+C.
En cualquier modo, los registros se guardan en log.txt y se muestran en la pantalla de una vez. Por lo tanto, después de recopilar los registros, es posible que necesites mover ese archivo, por ejemplo:
$ mv log.txt app.scenario.txt
La característica de registro anterior es general en el sentido de que puedes especificar qué registrar
a nivel de método. (Consulta el módulo logging para más detalles.)
Sin embargo, esto a veces es demasiado verboso y puede inducir una degradación del rendimiento.
Esta característica está diseñada para registrar solo las interacciones del usuario. Usando esta
característica, puedes capturar solo eventos relacionados con la interfaz de usuario. De manera similar, se
proporciona el archivo dex precompilado para la biblioteca de registro: data/logging-ui.dex. Si quieres modificar
la verbosidad de la información de la interfaz de usuario, compílalo de la siguiente manera:
$ cd logging-ui
$ gradle copyDex
$ cd ..
Luego, usa el siguiente comando:
$ ruby scripts/cmd.rb target.apk --cmd logging_ui
La biblioteca de registro se hereda del servicio de accesibilidad de Android, que requiere
el consentimiento explícito del usuario. Por lo tanto, después de instalar el apk reescrito, ve a
Settings/Accessibility y activa el servicio UI Logging.
(Este paso puede verse similar a activar el modo de depuración del dispositivo.)
En el logcat, los mensajes con etiquetas org.umd.logging_ui.* son interacciones
entre el usuario y la aplicación bajo prueba.
Esta opción encuentra rutas de transición de componentes hacia llamadas a métodos objetivo.
$ ruby scripts/cmd.rb target.apk --cmd directed
Puedes especificar los métodos objetivo que se invocarán en data/directed.txt
Esas rutas de transición de componentes se utilizan para conducir aplicaciones para probar vulnerabilidades de seguridad en bibliotecas de terceros. Más detalles se describen en el siguiente artículo:
* Brahmastra: Driving Apps to Test the Security of Third-Party Components.
R. Bhoraskar, et al., In 23rd Usenix Security Symposium (Security '14).
withTimeout.rb puede construir un archivo de omisión para una aplicación automáticamente. Este script ejecuta cmd.rb con un tiempo de espera específico, utilizado para limitar el tiempo dedicado a instrumentar cualquier clase individual. Esta es una solución temporal para la clase ocasional que se queda en un bucle durante la instrumentación. Cuando este script encuentra una clase que falla, la agrega al archivo de omisión y continúa desde donde se quedó. Una vez que withTimeout haya terminado, habrá un archivo llamado [nombre del apk]-skip.txt en el directorio data, que se puede usar para construir una aplicación completamente instrumentada para ese apk. Para usar withTimeout, simplemente llama
$ ruby scripts/withTimeout.rb TIMEOUT COMMANDS
Donde TIMEOUT es la duración del tiempo de espera que deseas en segundos (300 es recomendado) y COMMANDS son todas las entradas regulares de línea de comandos que pasarías a scripts/cmd.rb para el apk.