Insertar archivos dentro del relleno de imágenes en formato bitmap.
Una imagen de mapa de bits (.bmp) es un tipo de archivo de imagen digital que representa una imagen como una cuadrícula de píxeles individuales, cada uno con un color definido. Almacena los datos en un formato sencillo y sin comprimir, lo que puede resultar en tamaños de archivo grandes, especialmente para imágenes de alta resolución. Las imágenes de mapa de bits son ampliamente compatibles con diversos software y sistemas operativos, pero carecen de la compresión y las funciones avanzadas de otros formatos como JPEG o PNG.
Por ejemplo, los datos que representan una línea compuesta por dos píxeles rojos en una imagen de mapa de bits de 24 bits aparecerían de la siguiente manera:
[00 00 FF] [00 00 FF] 00 00
Los datos de cada píxel se han colocado entre corchetes para una mejor claridad.
Los valores RGB se almacenan en un orden inverso, es decir, BGR. En una imagen de mapa de bits de 24 bits, cada color se representa por un triplete de 3 bytes, con cada byte correspondiente a los componentes rojo, verde y azul, con valores que van desde el hexadecimal 00 (decimal 0) hasta el hexadecimal FF (decimal 255). En este ejemplo, los valores de azul y verde están establecidos en 0, mientras que el valor de rojo está en FF (decimal 255, el valor máximo que puede representar un entero de 8 bits).
Sin embargo, es posible que hayas notado algo: en el ejemplo que proporcioné, hay dos bytes "extra" o "no utilizados" al final de la línea. Esto no es un error de mi parte; cada línea de exploración (scan line) se rellena hasta el múltiplo de 4 bytes más cercano. Si la longitud de la línea no es divisible por cuatro, como en el caso de 6 bytes, se agregarán 2 bytes de relleno al final de cada línea de exploración.
[00 00 FF] [00 00 FF]→(00 00)← relleno
Este relleno generalmente se llena con ceros, pero no tiene por qué ser así. Podemos incrustar datos ocultos dentro del mapa de bits sin alterar los datos reales de la imagen colocándolos dentro del relleno (es decir, siempre y cuando nuestro archivo de mapa de bits tenga relleno; recuerda que si la longitud de la línea es divisible por 4, no habría relleno).
Con bmpuzzle, insertar y extraer archivos en el relleno de una imagen de mapa de bits es algo trivial.
A continuación, se muestran los valores hexadecimales para una imagen de mapa de bits. Para simplificar, la imagen consiste en una sola línea blanca, donde los valores FF corresponden a los datos de color de los píxeles (siendo el blanco #FFFFFF), y los valores 00 representan el relleno.
Usando el siguiente comando, podemos insertar cualquier* archivo (en este caso, una imagen llamada "hidden.jpeg") dentro del mapa de bits:
bmpuzzle -i original_image.bmp hidden.jpeg
*Siempre y cuando quepa dentro del relleno.
Ahora, si abrimos el mapa de bits en un editor hexadecimal, observaremos que el relleno ha sido reemplazado con los datos de nuestra imagen.
Para extraer los datos ocultos de una imagen, podemos usar el siguiente comando:
bmpuzzle -e image_with_hidden_data.bmp extracted_data.jpeg
Este comando extraerá los datos ocultos de image_with_hidden_data.bmp y los guardará como extracted_data.jpeg.
Para obtener el máximo relleno, debes:
Asegurarte de que cada línea tenga 3 bytes de relleno, que es la cantidad máxima de relleno que una línea podría tener. [*]
Reducir el ancho de la imagen. Dado que el relleno se agrega al final de cada línea de exploración horizontal, hacer el ancho más pequeño resultará en una "mejor" relación de relleno/datos de la imagen (por "mejor" me refiero a que tendremos más relleno innecesario en lugar de datos de la imagen). Necesitamos menos ancho y más altura.
[*] Toma el ancho de la imagen y multiplícalo por el número de bytes por píxel (para un mapa de bits de 24 bits, eso son 3 bytes). Luego divide el resultado entre 4. Si el resultado termina en .25, tendrás 3 bytes de relleno por cada línea de exploración.