cropped_parser: обрезанный через заголовок BMP
Файл cropped_parser.bmp. В названии прямо сказано «обрезанный».
- Платформа
- CTF
- Носитель
- BMP, 32 бита на пиксель
- Приём
- высота в заголовке меньше реальной
- Инструменты
exiftool,xxd,dd- Статус
- метод найден, файл восстановлен
Аномалия в числах
Для форматов без сжатия (BMP, PPM, сырые пиксели) есть проверка, которую стоит делать всегда: ширина × высота × байт_на_пиксель должно совпасть с размером данных.
Image Width : 1000
Image Height : 1000
Bit Depth : 32 ← 4 байта на пиксель
Image Length : 4800000 ← столько байт пикселей на самом деле
ожидаемо: 1000 × 1000 × 4 = 4 000 000
лишнее: 800 000 / 4 байта = 200 000 пикселей = ровно 200 строк по 1000
Лишнее делится ровно на целое число строк, значит, это не мусор, а настоящие строки картинки. Реальный размер 1000 × 1200.
Почему в BMP это так просто
В BMP нет ни сжатия, ни контрольной суммы. Просмотрщик берёт высоту из заголовка и читает ровно столько строк. «Обрезать» картинку можно, поменяв 4 байта, и вернуть так же. В PNG пришлось бы подбирать высоту по CRC чанка IHDR, а здесь её можно просто посчитать.
| Смещение | Поле | Байты | Значение |
|---|---|---|---|
0x12 | ширина | e8 03 00 00 | 1000 |
0x16 | высота | e8 03 00 00 → b0 04 00 00 | 1000 → 1200 |
Числа в little-endian, младший байт первым: 1200 = 0x04B0 записывается как b0 04 00 00.
cp cropped_parser.bmp fixed.bmp
printf '\xb0\x04\x00\x00' | dd of=fixed.bmp bs=1 seek=$((0x16)) conv=notrunc
xxd -s 0x12 -l 8 fixed.bmp
00000012: e803 0000 b004 0000
Где появятся скрытые строки
BMP хранит строки снизу вверх. Просмотрщик прочитал первые 1000 строк данных, а это нижняя часть картинки. Лишние строки лежат в конце файла, то есть это верх изображения. Я воспроизвёл приём на своём файле:
по заголовку: 250 × 250
после правки: 250 × 300zstegна этом файле падал не из-за задачи: он не понимает BMP версии 5 (заголовок 124 байта). Если понадобится LSB, достаточно сконвертировать:convert fixed.bmp fixed.png.
Другие способы
- GIMP → Raw image data: смещение 138, 1000 × 1200, RGB Alpha. Потом отразить по вертикали и поменять местами R и B (BMP хранит BGR).
- ImHex: поправить поле в шаблоне BMP прямо в редакторе.
- Для PNG есть готовая «чинилка» PCRT: она сама подбирает ширину и высоту по CRC.