Kudrone: la historia de cómo un dron volvió a volar
El cacharro
El Kudrone lo compré en Kickstarter porque soy medio tonto. Prometía seguimiento por GPS, vídeo en 4K, y no sé cuántas cosas más por 100 dólares. A diferencia de otros scams chungos de estos, este al menos me llegó a casa, pero el dron era un juguete de pésima calidad. Imposible de controlar: se caía, se torcía, se iba donde le daba la gana… Y eso dentro de casa. En el exterior directamente hacía un back-flip nada más despegar y se estampaba.
Después de algunas actualizaciones de firmware por parte de los desarrolladores, empezó a volar un pelín mejor dentro de casa, pero sin llegar a funcionar nunca del todo bien. Totalmente inútil para usarlo como dron.

El principio del fin
El acabose vino en dos entregas. Primero, tras una actualización de la aplicación, empezó a pedir registro obligatorio en sus servidores para poder volar el dron ( ¿qué? ¿por qué? ). Y un poco después, la empresa, la aplicación y todo rastro de que alguna vez existieron, desaparecieron (excepto la página de Facebook, por lo que sea), lo que nos deja con un dron cutre que pide contraseña para funcionar, pero con los servidores que comprobaban esas contraseñas ya inexistentes. Cacharro más inservible aún que cuando llegó.
La idea
La idea era sencilla: reemplazar la aplicación por una mía. Es más POR UNA WEB mía. Algo sin instalación y multiplataforma real. Pero para eso, primero tenía que entender cómo funcionaba la que ya existía, es decir, averiguar cómo se comunicaba con el dron. Primero pense en usar captura de paquetes, pero no recuerdo ni si llegué a intentarlo. Tiré por otro camino: intentar leer el código original de la aplicación.
El problema es que una aplicación de móvil, tal cual, es una caja cerrada. Un archivo .apk que el teléfono sabe leer pero un humano no. Así que me fui a APKPure, una web donde puedes descargar versiones viejas, y me bajé varias versiones de la app Kudrone: la 3.0.0, la 5.0.0 y la 5.3.5. Mi idea era comparar, por si en alguna se les había colado algo interesante que en otra hubieran tapado.
Un .apk por dentro es básicamente un zip con el programa ya “cocinado”, ilegible para un humano. Para volver a convertirlo en algo que se pueda leer usé JADX, que hace un poco de magia: coge ese programa cocinado y te lo “descocina”. Reconstruye el código en un lenguaje que se entiende (Java, en el caso de las aplicaciones de Android viejunas). No te devuelve el original exacto (eso es imposible), pero sí algo lo bastante parecido como para leerlo y enterarte de cómo funciona.
Pasé la versión 5.3.5 por JADX, le eché un vistazo, vi que había comandos y contraseñas de wifi por ahí, así que la cosa tenía buena pinta. Guardé el resultado y ahí lo dejé, en una carpeta, con las otras versiones y los .apk originales criando polvo durante varios años. Hasta hoy.
Manos a la obra
Después de dejar madurar la idea 3 o 4 años, lo primero que hice al volver fue mirar qué tenía guardado. Un pequeño caos, la verdad: los .apk de tres versiones, un par de ellos ya descomprimidos en carpetas, y el resultado de JADX de la 5.3.5. Lo típico de cuando guardas cosas “por si acaso”.
Abrí el resultado de JADX y comenzamos la revisión: había (literalmente) miles de archivos. Aunque enseguida me di cuenta de algo importante: la mayoría de esos miles de archivos eran librerías de otras empresas. Muchas con pinta de spyware, cosas chungas y conexiones con servidores de China. El código que de verdad había escrito el fabricante del dron era una parte mucho más pequeña y estaba toda ordenadita en una carpeta con su nombre: com/kudolo/kudolodrone. Unos 438 archivos. Ahí estaba el tema.
Por una cuestión de paz mental borré todo lo demás y me quedé únicamente con la carpeta buena. Y aquí, sin saberlo, estuve a punto de cometer mi primer error gordo (spoiler: me libré por los pelos, ya lo contaré).
El control de vuelo: pan comido
Primero revisé el código que hacía volar el dron y resultó sorprendentemente fácil de entender, porque estaban todos los comandos ahí, legibles, sin trampa.
El dron y el móvil se hablan por WiFi: el propio dron monta una red WiFi (Kudrone-XXXX, con contraseña 12345678) y el móvil se conecta a ella. A partir de ahí, para pilotarlo, el móvil le manda mensajillos de 13 bytes, siempre del mismo tamaño. Cada mensaje empieza con una marca fija (para reconocerlo), lleva un número que dice “qué orden es” (despegar, girar, subir…), los datos de la orden, y al final un número de control para detectar errores.
Estas son algunas de las órdenes reales que le manda la app, cada una con su numerito (el «qué orden es» del que hablaba):
| Nº | Orden | Qué hace |
|---|---|---|
| 1 | BasicControl | Despegar, aterrizar, parada de emergencia, volver a casa |
| 2 | JoystickControl | Los cuatro ejes del mando: mover el dron por el aire |
| 3 | GPSCoordinates | Mandarle las coordenadas GPS del móvil |
| 9 | FlyModeSet | Cambiar de modo de vuelo (órbita, sígueme, altura fija…) |
| 10 | Calibration | Arrancar la calibración de la brújula |
| 11 | SelfiePhoto | Disparar foto o empezar/parar la grabación |
| 12 | RotateMode | Girar sobre sí mismo automáticamente |
Y aquí una anécdota que sólo me hace gracia a mi: la clase que calcula el número de control se llama CRC, que es el nombre técnico de un método serio y robusto de detectar errores. Pero cuando fui a ver cómo lo calculaba… no era un CRC. Era una simple suma de los bytes. Le habían puesto un nombre muy chulo a algo que hizo algún becario. Detalles así te dicen mucho de cómo se hizo el aparato.
Descubrí que el mando (los dos joysticks de la pantalla) manda cuatro valores: girar a los lados, adelante/atrás, rotar, subir/bajar. Cada uno en un rango de -1000 a +1000, con el 0 en el centro. Y que el móvil no para de mandar esos mensajes a razón de 20 veces por segundo, aunque no toques nada. En plan “sigo aquí, sigo aquí, no me he desconectado”. Si el móvil se calla, el dron entiende que ha perdido el contacto y aterriza. También encontré cómo pedirle la batería, la altura, la velocidad, el GPS… Todo. En una tarde tenía el protocolo de vuelo entero apuntado en un txt.
La calibración
Me sonaba que, al encender el dron, había que girarlo a mano en varios ejes, supongo que para calibrar. Fui a mirar el código a ver si había algo de esto y no solo era cierto, sino que encontré las cadenas de texto que salían en la pantalla de la aplicación al arrancar: sujétalo en horizontal y dale una vuelta completa, luego en vertical y otra vuelta, y siempre lejos de metales. Eso es, sin duda, calibrar la brújula.
La cámara: aquí empieza el mambo
Llegamos a lo que pensé que sería lo más fácil y lo que más me apetecía recuperar: el vídeo y las fotos por wifi. Pensé: bueno, aunque el dron no vuele, tengo una cámara inalámbrica 4K (con una lente de plástico horrorosa). Pero me di de bruces willis con la realidad: El tema del vuelo estaba en código legible, pero la cámara era otra historia.
El video lo manejaba una librería aparte, pre-compilada, dificl de leer directamente: unos archivos con extensión .so, hechos en un lenguaje de más bajo nivel que Java y compilados directamente para el procesador del móvil. El código legible solo los “llama”: les dice “conéctate a la cámara”, “empieza el vídeo”, y el .so hace todo el trabajo sucio por debajo, sin contarte cómo.
Y aquí es donde casi tengo drama por mis ansias de antes. Cuando borré los .apk, borré también los .so que venían dentro. Pensé que había tirado a la papelera justo los archivos que ahora me hacían falta. Fui a comprobarlo y… BINGO: JADX, cuando decompiló la aplicación, había guardado esos .so por su cuenta, en una carpeta de recursos. Que programa más listo y que bien montado. Me podría haber vuelto a bajar la .apk, pero así es mucho mejor.
Y ahora ¿Cómo leemos esto?
Con los .so a salvo, tocaba lo más interesante: destripar esas librerías. Es como intentar leer un libro que está en un idioma que no hablas, sin espacios y con el libro cerrado. Pensé en volver al plan de la captura de paquetes. Creo que hubiese funcionado, pero mi pereza me llevó a buscar alternativas que no me obligasen a levantarme a por el portátil.
Mi primer intento de desensamblar el .so fue con la herramienta, objdump, que tampoco me controlo mucho. Me dijo algo tipo: “no sé desensamblar esta arquitectura”. Claro: el programa está hecho para el procesador de un móvil (ARM), y objdump estaba en x86. Callejón sin salida por ahí.
Miré opciones por internet y encontré capstone, que sí sabe leer código de ARM. El plan ahora era localizar dentro del .so textos tipo “fallo al conectar” y, a partir de ahí, encontrar el trozo de código que los usa. Técnicas de cracking de la vieja escuela. Por ahí si que me apaño.
Anécdota: en uno de esos strings apareció un detalle curioso: una ruta de carpetas del ordenador del programador original. Algo así como Users/roy/Downloads/aw_jni/.... Un tal “roy”, en su carpeta de Descargas, montó todo esto hace muchos años. ¡Saludos, Roy!
Lo que el código reveló
Ese trocito de código no me sirvió para entender el protocolo completo, pero me confirmó varias cosas:
- Vi el momento exacto en que se prepara la conexión de red y se establece el número de puerto y resulta que ese número no está fijo en el programa. ¿De dónde sale entonces? De un paso anterior: cuando el móvil búsca la cámara, la cámara le responde con su nombre, su dirección y su puerto.
- Confirmé otra sospecha, la de las dos calidades. Hay un ajuste para la calidad del vídeo que se manda al móvil en directo y otro, totalmente aparte, para la calidad de lo que se graba en la tarjeta de memoria. No es el mismo vídeo con dos nombres: son dos grabaciones distintas a la vez. Lo normal es que al móvil le llegue una versión más ligera (para que fluya en tiempo real) y en la tarjeta se guarde la buena de verdad.
- Y entendí que las fotos y vídeos ya guardados en la tarjeta se pueden sacar por una vía mucho más sencilla y conocida (como un disco compartido en red).
Cambio de dirección
Con todos estos datos, aún sin el protocolo completo, ya sabemos algo: una web, tal cual, no puede hablar con este dron. Ni con la cámara ni con el sistema de vuelo. Esta era mi idea, pero parece que no iba a ser posible directamente.
No es el fin del mundo. Hará falta un pequeño programa intermediario corriendo cerca del dron (en un portátil, una Raspberry Pi o el propio móvil) que se conecte a su WiFi, hable con él en su idioma, y le sirva a la web todo ya masticado y en un formato que el navegador sí entienda. La web sería únicamente la interfaz. Lo bueno es que ese traductor, una vez hecho, vale también para una futura app de escritorio o de móvil.
El giro insesperado
Aquí la historia da un volantazo. Pensaba que para rematar el tema de la cámara tendría que ir a morir a Whireshark o similares, porque mis capacidades para leer hexadecimal directamente de un archivo ARM están un poco oxidadas.
De repente IDEACA: Busqué en Internet los numeritos con los que la aplicación da órdenes a la cámara. “Empieza el vídeo” es el número 511, “Stop” es el 767, “Cambia de calidad” es el 800… Una combinación muy concreta. Y resulta que no son random: ¡están más que documentados!.
Resultó que estas librerías no estaban hechas a medida (como era de esperar, por otra parte): usa un kit archiconocido que se llama TUTK (plataforma “Kalay”), el mismo que usan miles de cámaras baratas, timbres con cámara y esos monitores para vigilar bebés que vienen de China. El fabricante del dron literalmente se limitó a renombrar las funciones con un prefijo suyo para disimular. Mi amigo “Roy” me lo había dejado en bandeja.

Así que lo que parecía la parte más complicada de rastrear y averiguar, resulta que está documentadísima y a la vista de todos. Hay manuales, hay versiones del kit por internet, y hasta hay investigadores de seguridad que le encontraron agujeros famosos hace años. La cámara deja de ser una caja negra para pasar a ser un libro abierto.
Mejor aún: hay gente que ya ha hecho exactamente lo que busco. Encontré el proyecto de un tío que cogió un monitor de bebé (de esos con cámara y el mismo kit TUTK dentro), le sacó el vídeo por la red local, y lo volvió a servir en un formato normal para verlo en el navegador. Es, punto por punto, el “intermediario” que describí en el capítulo anterior, pero ya construido por otro. O sea, que tenemos plano y hasta plantilla.
Total
¿Qué falta? Muy poco. Comprobar la versión exacta del kit y probar el usuario y la contraseña de la cámara, que creo que será un 12345. Una vez más: gracias Roy.
Así que, resumiendo: el dron que una empresa mató a base de obligarte a iniciar sesión en unos servidores que ya no existen… podría volver a la vida entre nosotros, sin ellos, sin nube y sin pedirle permiso a nadie. Que era justo la idea desde el principio. Pero esto lo confirmaremos en el próximo episodio.
