Как извлечь двоичные данные, добавленные в файл png? - PullRequest
1 голос
/ 02 мая 2020

Похоже, что если я добавлю двоичные данные в конец png-файла, png-файл все еще будет доступен для просмотра. Таким образом, файл PNG по-прежнему является действительным файлом. Есть ли способ автоматически извлечь такие конечные данные из файла png, исходный размер файла которого не записан?

Ответы [ 2 ]

2 голосов
/ 03 мая 2020

PNG заканчиваются фрагментом "IEND". Последние 12 байтов всегда выглядят одинаково. Таким образом, вы могли бы, возможно, использовать:

dd if=appended.png of=extracted.png bs=1 count=$((($(od -t x1 appended.png | awk '{$1=""}1' | tr -d \\n | sed "s/00 00 00 00 49 45 4e 44 ae 42 60 82/XMATCHX/" | tr X \\n  | grep -b MATCH | cut -f1 -d:)-2)/3+12))

Выше приведено немного больше времени, чем нужно для работы с macos, который обрабатывает grep -b иначе, чем GNU grep.

Суть этого is:

  • Используйте dd для извлечения количества байтов из начала appended.png
  • Определите счет путем:
    • преобразования файла в шестнадцатеричную строку, разделенную пробелом байт в одной строке, используя od / awk / tr
    • , найдите шаблон IEND и замените на MATCH, используя sed / tr
    • , получите смещение MATCH, используя grep -b и cut
    • cal c фактическая длина файла (вычтите лишний пробел / CR, разделите на 3 шестнадцатеричных символа / пробел на байт, добавьте 12 для длины IEND)

Примечание : маловероятно, если не невозможно, что 12-байтовый блок IEND может происходить в PNG, но вышеупомянутое не проверяет его.

Это было забавное коронавирусное упражнение - спасибо!

1 голос
/ 03 мая 2020

Вы можете запустить pngcheck -v YOURFILE.png, и он сообщит вам, есть ли дополнительные байты в конце, и завершится со статусом ошибки 2.

Он также сообщит вам, где находится фактический конец файла is:

# Generate legitimate PNG with ImageMagick
convert -size 300x400 gradient:yellow-red orig.png

# Check its size
ls -l orig.png
-rw-r--r--  1 mark  staff  2509  3 May 17:47 orig.png

# Check it with `pngcheck` - exit status = 0, i.e. all ok
    File: orig.png (2509 bytes)
  chunk IHDR at offset 0x0000c, length 13
    300 x 400 image, 48-bit RGB, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk cHRM at offset 0x00035, length 32
    White x = 0.3127 y = 0.329,  Red x = 0.64 y = 0.33
    Green x = 0.3 y = 0.6,  Blue x = 0.15 y = 0.06
  chunk bKGD at offset 0x00061, length 6
    red = 0xffff, green = 0xffff, blue = 0xffff
  chunk IDAT at offset 0x00073, length 2276
    zlib: deflated, 32K window, maximum compression
  chunk tEXt at offset 0x00963, length 37, keyword: date:create
  chunk tEXt at offset 0x00994, length 37, keyword: date:modify
  chunk IEND at offset 0x009c5, length 0
No errors detected in orig.png (8 chunks, 99.7% compression).

Теперь добавьте немного Rubbi sh в конец:

ls -l >> orig.png

# Check the size again
ls -l orig.png
-rw-r--r--  1 mark  staff  8398  3 May 17:53 orig.png

# And check again - exit status =2
pngcheck -v orig.png
File: orig.png (8398 bytes)
  chunk IHDR at offset 0x0000c, length 13
    300 x 400 image, 48-bit RGB, non-interlaced
  chunk gAMA at offset 0x00025, length 4: 0.45455
  chunk cHRM at offset 0x00035, length 32
    White x = 0.3127 y = 0.329,  Red x = 0.64 y = 0.33
    Green x = 0.3 y = 0.6,  Blue x = 0.15 y = 0.06
  chunk bKGD at offset 0x00061, length 6
    red = 0xffff, green = 0xffff, blue = 0xffff
  chunk IDAT at offset 0x00073, length 2276
    zlib: deflated, 32K window, maximum compression
  chunk tEXt at offset 0x00963, length 37, keyword: date:create
  chunk tEXt at offset 0x00994, length 37, keyword: date:modify
  chunk IEND at offset 0x009c5, length 0
  additional data after IEND chunk
ERRORS DETECTED in orig.png

Он также сообщает вам, где настоящий конец файла находится в 3-й до последней строке, т.е. в 0x009c5. Вам нужно будет добавить 8 к этому, чтобы учесть размер самого IEND.


Кстати, если на macOS вы можете установить pngcheck с homebrew , используя :

brew install pngcheck
...