Archivo del autor creadores

Avatar Porcreadores

Ingeniería inversa en Arduino Uno

Una de las grandes preguntas sobre Arduino que tenía desde hace tiempo, era la posibilidad de hacerle ingeniería inversa, específicamente, obtener el código de un Arduino programado. Les adelanto la sorpresa, la respuesta corta es que si, si es posible obtener código de un Arduino programado, sin embargo, no será lenguaje de alto nivel. Lo más cerca que tendremos será un paso intermedio entre lenguaje ensamblador e instrucciones en hexadecimal.

Lista de equipo

  • Arduino Uno (yo usé un Arduino Uno R3 con chip desmontable)
  • Tarjeta lectora/escritora de chips AVR. (Yo usé la conocida stk500 de Atmel)
  • Adaptador usb-serial
  • Cable usb con terminal tipo A
  • PC con la suite de Arduino instalada

Proceso de ingeniería inversa

Grabar el código original

Este paso ya lo has hecho una y otra vez, sólo carga el sketch al arduino. En mi caso voy a usar un sketch muy sencillo para efectos didácticos como el que podemos encontrar dentro de la carpeta de «Ejemplos», el famoso Blink. Lo modifiqué un poco para que el led 13 parpareada cada 7 segundos en lugar de 1, esto para poder identificar fácilmente el resultado.

void setup() { 
 // initialize the digital pin as an output.
 pinMode(13, OUTPUT); 
}

// the loop routine runs over and over again forever:
void loop() {
 digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) 
 delay(7000);// wait for a second
 digitalWrite(13, LOW); // turn the LED off by making the voltage LOW 
 delay(7000);// wait for a second
}

mci-tdd-00756_arduino_uno_r3_2

Extraer el chip atmega328p

Este modelo nos permite extraer el chip atmega328p, para poderlo colocar en el lector stk500.

atmega328p-pustk500

Extraer el binario en hexadecimal

Para extraer el binaro en formato hexadecimal de Intel, usa el siguiente comando:

avrdude -F -v -pm328p -cstk500 -P/dev/ttyUSB0 -D -Uflash:r:reverse.hex:i

/dev/ttyUSB0 es el puerto que usa el convertidor usb-serial, en tu caso puede cambiar, revísalo con el comando dmesg inmediatamente después de conectar el usb-serial.

El resultado será un archivo con el nombre reverse.hex, si lo abres, encontrarás algo como lo siguiente:

:200000000C945C000C946E000C946E000C946E000C946E000C946E000C946E000C946E0082
:200020000C946E000C946E000C946E000C946E000C946E000C946E000C946E000C946E0050
:200040000C9488000C946E000C946E000C946E000C946E000C946E000C946E000C946E0016
:200060000C946E000C946E000000000700020100000304060000000000000000010204083E
:200080001020408001020408102001020408102004040404040404040202020202020303C0

Descompilar el hexadecimal

Para poder entender el código hexadecimal, lo pasaremos por un descompilador que convertirá los códigos en instrucciones legibles.

avr-objdump --no-show-raw-insn -m avr --prefix-addresses -D reverse.hex > reverse.assembler

El resultado de ese comando, nos entregará un pseudocódigo parecido al ensamblador, claro que habrá que hacer bastante trabajo estético para poderlo leer, pero el siguiente extracto muestra llamadas las funciones que prenden y pagan el pin 13.

0x000000e8 ldi r22, 0x01 ; 1
0x000000ea ldi r24, 0x0D ; 13
0x000000ec call 0x37a ; 0x0000037a Llama a la función que cambia el pin a alto
0x000000f0 ldi r22, 0x58 ; 88
0x000000f2 ldi r23, 0x1B ; 27
0x000000f4 ldi r24, 0x00 ; 0
0x000000f6 ldi r25, 0x00 ; 0
0x000000f8 call 0x1ee ; 0x000001ee Llama la función de delay
0x000000fc ldi r22, 0x00 ; 0
0x000000fe ldi r24, 0x0D ; 13
0x00000100 call 0x37a ; 0x0000037a LLama la función que cambia el pin a bajo
0x00000104 ldi r22, 0x58 ; 88
0x00000106 ldi r23, 0x1B ; 27
0x00000108 ldi r24, 0x00 ; 0
0x0000010a ldi r25, 0x00 ; 0

Claro que hay que hacer mucho trabajo para entender el funcionamiento correcto del equipo, sin embargo, es completamente viable realizarlo.

¿Cómo evitar que lean código de mi chip?

Existe una sección de fusibles o bits de cerrado que impedirán el proceso anterior. Sólo tienes que seguir correctamente la receta. Adjunto este sitio con información al respecto.

Happy reverse engnineering!!

 

 

Avatar Porcreadores

Mediaserver en un Cubieboard A10

Objetivo

En mi caso estoy buscando compartir algunos videos, música y libros digitales utilizando un servidor web y dlna. Además usaré este tipo de instalación como base para el desarrollo de nuestra plataforma para IoT (Internet of Things).

Lista de materiales

  • Cubieboard A10
  • Disco duro SATA de espacio a elegir (yo estoy usando 1TB)
  • Cable SATA + 5V breakout
  • Adaptador o fuente de alimentación de 5V a 2A
  • Wifi DWA-131E1 marca D-Link

sata-cable-5v-2a-dc-power-adapter

Instalando la plataforma

Descarga la imagen

Primero hay que descargar la imagen. La que estoy utilizando y me funcionó muy bien es la Cubian-nano-x1-a10-hdmi.img. Aquí el torrent para descargarlo.

Si no tienes 7z, lo puedes descargar en ubuntu así:

sudo apt-get install p7zip

Una vez descargado, puedes descomprimir el archivo así:

7zr x Cubian-nano-x1-a10-hdmi.img.7z

Copia la imagen a la memoria uSD

Coloca tu memoria sd en el lector y copia la imagen a la misma. Yo estoy usando micro sd’s de 8GB y me han funcionando muy bien.

micro_sd_8gb

sudo dd if=Cubian-nano-x1-a10-hdmi.img of=/dev/mmcblk0

Nota que en mi caso la memoria sd se detecta como /dev/mmcblk0 y así como aparece lo uso. NUNCA uses la partición /dev/mmcblk0p1.

Configurando el sistema

Inicia el sistema

Arranca tu sistema conectando un monitor y un teclado. Sigue el wizard para realizar la configuración inicial y reinicia el sistema.

cubieboard

Actualiza el sistema

Actualiza los paquetes y el sistema para tener la última versión.

sudo su -
apt-get install aptitude
aptitude update
aptitude upgrade

Wifi

Instalando el módulo

Estoy usando una tarjeta DWA-131E1 de D-Link, su módulo no está incluido en la distribución, así que lo voy a compilar. Es relativamente fácil encontrar este hardware en México y también es económico, por eso lo incorporé al diseño.

dwa-131e1

aptitude install usbutils
aptitude install firmware-realtek firmware-linux

aptitude install build-essential git
aptitude install linux-headers
aptitude install linux-headers-3.4.79-sun4i

git clone https://github.com/romcyncynatus/rtl8192eu.git

Ya que tenemos todos los paquetes necesarios, ahora sí lo compilaremos.

cd rtl8192eu

Comenta la siguiente línea  en el archivo Makefile anteponiendo el numeral #

#EXTRA_CFLAGS += -Wno-error=date-time

Guarda el archivo y comienza la compilación,  posteriormente instala los binarios

make ARCH=arm KVER=3.4.79-sun4i
make ARCH=arm KVER=3.4.79-sun4i install

Agrega las opciones del módulo, no estoy muy claro si las debería de llevar o no, si alguien ha hecho más pruebas, me vendrían muy bien sus comentarios.

Crea el archivo /etc/modprobe.d/8192eu.conf

options 8192eu rtw_power_mgnt=0 rtw_enusbss=0

Edita el archivo que carga los módulos al arranque para que esté presente cuando inicies la cubieboard. /etc/modules

#wifi
8192eu

Reinicia y prueba que se cargue el módulo correctamente. Una forma sencilla es ejecutar el comando:

lsmod | grep 8192eu

Configurando el SSID

Ejecuta el siguiente comando, reemplazando Mi_SSID por el nombre de tu red.

wpa_passphrase Mi_SSID

La salida será parecida a esto:

network={
   ssid="Mi_SSID"
   #psk="my_very_secret_passphrase"
   psk=ee80f3ecd6496a956e76f7c0332960326951f8edee80f3ecd6496a956e76f7c0332960326951f8ed
}

Para que se configure al inicio del sistema tenemos que editar /etc/network/interfaces.

auto wlan0
iface wlan0 inet dhcp
   wpa-ssid Mi_SSID
   wpa-psk ee80f3ecd6496a956e76f7c0332960326951f8edee80f3ecd6496a956e76f7c0332960326951f8ed

Prueba que funcione levantando la interface y revisando que se haya configurado correctamente con ifconfig.

ifup wlan0 && ifconfig wlan0

Almacenamiento

disco_duro_2-5

Preparar el almacenamiento

Apaga el sistema y conecta el disco duro de 2.5″, seguramente el sistema le asignará el descriptor /dev/sda1, lo puedes checar con un dmesg.

Formatea con ext4

mkfs.ext4 -I 256 /dev/sda1

Móntalo permanentemente

Edita el archivo /etc/fstab, es el lugar en donde el sistema guarda la tabla para montar sistemas de archivos automáticamente. Agrega al final la siguiente línea.

/dev/sda1  /archivos  ext4  noatime,dealloc  0  0

Arregla los locales

Encontrarás errores sobre los locales si cambiaste el idioma de inglés a español. Aquí algunos tips de como arreglarlo:

locale-gen
dpgk-reconfigure locales

Instalando el miniDLNA

Ahora configuraremos el servidor miniDLNA que nos ayudará a compartir la música y los videos con smartTVs y consolas.

aptitude install minidlna

Edita el archivo /etc/minidlna.conf y cambia las siguientes líneas:

media_dir=/mi_ruta
presentation_url=http://mi_ip:8200

Cambia /mi_ruta por el directorio en donde están tus archivos a compartir, también cambia mi_ip por la IP que tu sistema usará. (también sería recomendable configurar tu interface wlan0 con una dirección estática para que nunca cambie).

Instalando el servidor web

Un servidor web muy ligero y rápido es nginx, en lo personal lo prefiero a apache para aplicaciones pequeñas. No viene preeinstalado en el sistema, así que hay que instalarlo y configurarlo.

aptitude install nginx

Edita el archivo /etc/nginx/sites-enable/default, encuentra la sección que comienza con «location /» y agrega esto entre las llaves:

autoindex on;

La línea anterior te permitirá ver todos los archivos y navegar entre ellos.

Aquí puedes agregar un sistema sencillo de autenticación como un htaccess o similar.

Happy sharing!!