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

Для восстановления файлов по сигнатуре непременным условием является хорошее знание структуры формата файла.
В качестве примера рассмотрим графический файл JPEG (файл с расширением jpg). Не буду описывать его формат, а просто привожу ссылку на хорошую статью, в которой все подробно описано. В принципе достаточно знание и одной сигнатуры файла (начальная последовательность байт, однозначно идентифицирующая определенный тип файлов).
Для файлов jpg такой последовательностью являются два байта FF D8, но обычно во всех базах и справочниках за сигнатуру файлов jpg принимают 4 байта - FF D8 FF E0. И как видим из описания формата jpg, конец файла завершается двумя байтами FF D9

Для поиска лучше разделить образ/дамп (раздела, флэшки и др.) на части, например, по 5 Гигов или меньше или больше или вообще не делить - все зависит от размера образа/дампа и быстродействия компа.
Можно, конечно, использовать для поиска hexeditor, но там есть свои нюансы. Лучше использовать чисто ручной поиск.
И так приступим. В качестве подопытного выбрал файл-образ учебной системы с btrfs размером 1G (~/btrfs-image), в котором хранится три типа файлов: jpg, odt, txt.
Как уже писал, выбран файл jpg, имеющий сигнатуру FF D8 FF E0, вот ее и будем искать, используя утилиту od.
Важно - сигнатуру прописывать маленькими буквами, отделяя каждый байт пробелом.

od -A d -t x1 ~/btrfs-image | grep "ff d8 ff e0"
13660160 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60

13660160 - это смещение (номер байта в 10-ом исчислении), начиная с которого в ~/btrfs-image начинается расположение нужного нам файла. Проверим, что мы нашли, но уже используя утилиту hexdump
hexdump -C -s 13660160 -n 16 ~/btrfs-image
00d07000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 |......JFIF.....`|
и видим, что это точно jpg - видим наличие JFIF

Ищем конец файла, но начинаем искать со смешением 13660160
od -A d -t x1 -j 13660160 ~/btrfs-image | grep "ff d9"
13858368 50 6c 03 b9 fc e8 a2 b3 70 8f 63 5b b3 ff d9 00
Определяем, что файл заканчивается на байте 13858383, проверяем hexdump, но пропустим 13858382 байта (на 1 байт меньше и первым байтом должно быть d9)
hexdump -C -s 13858382 -n 16 ~/btrfs-image
00d3764e d9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Все верно, а дальше идут нули.
Вытаскиваем этот файл с помощью dd - скопируем из файла ~/btrfs-image 198223 байт (13858383 - 13660160), пропустив 13660160 байт
dd if=~/btrfs-image of=~/test.jpg skip=13660160 bs=1 count=198223
Открываем файл test.jpg и убеждаемся, что все нормально.

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

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

13660144 d0 ee ff e0 00 10 4a 46 49 46 00 01 01 01 ff d8
13660160 ff e0 12 45 10 4a 46 49 46 00 01 01 01 00 60 ff

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

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

Положительные - байты, не являющиеся реперными, можно менять, удалять и это не скажется на открытии изображение. Это частенько используют при защите паролей, небольших файлов - называется сей способ стеганография и есть даже специальные утилиты для этого. Но, имхо, применение любой утилиты связано тоже с сигнатуорй, которую накладывает данная утилита, а значит сам факт наличия чего то спрятанного в изображении можно установить. Кстати, даже есть такие антиутилиты, которые позволяют это делать. Один плюс - вычислить это довольно сложно, да и редко кто сможет.
Лично я использую для этого чисто ручной способ. Хоть сейчас езжу редко, но раньше в поездках всегда брал с собой флешку, на которой находилось несколько (2-3) часто используемых паролей, не запоминаемых. Использовать всякие утилиты для шифрования не удобно, намного проще спрятать эти пароли в какой-нибудь картинке, в определенном месте, hexeditor-ом посмотреть не проблема, а, главное, никогда не вычислишь любым способом.
Ошибки не исчезают с опытом - они просто умнеют