lunes, 12 de septiembre de 2016

¿Como actualizar un Gear S2 sin un dispositivo Android compatible?


La respuesta corta es: por cojones.

Antes de nada, decir que después de tanto tiempo sin escribir en el blog, me apetecía contar esto, aunque técnicamente no es demasiado complicado. Quizás a partir de ahora escriba con más frecuencia, ya que, al menos, tengo pensada otra entrada más sobre Yomvi (el nuevo Movistar+).

Empecemos con esta entrada!

Hace unas semanas Samsung lanzó su aplicación de administración de su smartwatch, el Gear S2, para iOS. Hacía mucho tiempo que la estaba esperando, así que en cuanto me enteré de que habían lanzado el programa de pruebas, me registré para probarla. Después de ser aceptado e instalar la aplicación, estuve durante un rato intentado sin éxito conectar mi reloj a la aplicación. Entonces, buscando por internet, me di cuenta de que la versión del firmware de mi reloj era demasiado antigua, tan antigua que no era posible actualizarlo por Wifi. Al parecer, el único modo de actualizarlo era utilizando la aplicación de Android, ya que al ser una versión antigua de firmware, esta no era compatible con la app de iOS.

En este punto, surgen los problemas, ya que no dispongo de ningún dispositivo "compatible" con la aplicación. Los requisitos de la aplicación son:


  1. Tener una versión de Android mayor o igual a la 4.4
  2. Tener un dispositivo con al menos 1.5GB de RAM

Podéis ver aquí una lista con los dispositivos compatibles.

Como podemos observar, hay una gran cantidad de dispositivos compatibles (notese la ironía).

Bien, como os imaginais, no tengo un dispositivo "compatible", pero si que dispongo de un Xperia M2, que estaba seguro que era igualmente suficiente para utilizar la app.

Visto lo visto, estaba claro que si quería actualizar mi reloj y que sirviese para algo tenía que buscarme la vida por mi cuenta, y eso hice. Lo primero que se me ocurrió fue obtener el APK de la aplicación. Ya que tenía la app instalada, la obtuve de mi dispositivo utilizando ADB. Los comandos necesario para ello son:

adb shell pm list packages

Con el obtendremos la lista de paquetes instalados en nuestro dispositivo. Podemos mejorar el comando si utilizamos: adb shell pm list packages | grep samsung. De esta forma nos aparecerá directamente el paquete que nos interesa, cuyo nombre es: com.samsung.android.app.watchmanager.

El siguiente comando: 

adb shell pm path com.samsung.android.app.watchmanager

Que nos devolverá la ruta de nuestro dispositivo en la que podemos encontrar el APK.

Y finalmente usaremos:

adb pull com.samsung.android.app.watchmanager.apk ./destino

Para descargar el APK en la carpeta "destino".

Con esto, ya tendremos en nuestro PC el APK de la aplicación. El siguiente paso es utilizar una herramienta para descompilar el APK y obtener los ficheros de código Smali. Para ello, yo he utilizado apktool, en su versión 2.0.3 (podéis descargar su última versión en: https://ibotpeaches.github.io/Apktool/). Para descompilar simplemente es necesario utilizar el siguiente comando:

java -jar apktool.jar d com.samsung.android.app.watchmanager.apk

Una vez ejecutado, nos generará una carpeta con todos los recursos de la aplicación, incluyendo lo que nos interesa, el código Smali. 

Después de un rato mirando el código, nos daremos cuenta que existe una clase llamada "HostManagerUtils", que contiene un método que parece interesante: isSupportedInHostDevice. Efectivamente, este método devuelve true o false (1 ó 0) en función de si el dispositivo es compatible o no, es decir, si cumple los requisitos anteriormente indicados. 

Llegados a este punto, existen dos opciones en función de las posibilidades de vuestro dispositivo:

  1. Si está rooteado, utilizar alguna herramienta que permita hookear funciones, de modo que podamos modificar durante la ejecución el resultado de esta función. En mi caso he utilizado Frida (http://frida.re/)
  2. Si no está rooteado, modificar el código Smali para que siempre devuelva verdadero.

Yo utilicé Frida, puesto que mi dispositivo estaba rooteado y es más rápido que compilar la aplicación e instalarla, sobretodo la primera vez, cuando lo que queremos es comprobar si realmente esa función hace lo que parece. El script de Frida que he utilizado lo dejo aquí. Podéis utilizar la documentación de Frida para ver como se instala y como utilizar Frida en vuestro dispositivo (http://frida.re/docs).

Para la segunda opción, necesitaremos modificar el código, compilar e instalar de nuevo la aplicación. Como podemos observar en el código de la función "isSupportedInHostDevice", esta es bastante extensa, puesto que comprueba la cantidad de RAM y versión del sistema operativo. Nuestra modificación será realmente simple, al comienzo devolveremos directamente verdadero, y ya está.



Como vemos en la imagen, al inicio he modificado la inicialización de v0, para que en lugar de inicializarse a 0 (false) se inicialice a 1 (true), e inmediatamente después devuelvo v0. Con esto siempre se devuelve verdadero.

Ahora solamente resta compilar, firmar e instalar. Para compilar, utilizaremos de nuevo apktool, en este caso utilizaremos el comando (en el directorio en el que nos ha descompilado la app):

java -jar apktool.jar b -f -d .

Con esto nos construirá un nuevo APK en el directorio "dist". Antes de instalar ese APK, necesitaremos firmarlo. Para ello, usaremos la herramienta signapk (disponible aquí), con el siguiente comando:

signapk.jar testkey.x509.pem testkey.pk8 dist/com.samsung.android.app.watchmanager-1.apk dist/com.samsung.android.app.watchmanager-1.signed.apk

Como vemos, se pasan como parámetro los dos ficheros de clave para firmar el APK. Estos ficheros son los que lleva para probar signapk, recomiendo utilizarlos por simplicidad.

Con esto, tendremos un APK firmado y listo para usar. A continuación instalamos con el siguiente comando:

adb install dist/com.samsung.android.app.watchmanager-1.signed.apk

Y una vez instalado tendremos la aplicación en nuestro dispositivo, lista para iniciar y actualizar nuestro reloj.

En mi caso, funcionó así sin problemas, pero existe una función llamada "isSamsungDeviceWithCustomBinary" que comprueba si la aplicación ha sido modificada. En principio no detecta esta modificación, pero por si acaso, se puede modificar de igual forma que hemos hecho con la que comprueba si el dispositivo es compatible. En este caso nos interesa que siempre devuelva 0 (false), que significa que la aplicación no ha sido modificada. Por tanto, introduciremos al comienzo de la función lo mismo que antes excepto el valor de v0, que será 0 en este caso:

const/4 v0, 0x0
return v0


Y después de todo esto, ya podremos utilizar nuestro Gear S2 con nuestro dispositivo Android.

ADVERTENCIA: No me hago responsable de cualquier daño sufrido por vuestro teléfono o reloj. Haz esto bajo tu propia responsabilidad.

No es nada complicado, ni muy técnico, pero me parecía interesante compartirlo, puesto que seguramente haya alguien al que le pueda resultar útil.

Con esto me despido hasta la próxima, que espero sea pronto y sea explicando algunas curiosidades de la app de Yomvi (ahora Movistar+) ;)