
Запись в архивы ARC, ZOO и LHZ без помощи архиватора
В первой части статьи о записи в архивы без помощи архиваторов я разобрал внутренний формат наиболее популярных современных архиваторов. Как я понял, особого интереса статья не вызвала, но материал на новую статью уже был практически подготовлен. Не пропадать же добру. В этой части я расскажу о том, как внедряться в более редкие форматы архивов: ARC, ZOO и LHZ без использования сторонних приложений. Поскольку такие раритеты найти уже проблематично, к каждому примеру я приложил сам архиватор и описание внутреннего формата его архивов. Ну а совсем экзотические архиваторы рассмотрены в третьей и четвертой частях статьи.ARC - формат архивов одноименного архиватора от компании System Enhancement Associates, который был достаточно широко распространен в 80-90-х годах прошлого века. Примечательно, что параметры его командной строки в последующем стали эталоном практически для всех других архиваторов с их появления и до нашего времени. Этот же формат архивов (но с расширением .PAK) также имеет архиватор PAK. Сейчас для операционных систем Windows появился архиватор FreeArc, который создает архивы с таким же расширением .ARC, но они имеют другой формат. Здесь я рассмотрю именно старый, DOS'овский формат архивов ARC.
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------
- ; ARC/PAK Header
- ;---------------------------------------------
- csig db ? ; Sign
- cmeth db ? ; Compression method (2 = store)
- cfname rb 13 ; 12 char File name ASCIIZ
- ccsize dd ? ; Compressed file size
- cdtm dd ? ; Date/Time
- cfcrc dw ? ; 16-bit CRC
- cosize dd ? ; Original file size
Code (Assembler) : Убрать нумерацию
- ; Признак окончание архива
- tail db 1Ah,00
- tail_length = $-tail
Записываемый файл предварительно надо загрузить в память, после этого заполняем поля заголовка архива:
- csig = 1Ah - байт сигнатуры начала блока данных;
- cmeth = 2 - метод сжатия, в нашем случае Store;
- cfname = имя файла в формате 8.3, завершается нулевым символом;
- cosize = размер оригинального файла;
- ccsize = размер сжатого файла (равен оригинальному);
- cdtm = дата и время создания файла;
- cfcrc = CRC-16 оригинального файла;
Формат ZOO появился также в начале 80-х годов и использовался в основном на компьютерах Commodore. Также были версии для UNIX и MS-DOS, но там он использовался очень редко, по крайней мере за всю мою многолетнюю практику работы под MS-DOS я встречал такие архивы всего несколько раз. Из-за малой распространенности архиватора и закрытого кода долгое время я не мог найти нормальной документации по его формату, поэтому все мои попытки внедрения в эти архивы заканчивались неудачей. И лишь совсем недавно мне в руки попали исходники архиватора WinZOO, где я за пару дней экспериментов наконец-то смог выяснить назначение, формат и правильное количество всех полей заголовка архива, а также узнал все остальные интересующие меня технические подробности. Так что перед вами, пожалуй, единственное в Интернете корректное описание внутреннего формата архива ZOO.
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------
- ; ZOO Header
- ;---------------------------------------------
- zsign dd ? ; Signature (0FDC4A7DCh)
- zentry db ? ; Type of directory entry (=2)
- zmeth db ? ; Compression method (0 = store)
- zdir dd ? ; Offset of next directory entry
- zfile dd ? ; Offset of next header
- zdtm dd ? ; Time/Date
- zfcrc dw ? ; File CRC 16
- zosize dd ? ; Original file size
- zcsize dd ? ; Compressed file size
- zver1 db ? ; Version this file was compressed by
- zver2 db ? ; Minimum version needed to extract
- zextr db ? ; Deleted flag
- zstruc db ? ; File structure if any
- zcmnto dd ? ; Offset of comment field, 0 if none
- zcmntl dw ? ; Length of comment field
- zfname rb 13 ; Filename (ASCIIZ)
- zvlen dw ? ; Length of variable part of dir entry
- ztzone db ? ; Timezone where file was archived
- zhcrc dw ? ; CRC 16 of directory entry
- zlead dd ? ; Allowing location of file data
- zres db ? ; Reserved
Code (Assembler) : Убрать нумерацию
- ; Признак окончание архива
- tail:
- tsign dd ? ; Signature (0FDC4A7DCh)
- tentry db ? ; Type of directory entry (=2)
- rb 49 ; Empty data
- tend dw ? ; End of archive
- tail_length = $-tail
- tsign = 0FDC4A7DCh - сигнатура заголовка;
- tentry = 2 - тип заголовка;
- tend = 83FCh - признак окончания архива;
- zsign = 0FDC4A7DCh - сигнатура заголовка;
- zentry = 2 - тип заголовка;
- zmeth = 0 - тип компрессии Store;
- zvlen = 0 - размер блока с дополнительными данными;
- ztzone = 07Fh - временная зона, в которой был создан архив;
- zlead = '@)#(' - маркер начала упакованных данных;
- zdtm = дата и время создания файла;
- zfcrc = CRC-16 оригинального файла;
- zosize = размер оригинального файла;
- zcsize = размер сжатого файла (равен оригинальному);
- zfname = имя файла в формате 8.3, завершается нулевым символом;
- zhcrc = CRC-16 заголовка от поля zsign до поля zhcrc включительно;
- zdir = адрес следующего архивного блока в архиве от начала файла;
- zfile = адрес начала упакованных данных от начала файла;
При внедрении в архивы ZOO надо установить указатель на 56 байт от конца файла, чтобы перекрыть существующий "хвост" архива. После этого записать сформированный заголовок, затем наш файл, и после этого дописать заполненный "хвост" архива. С форматом ZOO тоже разобрались.
LHZ - также один из первых появившихся форматов архивов. Разработанный японцами еще в 80-х годах, он был неоднократно "клонирован" другими разработчиками, портирован на различные операционные системы, поэтому этот формат архива встречается и в других архиваторах, например, LHA и ICE. Несмотря на столь почтенный возраст, этот архиватор до сих пор успешно используется на своей родине - Японии, а также применяется для хранения сжатых данных в некоторых программах и играх. Я встретил как минимум две разных структуры файлов формата LHZ. Как я понял, в новых версиях используются расширенные заголовки с дополнительными полями. Но так как в новых версиях осталась поддержка старого формата, то и внедряться в архивы мы будем, используя заголовки старого формата. Как показали опыты, гибрид из архива нового формата с дописанным к нему файлом со старым заголовком остается вполне корректным, проходит все проверки и прекрасно распаковывается.
Code (Assembler) : Убрать нумерацию
- ;---------------------------------------------
- ; LHA/LZH/ICE Header
- ;---------------------------------------------
- lsig db ? ; Header size
- lhcrc db ? ; --> Header CRC
- lmeth rb 5 ; Packing method '-lh0-' = store
- lcsize dd ? ; --> Compressed file size
- losize dd ? ; --> Original file size
- ldtm dd ? ; Time/Date
- lflag dw ? ; File attribute
- lnlen db ? ; Filename length
- lfname rb (?) ; Filename (ASCII)
- lfcrc dw ? ; --> File CRC 16
- lres1 db ? ; Reserved 1
- lres2 dw ? ; Reserved 2
Code (Assembler) : Убрать нумерацию
- ; Признак окончания архива - нулевой байт
- tail db 0
- tail_length = $-tail
- lsig = размер заголовка от lsig до lres1 включительно;
- lmeth = '-lh0-' - метод компрессии Store;
- losize = размер оригинального файла;
- lcsize = размер сжатого файла (равен оригинальному);
- ldtm = дата и время создания файла;
- lflag = 120h - атрибуты файла;
- lnlen = длина имени файла с расширением;
- lfname = имя файла;
- lfcrc = CRC-16 оригинального файа;
- lres1 = 'M' - какое-то служебное поле;
После заполнения заголовка надо переместить указатель на 1 байт от конца файла, чтобы удалить существующий "хвост" архива. После этого записываем сформированный заголовок, за ним внедряемый файл и "хвост" архива, состоящий из нулевого символа. Точно так же выполняется запись в архивы форматов ICE, LHA и других, имеющих аналогичную структуру.
В приложении примеры программ с исходными текстами, демонстрирующие все три описанных способа записи в архивы. При каждом запуске программа дописывает себя к архиву "example" соответствующего формата, выбирая случайное имя исполняемого файла.
Просмотров: 8352 | Комментариев: 4
Метки: Assembler, архиваторы

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(22.02.2013 в 18:59):
Окей, перефразирую свою мысль :) Есть программа, которая создает архивы с расширением .ICE, которые, в свою очередь, по внутреннему формату полностью соответствуют архивам LZH/LHA. А уж кто там у кого чего притырил - это уже пусть другие разбираются.

lammer
(22.02.2013 в 18:51):
<ICE> - нет такого архиватора, это была (красиво хакнутая) версия LHArc 1.13, отличавшаяся (в лучшую сторону) только оформлением. Появление ICE 1.14, в свое время, вызвало большой шум, файл был немедленно дизассемблирован и установлена его бинарная идентичность с LHArc 1.13, исключая замену нескольких текстовых элементов (название итд.)

ManHunter
(22.02.2013 в 18:46):
Их я видел, я больше провозился с вычислением контрольных сумм заголовка. А этот кусок был нормально описан только в исходниках WinZoo.

lammer
(22.02.2013 в 18:40):
исходники ZOO 2.10 давно валяются по всему инету. Или речь не об этой версии? http://en.wikipedia.org/wiki/Z...le_format%29

Добавить комментарий
Заполните форму для добавления комментария
