sábado, 15 de agosto de 2015

Rooteo de la tablet Energy Sistem NEO2

En esta entrada explicamos el proceso seguido para rootear una tablet Energy Sistem NEO2 como esta:

Por defecto la tablet está protegida por el fabricante, si intentas acceder con el superusuario "root", obtendrás este mensaje de error:

    $ adb root
    adbd cannot run as root in production builds

Los fabricantes son rehacios a dejar que los usuarios normales tenga acceso root a sus dispositivos, ya que no les gusta que los usuarios normales puedan customizar sus dispositivos (y tampoco que usuarios que no saben lo que hacen los puedan estropear). Si no eres root, tu capacidad de hacer modificaciones en tu dispositivo estará bastante limitada. La intención de esta articulo es hacerse root de la tablet Energy Sistem NEO2. Usaremos como sistema host un Ubuntu Linux 14.04. Advierto que el procedimiento es altamente destructivo si no se hace con cuidado. Advertido quedas, lector!

Averigua el product-id y el vendor-id

Conecta la tablet a tu PC con el cable USB y mira la salida del comando "lsusb":

    $ lsusb

Identifica en el listado una linea como esta:

    Bus 003 Device 066: ID 2207:0011

El ID 2207:0011 se corresponde con tu tablet Energy Sistem de 10.1 pulgadas.

Acceso al dispositivo a través de USB

Configurar el sistema operativo de tu PC para que tenga acceso al dispositivo Android a través del USB. Bajo Ubuntu, los usuarios regulares no pueden acceder directamente a los dispositivos USB por defecto. El sistema necesita estar configurado para permitir tal acceso. La mejor solución consiste en crear un fichero (como usuario root):

    $ sudo vi /etc/udev/rules.d/51-android.rules

Y añadir el siguiente contenido:

    SUBSYSTEM=="usb", ATTR{idVendor}=="<idvendor>", ATTR{idProduct}=="<idproduct>", MODE="0600", OWNER="<username>"

Donde:

  • <username>: es el nombre del usuario que estará autorizado a acceder al dispositivo a través del USB
  • <idvendor>: es el identificador del vendedor del dispositivo
  • <idproduct>: es el identificador del producto

Para el dispositivo que nos ocupa:

    <username> es "aicastell"
    <idvendor> es "2207"
    <idproduct> es "0011"

Por tanto, añade este contenido:

    # adb protocol
    SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0011", MODE="0600", OWNER="aicastell"

Cambia los permisos del fichero:

    $ chmod a+r /etc/udev/rules.d/51-android.rules

Reinicia el servicio del udev:

    $ sudo service udev restart

Estas reglas nuevas pasan a tener efecto la siguiente vez que se conecta un dispositivo. Por tanto, será necesario desconectar el dispositivo y volver a conectarlo al USB.

Customización especial

Este paso no es habitual en todos los dispositivos Android, pero SI es necesario para los dispositivos SOC Rockchip. Si no lo haces, el comando "adb devices" no detectará el dispositivo Android conectado. Crea este directorio:

    $ mkdir ~/.android

Y crea este fichero, con este contenido:

    $ vi ~/.android/adb_usb.ini

    # ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.
    # USE 'android update adb' TO GENERATE.
    # 1 USB VENDOR ID PER LINE
    0x2207

Habilitar el modo desarrollador Android

En tu dispositivo Android, navega hasta el menu de configuración y busca la opción:

    { } Opciones de desarrollo

Si no tienes acceso a estas opciones, ves al apartado:

    Ajustes > información de la tablet > Numero de compilación

Pulsa varias veces sobre la opción "Numero de compilación" hasta que se active la opción "Opciones de desarrollo".

Ahora navega a traves de estas opciones:

    "Opciones de desarrollo" > "Depuración" > "Depuración USB"

para activar el modo de depuración cuando el dispositivo este conectado por USB.

Android Debug Bridge (ADB)

La herramienta “adb" es esencial para depurar, manejar y personalizar dispositivos Android. "adb" son las siglas de Android Debug Bridge. Esta herramienta esta disponible a partir de Ubuntu 14.04 como binario precompilado. Puedes instalarla usando este comando:

    $ sudo apt-get install android-tools-adb

También se podría compilar descargando los fuentes del Android Open Source Project (AOSP), aunque no es el objetivo de este documento.

Detección del dispositivo

Cuando conectes el dispositivo Android por USB a tu PC, podrás verificar que tu dispositivo esta conectado ejecutando el comando:

    $ adb devices

Desde Android 4.2.2 en adelante se introdujo una nueva caracteristica de seguridad. Debes confirmar que tu dispositivo android esta conectado a un PC autorizado antes de que se permita ningún dialogo. Por tanto, si es la primera vez que lanzas este comando, verás esta salida:

    List of devices attached

    d1548bec06f16120    unauthorized

En este caso, en el dispositivo de Android saldrá una ventana de dialogo preguntando si quieres aceptar la clave RSA que acepte la depuración del dispositivo a través del PC desde el que has conectado. Este mecanismo de seguridad protege al dispositivo frente a ataques remotos, porque asegura que el debugging USB y otros comandos adb no puedan ser ejecutados a menos que seas capaz de desbloquear el dispositivo confirmando este dialogo.

Si no es la primera vez que lanzas el comando, verás esta salida, sin mas:

    $ adb devices
    List of devices attached
    0123456789ABCDEF    device

El problema

El fabricante protege la tablet y no podremos lanzar este comando, ya que genera error:

    $ adb root
    adbd cannot run as root in production builds

El objetivo de este post es encontrar una solución a este problema, así que vamos a analizar este error. Lo primero es buscar en los fuentes de Android (proyecto AOSP) el string del error. Encontramos el mensaje en este fichero:

    $ vi aosp/system/core/adb/services.c

    property_get("ro.debuggable", value, "");
    if (strcmp(value, "1") != 0) {
        snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
        writex(fd, buf, strlen(buf));
        adb_close(fd);
        return;
    }

Como vemos, el método "property_get" lee el valor de la propiedad "ro.debuggable" y si su valor no es 1, muestra el error "adbd cannot run as root in production builds".

Buscando mas a fondo en los fuentes de Android, encontramos que la función property_get esta definida en este fichero:

    $ vi aosp/system/core/libcutils/properties.c

    int property_get(const char *key, char *value, const char *default_value)
    {
        int len;

        len = __system_property_get(key, value);
        if(len > 0) {
            return len;
        }

        if(default_value) {
            len = strlen(default_value);
            memcpy(value, default_value, len + 1);
        }
        return len;
    }

Por el nombre del método __system_property_get, deducimos que se trata de una propiedad de la partición "system" de Android. Por tanto, el primer objetivo será obtener el contenido de la partición system de la tablet, para modificar su fichero de propiedades (build.prop), añadiendo en su interior la propiedad ro.debuggable=1.

La herramienta rkflashtool

La herramienta "rkflashtool" permite leer/escribir el contenido de cualquier partición de la tablet. Para instalar esta herramienta, lo primero es instalar las dependencias de Ubuntu necesarias para su compilación:

    $ sudo apt-get install build-essential libusb-1.0-0-dev

Descarga la herramienta:

    $ git clone https://github.com/linux-rockchip/rkflashtool

Compila e instala:

    $ cd rkflashtool
    $ make
    $ sudo cp rkflashtool rkcrc rkunpack rkunsign /usr/local/bin

Despues arrancas la tablet en modo bootloader:

    $ adb reboot bootloader

Y ya puedes obtener el layout de la memoria flash con este comando:

    $ rkflashtool p > parameters.txt

En mi caso concreto, tengo este layout:

    NAME OFFSET NSECTORS
    misc 0x00002000 0x00002000
    kernel 0x00004000 0x00006000
    boot 0x0000a000 0x00006000
    recovery 0x00010000 0x00010000
    backup 0x00020000 0x00020000
    cache 0x00040000 0x00040000
    metadata 0x00080000 0x00002000
    kpanic 0x00082000 0x00002000
    system 0x00084000 0x00200000
    vendor 0x00284000 0x00002000
    userdata 0x00286000 -

Ahora puedo leer el contenido de cualquier partición con este comando:

    $ rkflashtool r <nombre_particion> > <nombre_particion>.img

Y puedo grabar el contenido de cualquier partición con este comando:

    $ rkflashtool w <nombre_particion> <nombre_particion>.img

Añadir ro.debuggable=1

Para obtener el contenido de la partición de system hacemos:

    $ sudo rkflashtool r system > system.img

Vemos que system.img es la imagen de un sistema de ficheros en formato ext4:

    $ file system.img
    system.img: Linux rev 1.0 ext4 filesystem data, UUID=da594c53-9beb-f85c-85c5-cedf76546f7a, volume name "system" (extents) (large files)

Podemos montar esta partición system.img en modo loopback:

    $ sudo mount -o loop system.img /media/removable

Cambiar el contenido del fichero build.prop:

    $ vi /media/removable/build.prop
    ro.debuggable=1

Tras desmontar la partición:

    $ sudo umount /media/removable

Vuelve a grabar el contenido con este comando:

    $ rkflashtool w system < system.img

Sin embargo, el problema sigue manifestándose:

    $ adb root
    adbd cannot run as root in production builds

Con esto deducimos que el cliente "adb" conecta con un servicio de la tablet (llamado adbd), que se encarga de decodificar el contenido del fichero build.prop y proporcionar una respuesta al cliente "adb". Si el fichero build.prop tiene la propiedad ro.debuggable=1 y sigue sin funcionar, debe ser porque este servicio adbd esta capado, y siempre devuelve error, independientemente del contenido del fichero de propiedades build.prop.

La herramienta imgrepackerrk

Para solucionar este problema intentaremos reemplazar el adbd capado por uno no-capado. Para ello lo primero es averiguar donde está almacenado el adbd capado. Tras buscar adbd en la partición system, no lo encontramos. Podría estar almacenado en la partición de boot, así que lo primero es leer su contenido con la herramienta rkflashtool:

    $ rkflashtool r boot > boot.img

Vemos que la imagen de boot (boot.img) no se puede montar, pues se trata de un fichero de datos, no de un sistema de ficheros:

    $ file boot.img
    boot.img: data

Necesitamos una herramienta para extraer el contenido de esta partición. En este foro de xda-developers:

    http://forum.xda-developers.com/showthread.php?t=2257331

encontramos la herramienta "imgrepackerrk" (versión 104). Esta utilidad permite desempaquetar/reempaquetar imágenes de boot.img.

Tras descargar la herramienta, la instalámos en nuestra máquina, copiandola en /usr/local/bin:

    $ cp imgrepackerrk /usr/local/bin
    $ chmod 755 /usr/local/bin/imgrepackerrk

Usamos esta herramienta para extraer el contenido de la imagen boot.img:

    $ imgrepackerrk boot.img

Una vez desempaquetado el contenido de boot.img, buscamos el servicio adbd en su interior:

    $ find boot.img.dump/ | grep adbd
    boot.img.dump/ramdisk.dump/sbin/adbd

Efectivamente, el servicio se encuentra dentro de esta partición. Este fichero es el que creemos que está capado, y hay que reemplazar por un servicio adbd que no este capado.

El servicio adbd no-capado

El servicio adbd no-capado lo vamos a obtener descargando el paquete adbd-Insecure-v2.00.apk desde esta URL:

    http://forum.xda-developers.com/showthread.php?t=1687590

El checksum del archivo descargado es este:

    $ md5sum adbd-Insecure-v2.00.apk
    df9ef24983dd29530bbbe2a7caeb35d8  adbd-Insecure-v2.00.apk

Descomprime su contenido:

    $ unzip adbd-Insecure-v2.00.apk

Dentro de este apk encontraremos el nuevo adbd no-capado, que curiosamente tiene una extensión .png (normalmente usada para fotos), aunque vemos que en realidad no se trata de una foto, se trata de un binario ejecutable:

    $ file ./assets/adbd.21.png
    ./assets/adbd.21.png: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, stripped

Reemplaza este archivo adbd.21.png por el adb capado:

    $ cp ./assets/adbd.21.png boot.img.dump/ramdisk.dump/sbin/adbd

Reempaqueta la imagen boot.img con el nuevo servicio adbd no-capado:

    $ imgrepackerrk boot.img.cfg

El comando anterior reempaqueta la imagen boot.img con un adbd no-capado que esperamos que resuelva nuestro problema inicial.

Graba el nuevo boot.img en la flash:

    $ rkflashtool w boot < boot.img

Disfrutar del resultado

Reinicia la tablet. Si todo ha ido bien podrás disfrutar de tu tablet rooteada:

    # adb root
    adbd is already running as root

    # adb remount
    remount succeeded

Visitas:

Seguidores