Как испортить архивный файл контролируемым образом?

23

Я написал функцию, которая проверяет поврежденный архив, используя контрольную сумму CRC.

Чтобы проверить это, я просто открыл архив и зашифровал содержимое с помощью шестнадцатеричного редактора. Проблема в том, что я не верю, что это правильный способ создания поврежденного файла.

Есть ли другой способ создать «контролируемое повреждение», чтобы оно не было полностью случайным, но могло имитировать то, что происходит с настоящими поврежденными архивами? Мне никогда не приходилось специально что-то портить, поэтому я не совсем уверен, как это сделать, кроме случайного шифрования данных в файле.

барабанный бой
источник
Какой инструмент используется для «архивирования», под поврежденным вы подразумеваете содержимое одного из файлов в архиве или сам архив?
Драв Слоан
Я использую tar в качестве формата архива. Я хотел бы испортить только содержимое файла; поэтому сам архив все еще распознается как файл tar. Моя функция распаковать файл; У меня есть случай, когда там файл поврежден, но я хочу проверить, что происходит, когда файл внутри архива поврежден.
rataplan

Ответы:

22

Я не проводил много нечетких испытаний , но вот две идеи:

Запишите несколько нулей в середину файла. Используйте ddс conv=notrunc. Это записывает один байт (размер блока = 1 счетчик = 1):

dd if=/dev/zero of=file_to_fuzz.zip bs=1 count=1 seek=N conv=notrunc

Использование /dev/urandomв качестве источника также вариант.

В качестве альтернативы, пробейте несколько отверстий 4k с помощью fallocate --punch-hole. Вы могли бы даже fallocate --collapse-rangeвырезать страницу, не оставляя заполненной нулями дыры. (Это изменит размер файла).

Загрузка, возобновленная в неправильном месте, будет соответствовать --collapse-rangeсценарию. Неполный торрент будет соответствовать punch-holeсценарию. (Разреженный файл или предварительно выделенные экстенты, либо читаются как ноль в любом месте, которое еще не было записано.)

Плохое ОЗУ (в системе, из которой вы загрузили файл) может привести к повреждению, а оптические приводы также могут повредить файлы (их ECC не всегда достаточно прочен, чтобы полностью восстановиться от царапин или выцветания красителя).

Секторы DVD (блоки ECC) имеют размер 2048B , но могут возникнуть ошибки в один байт или даже в один бит. Некоторые накопители, скорее всего, будут выдавать вам некорректные некорректируемые данные вместо ошибки чтения для сектора, особенно если вы читаете в необработанном режиме или когда он называется.

Питер Кордес
источник
1
Из-за того, как работают жесткие диски, заполнение нулями блока с 4K-выравниванием 4K или 512-байтового с 512-байтовым блоком является наиболее реалистичным.
Марк
@Mark: О, если вы думаете о коррупции, вызванной HD, то да. Плохая память на чьем-то компьютере может немного перевернуться в середине файла. Точно так же обратная передача на / с плохого оптического диска может обнулить меньший фрагмент (коды DVD ECC работают с другим размером фрагмента).
Питер Кордес
10

Другие ответы в основном касаются аппаратных ошибок. Позвольте мне перечислить некоторые программные повреждения:

  • LF заменен на CRLF.
  • CR удален. (Даже если не следует LF)
  • Добавлены дополнительные нулевые байты.
  • Добавлен дополнительный код Unicode "Byte Order Mark".
  • Набор символов преобразуется из UTF-8 в Latin-1 или наоборот.
  • EOS-символ DOS (# 1A) удален, даже если он не находится в конце файла.

Эти вещи довольно безвредны при работе с текстовыми файлами, но, как правило, смертельно при применении к двоичным файлам.

Стиг Хеммер
источник
О, хорошие! Также конверсии в другую сторону, конечно. Заголовок PNG имеет несколько ошибок при проверке подобных ситуаций: w3.org/TR/PNG-Rationale.html#R.PNG-file-signature
Дьюи Морган,
7

Используйте ddдля усечения файла или попробуйте двоичный редактор, например, hexerдля редактирования и внесения некоторых искажений.

Пример усечения файла с использованием dd

Создать 5 МБ файл

# dd if=/dev/zero of=foo bs=1M count=5
5+0 records in
5+0 records out
5242880 bytes (5.2 MB) copied, 0.0243189 s, 216 MB/s
# ls -l foo
-rw-r--r-- 1 root root 5242880 Aug 12 20:13 foo
#

Обрезать 10 байтов от конца

# dd if=foo of=foo-corrupted bs=1 count=5242870
5242870+0 records in
5242870+0 records out
5242870 bytes (5.2 MB) copied, 23.7826 s, 220 kB/s
# ls -l foo foo-corrupted
-rw-r--r-- 1 root root 5242880 Aug 12 20:13 foo
-rw-r--r-- 1 root root 5242870 Aug 12 20:14 foo-corrupted
#

Man-страница Hexer

HEXER(1)                              General Commands Manual                             HEXER(1)

NAME
   hexer - binary file editor

SYNOPSIS
   hexer [options] [file [...]]

DESCRIPTION
   hexer  is  a  multi-buffer  editor  for  viewing  and  manipulating binary files.  It can't
   (shouldn't) be used for editing block devices, because it tries to load the whole file into
   a  buffer (it should work for diskettes).  The most important features of hexer are:  multi
   buffers, multi level undo, command line editing with completion, binary regular expressions
   (see  below).   The  user  interface  is  kept similar to vi, so if you know how to use vi,
   you'll get started easily.
Стив
источник
Спасибо Стив. будет ли это имитировать то, что происходит в реальном сценарии? Как будто вы копируете архив из сети и он поврежден? Я считаю, что неудачная загрузка может быть смоделирована с помощью dd, чтобы обрезать файл. Это было бы точно?
Раплан
2
Да, с помощью усечения файла ddэто имитирует сценарий реального мира, в котором создается только часть файла. А редактирование, использующее hexer для введения некоторого поддельного контента, имитирует другой тип искажения. Кроме того, на md5sumчто стоит обратить внимание, он вычисляет контрольную сумму md5 для файла.
Стив
1
@newbiez, случайное усечение симулирует сбой сети, а усечение на границе 4 КБ или 512 байт имитирует сбой диска.
Марк
Как вы на самом деле обрезать файл с помощью dd?
Эдвард Торвальдс
@edward torvalds - добавлен пример dd truncate
Стив
2

Предложение:

Начните писать в архив и остановите запись, прежде чем она закончится. Это может произойти во время отключений питания и других сценариев.

Реальный сценарий жизни:

Однажды я испортил zip-файл, пытаясь скопировать в него больше данных, чем поместилось бы на носителе. Windows (это была Windows 7 в безопасном режиме ftr) пыталась завершить действие, прежде чем выяснить, достаточно ли места, и к тому времени, когда она выяснила это, файл был наполовину полон и, следовательно, поврежден. Я надеюсь, что они исправили эту проблему в более поздних версиях Windows или это был просто безопасный режим.

Pharap
источник
2

Другим распространенным типом искажений является битовое перемешивание: когда один бит (или несколько бит) переключается в потоке данных.

Таким образом, байт 1111 0000может стать, скажем, 1111 0010или 1011 0000или 1110 1100или как угодно.

Системы 1110 1000контроля чётности и подсчета чеков имеют проблемы с такими вещами, как, например , равное количество множеств и неустановок, так как и чётность, и количество единиц остаются одинаковыми.

Поэтому замена всех экземпляров случайного символа его обратным, скажем, от 0x57 до 0x75 (от '9' до 'K') или наоборот, может быть не обнаружима. Для систем, которые имеют mysql, команда «заменить» существует как раз для такой цели:

replace K 9 < goodInputFile > corruptedOutputFile

Вы также можете попробовать поменять местами буквы K и 9, что будет особенно хорошим тестом, если они оба появятся в файле одинаковое количество раз:

replace K 9 9 K < goodInputFile > corruptedOutputFile

Используйте man replaceдля получения дополнительной информации.

Деви Морган
источник
0

Случайные изменения поврежденных тестовых данных не являются хорошим подходом, так как вы не можете воспроизвести образец для повторного запуска тестов.

Я был бы счастлив только с 3 выборками, меняя только 1 бит в первом байте, в последнем байте и в любом среднем байте. Но только 1 бит, а не весь байт.

Но лучшим тестовым образцом будет тот, в котором вы можете генерировать образцы, меняя каждый бит файла с первого до последнего байта. Этого нельзя (обычно) получить с помощью обычных инструментов, вам нужно создать один (я думаю).

При таком подходе вы изолируете множество возможностей, включая порядковый номер, если ваш алгоритм основан на одном виде порядкового номера. В других руках большой образец может потребовать много времени для обработки.

Наконец, некоторые примеры усечения или добавления байтов завершат ваши тесты.

Лучано
источник