¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Ingeniería inversa: leer un binario sin ejecutarlo

Después de esta lección: Puedo averiguar qué contiene un programa sin ejecutarlo.

Lección de 50 min6 comandosLaboratorio de ingeniería inversa: leer programas con gdb, radare2, strace y ltrace en una VM

Qué es la ingeniería inversa

La ingeniería inversa consiste en averiguar cómo funciona un programa a partir del propio programa, sin su código fuente. Se practica solo con programas preparados para el laboratorio, para entender cómo se ve un fallo y poder corregirlo.

Una tienda online encuentra en su servidor una herramienta que nadie recuerda haber escrito. Antes de ejecutarla, alguien tiene que leer qué hace.

La regla de este módulo

Importante

Usa estas herramientas solo con los programas de tu laboratorio y sobre tu propia copia. Nunca con el software de otra persona, ni con la licencia, el juego o la protección de nadie. El motivo es defensivo: quien sabe cómo se ve un fallo sabe encontrarlo y corregirlo. Tu laboratorio no llega a ningún otro sitio.

Al final de esta lección

Nota

Puedo averiguar qué contiene un programa sin ejecutarlo.

Palabras clave

PalabraQué significaEjemplo
Binarioel programa tal como lo ejecuta el ordenador
Cadena de textouna serie de caracteres legibles dentro de un archivo
ELFel formato de archivo de los programas en Linux
Ensambladorlas instrucciones del procesador escritas con nombres
Desensambladoruna herramienta que convierte un binario en ensambladorobjdump -d

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un binario lleva su texto dentro

Al compilar, los textos que escribiste entre comillas pasan al binario tal cual. El comando strings imprime cada serie de caracteres legibles de un archivo, sin ejecutarlo.

Por eso un mensaje, una ruta o un código que el programa necesita aparece en esa lista. Para practicar, el primer Run crea tienda, un programa de ejemplo nuestro que comprueba un código de descuento con gcc, el compilador del laboratorio. No es uno de los programas de la práctica del laboratorio.

Crea el programa de ejemplo tienda

Comando
printf '#include <stdio.h>\n#include <string.h>\nint main(int argc, char **argv) {\n    if (argc == 2 && strcmp(argv[1], "REBAJAS26") == 0) { puts("Descuento aplicado"); return 0; }\n    puts("Codigo incorrecto");\n    return 1;\n}\n' | gcc -O0 -no-pie -x c -o /tmp/tienda -

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Pregunta de qué tipo es el archivo

Comando
file /tmp/tienda | cut -d, -f1

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Busca sus textos, ordenados

Comando
strings /tmp/tienda | grep -E "REBAJAS|Descuento|Codigo" | sort

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

El desensamblador muestra qué llama el programa

Un desensamblador convierte las instrucciones del binario en ensamblador, que una persona puede leer. El comando objdump -d lo hace, y con --disassemble=main pide solo la función main, por donde empieza el programa.

Una línea call llama a otra función. El Run siguiente se queda solo con los nombres que siguen a cada call: las funciones de biblioteca que usa main.

Mira a qué funciones llama main

Comando
objdump -d /tmp/tienda --disassemble=main | grep -o "<[a-z]*@plt>"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente cree que, sin el código fuente, un programa esconde lo que hace. Compilar cambia la forma, no los datos: los textos, los nombres de las llamadas y el orden de los pasos siguen dentro. Por eso nunca se guarda un secreto en un programa.

Tu hipótesis se prueba sobre tu copia

strings te dio un texto que parece un código y objdump te dijo que se compara con strcmp. Eso es una hipótesis, no una prueba.

Ejecutar tienda con ese texto confirma o descarta la idea. Primero va un texto cualquiera, para ver qué dice el programa cuando se equivocan.

Prueba un código cualquiera

Comando
/tmp/tienda hola

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Prueba el código que encontraste

Comando
/tmp/tienda REBAJAS26

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para ir más lejos

Ejecuta strings -n 8 /tmp/tienda en el terminal. La opción -n sube el mínimo de caracteres, igual que el segundo argumento de tu función. Compara cuántas líneas salen con -n 4 y con -n 8.

Después explica por qué un mínimo muy bajo llena la lista de ruido, y por qué uno muy alto puede perder el texto que buscas.

Sobre este laboratorio y su código: Laboratorio de ingeniería inversa: leer programas con gdb, radare2, strace y ltrace en una VM

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.