В настоящий момент, exiftool является мощным инструментом для анализа и изменения различной информации о файлах. Недавно, экспериментируя с файлами формата PNG и exiftool, я обнаружил одну занятную вещь, связанную с тем, что exiftool в стандартном режиме не считывает кастомные чанки PNG. В данной статье рассмотрим способ как вписывать невидимые для стандартного режима exiftool чанки в PNG.
В данной статье использовался exiftool версии 12.76
Кратко о структуре PNG файла
В начале любого PNG файла стоит сигнатура, которая представляет из себя последовательность из 8 байтов:
89 50 4e 47 0d 0a 1a 0a
После сигнатуры в PNG файле идёт последовательность чанков.
Чанк представляет из себя следующую структуру:
4 байта - количество байт данных в теге (далее count)
4 байта - тип чанка
count байт - данные чанка
-
4 байта - crc32 checksum от 4х байт типа чанка и данных чанка

Рисунок 1: Структура PNG файла
Ввиду вышеописанной структуры, процесс добавления чанка в PNG состоит из нескольких шагов:
считаем длину от добавляемых байт и конвертируем её в 4 байта;
считаем crc32 от типа чанка и данных;
ищем место в файле куда хотим добавить свой чанк;
вписываем 4 байта длины, 4 байта типа чанка, данные и 4 байта crc32.
Устройство типа чанка и что нам это даёт
Тип чанка как ранее упоминалось представляет из себя 4 байта, в частности, 4 символа латинского алфавита в верхнем либо нижнем регистре. Всё бы ничего, однако, эти байты носят не только информативный, но и функциональный характер в зависимости от регистра:
-
первый байт - байт критичности:
если символ в нижнем регистре, то считается, что чанк некритичный и если программе не удаётся его распознать, то его можно пропустить;
если символ в верхнем регистре, то считается, что чанк критичный и если программе не удаётся его распознать, то его необходимо прервать обработку;
-
второй байт - байт публичности:
если символ в нижнем регистре, то считается, что чанк не публичный;
если символ в верхнем регистре, то считается, что чанк публичный;
третий байт - незначащий байт, закладывается под будущий функционал;
-
четвёртый байт - байт безопасности для копирования:
если в нижнем регистре, то копировать небезопасно;
если в верхнем регистре, то копировать безопасно.
Важной особенностью является то, что кастомные чанки необходимо вставлять после чанка IHDR, в противном случае, большинство программ будет ругаться. Но как отреагирует exiftool, если вставить свой некритичный чанк после IHDR?
Вписываем невидимый для стандартного режима exiftool чанк в PNG
Для того чтобы вставлять и читать данные в PNG, я написал простенькую утилиту metadata-explorer(github) и скачал случайную картинку из интернета (далее test.png).
Первое что сделаем - прочитаем метаданные исходной картинки с помощью exiftool.
exiftool test.png

Следующим шагом, добавим в файл чанк hABr с данными "Hello Habr" с помощью metadata-explorer.
./mde --png --write --filename test.png --offset 0 --chunk_type hABr --data 72,101,108,108,111,32,72,97,98,114
Новый файл сохранён как test.png_output. Прочитаем его с помощью exiftool в стандартном режиме и убедимся что ничего не поменялось.

Теперь прочитаем файл с помощью metadata-explorer (можно и просто через hexdump+grep)
./mde --png --read --filename test.png_output
И в выводе видим что чанк существует

Однако, правда ли такая мощная утилита как exiftool совсем не видит кастомные чанки? Ответ: видит, если добавить флаг -v однако выводит очень мало информации и всё равно придётся залезать в hexdump.

Заключение
Подводя итоги, в ходе данной статьи:
немного узнали как устроены PNG файлы;
разобрали особенности типов чанков в PNG;
научились добавлять свои теги;
рассмотрели случай, когда exiftool не выводит никакой информации о добавленом чанке. Всем спасибо за прочтение!
P.S. Написал легковесный EDR-клиент для linux-серверов с полной интеграцией с Телеграм (@light_defender_bot), в данный момент проходит тестирование. Буду рад фидбеку.