vasek |
|
Темы:
48
Сообщения:
11320
Участник с: 17 февраля 2013
|
Сегодня чистил ноут от мусора - удалял не нужный хлам (софт, файлы и пр.) и попался на глаза один документ, как то молодежь попросила провести ликбез - вот и решил выложить текст в блоги, может кому и пригодится. Ничего интересного нет, но в жизни все бывает. Безусловно, термин нестандарно упакованные файлы не удачен, но другого лучшего выражения не придумал, да и в общем то это не суть так важно. А суть в следующем — встречаются файлы, про которые точно знаешь, что они упакованы определенным архиватором, а распаковать их стандартным способом не можешь, или, например, распаковал, а в распакованном файле обнаруживаешь другие упакованные файлы, распаковать которые тоже обычным способом не получается. Вот о распаковке таких файлов и хочу поделиться опытом с пользователями, которые с этим не знакомы. А чтобы бы понять саму идею распаковки таких файлов, сначала немного поэкспериментируем, а для проведения экспериментов упакуем/заархивируем произвольный простой файл, но сначала создадим его $ echo 'Т Е С Т' > ~/test Убедимся, что файл создан $ cat ~/test Т Е С Т упакуем этот файл, например, архиватором gzip $ gzip ~/test и посмотрим на упакованный файл утилитой hexdump, точнее посмотрим 1-ые 16 байт $ hexdump -C -n 16 ~/test.gz 00000000 1f 8b 08 08 9e 52 18 59 00 03 74 65 73 74 00 bb |.....R.Y..test..| Первые 3 байта — это так называемая сигнатура (HEX код) архиватора gzip - 1F 8B 08, которая является составной частью упакованного файла (его началом) и присуща только архиватору gzip, что позволяет отличить этот файл от других и, главное, видно, что архиватор, точнее сигнатура начинается с самого начала (с нулевого байта, смещение равно 0). UPD - если быть точным, то сама сигнатура два байта (0x1f, 0x8b), а 3-ий байт определяет compression method (08 - deflate) При распаковке этого файла, утилита gzip сначала проверит наличие сигнатуры, присущей gzip, и только после этого примет решение о распаковке. Проверим это, а для чего изменим сигнатуру файла, точнее, изменим 1-ый байт — вместо 1F запишем 1E (я проделал это в hex редакторе) $ hexdump -C -n 16 ~/test.gz 00000000 1e 8b 08 08 9e 52 18 59 00 03 74 65 73 74 00 bb |.....R.Y..test..| Ну и попытаемся рапаковать $ gzip -d ~/test.gz gzip: ~/test.gz: not in gzip format И то же самое будет, если сигнатура будет правильная, но начинаться будет не с начала файла (смещение не равно 0) — вернем все на место, но перед сигнатурой запишем 1 байт — 00 (я сохранил этот файл, как test1.gz). $ hexdump -C -n 16 ~/test1.gz 00000000 00 1f 8b 08 08 9e 52 18 59 00 03 74 65 73 74 00 |......R.Y..test.| $ gzip -d ~/test1.gz gzip: ~/test1.gz: not in gzip format И значит распаковывать такие файлы нужно по-другому, а именно, нужно указать при распаковке смещение, откуда начинать, т.е. где начинается сигнатура. Самый простой вариант — удалить байты до сигнатуры, но это не этично, да и иногда это выливается в мегабайты и десятки мегабайт. Лучше поступить грамотно — указать утилите смещение, с которго начинать распаковку (делаем пропуск с помощью dd в 1 байт прежде чем начать распаковку) $ dd if=~/test1.gz skip=1 bs=1 | gzip -d > test1 Проверим, что мы получили $ cat ~/test1 Т Е С Т То есть распаковали успешно и получили исходный файл. И так на простом файле показал суть и сам принцип распаковки таких нестандартно упакованных файлов. Но в жизни все сложнее, но когда понимаешь суть, то можно распаковать и более сложные файлы. Попробуем сейчас опробовать наши знания на ядре Archlinux - пример неудачный, но полезный для обучения. Справка - ядро, как правило, находится в сжатом виде, но, главное, сжатое ядро представляет собой загрузчик и распаковщик, за которым следует собственно сжатый алгоритмом zlib vmlinux, а потому сначала необходимо отделить сжатое ядро от загрузчика. Сначала используя утилиты hexdump и file попробуем выяснить, что же это такое, наше ядро # hexdump -C -n 16 /boot/vmlinuz-linux 00000000 4d 5a ea 07 00 c0 07 8c c8 8e d8 8e c0 8e d0 31 |MZ.............1| Судя по сигнатуре 4d 5a (MZ) перед нами стандартный исполняемый формат (исполняемый DOS файл), сигнатура которого 4D 5A (MZ) составлена из инициалов одного из создателей MS-DOS Марка Збиковски. $ file /boot/vmlinuz-linux /boot/vmlinuz-linux: Linux kernel x86 boot executable bzImage, version 4.7.6-1-ARCH (builduser@tobias) #1 SMP PREEMPT Fri Sep 30 19:46, RO-rootFS, swap_dev 0x4, Normal VGA И в итоге подтверждается сказанное выше, что сжатое ядро представляет собой загрузчик + распаковщик + само ядро сжатое алгоритмом zlib архиватора gzip с распаковкой в процессе загрузки. Но нам, главное, понятно (по 1-ой части), чтобы распаковать ядро, нам нужно отделить сжатое ядро от загрузчика. Как нам уже известно, gzip имеет сигнатуру 1f 8b 08 — вот и найдем его начало. Перечислю способы, которыми можно это сделать. 1. Используя hex-редактор, например, bless - определяем, что 1f 8b 08 начинается с адреса 0х4501 или в 10 системе — 17665 UPD — делал и писал давно (обучал молодежь), так что число 17665 уже будет другое. 2. Используя утилиту od od -A d -t x1 vmlinuz-linux | grep "1f 8b 08" 0017664 e0 1f 8b 08 00 00 00 00 00 02 03 ec 5a 7b 74 53 и получаем опять 17665 3. Очень хорошую утилиту binwalk binwalk vmlinuz-linux Как видим совпадает во всех случаях - 17665Остается только извлечь из vmlinuz сжатое ядро и распаковать его: dd if=vmlinuz-linux skip=17665 bs=1 | gzip -d > vmlinux gzip: stdin: decompression OK, trailing garbage ignored Желающие могут снова применить binwalk - binwalk vmlinux и увидят уже названия файлов, правда вытащить их просто так уже не получится. Вот и все. binwalk также удобно использовать для определения архиватора, в случае если есть сомнения. Утилита включает большую базу сигнатур известных архиваторов. Но, разумеется, база базой, но лучше всегда перепроверить ручками, использую hex-редактор. Ну и бонус на посошок любителям паролей - можно не вешать никакие пароли на сжимаемый файл, а просто ручками добавить в начало несколько байтов, но ЛУЧШЕ изменить сигнатуру и никто этот файл не распакует. Конечно, эти изменения должны быть постоянны и легко запоминаемы.
Ошибки не исчезают с опытом - они просто умнеют
|