Blog. Just Blog

Распаковка данных с помощью LZ-функций

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Распаковка данных с помощью LZ-функций
Распаковка данных с помощью LZ-функций

В статьях о распаковке, опубликованным на этом сайте, мы рассмотрели уже несколько системных способов компрессии и декомпрессии данных. Сегодня разберем еще один. Это функции, появившиеся еще в ранних версиях Windows и использовавшиеся, в основном, в инсталляторах. Речь идет о LZ-функциях, в которых применяется алгоритм Lempel-Ziv, он же LZ77.

Суть всей движухи в том, что есть файлы, упакованные утилитой compress.exe, и есть утилиты и функции, которые эти упакованные файлы разворачивают в исходное состояние. Как я уже говорил, именно это используется в инсталляторах от Microsoft. Долгое время утилита compress.exe была доступна для скачивания на официальном сайте MS в составе Windows Server 2003 Resource Kit, но потом страница загрузки пропала. Не удивлюсь, если для скачивания надо без регистрации и СМС обновить систему до Windows 10. Шутка. К счастью, оригинальная копия дистрибутива пока еще доступна в интернет-архиве. Сторонники открытого ПО тоже не остались в стороне и нарисовали совместимый аналог, скачать его можно на офсайте. Последние на момент публикации статьи версии упаковщика и распаковщика находятся в прилагаемом архиве.

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

Переходим к практике. Сперва нам понадобится структура, которая используется для работы с упакованными файлами.
  1. struct OFSTRUCT
  2.     cBytes     db ?
  3.     fFixedDisk db ?
  4.     nErrCode   dw ?
  5.     Reserved1  dw ?
  6.     Reserved2  dw ?
  7.     szPathName rb 128
  8. ends
Весь процесс распаковки сводится к открытию упакованного файла специальной функцией и чтению из него данных с их автоматической распаковкой.
  1. ofs     OFSTRUCT
  2.         ...
  3.         ...
  4.         ; Открыть файл с упакованными данными
  5.         invoke  LZOpenFile,packed_file,ofs,OF_READ
  6.         mov     ebx,eax
  7.         ; Прочитать и распаковать данные
  8.         invoke  LZRead,ebx,unpacked_data,[original_size]
  9.         invoke  LZClose,ebx
Можно распаковывать сразу из файла в файл. Такой способ удобно применять в инсталляторах.
  1.         ; Открыть файл с упакованными данными
  2.         invoke  LZOpenFile,packed_file,ofs,OF_READ
  3.         mov     ebx,eax
  4.         ; Создать файл-приемник
  5.         invoke  _lcreat,original_file,0
  6.         mov     esi,eax
  7.         ; Прочитать, распаковать данные и записать их в новый файл
  8.         invoke  LZCopy,ebx,esi
  9.         ; Закрыть файлы
  10.         invoke  LZClose,ebx
  11.         invoke  _lclose,esi
При использовании LZ-функций нет способов заранее узнать, какой размер данных понадобится для принятия распакованных данных. Так что придется или читать данные по частям, или резервировать память на основании ранее сохраненной информации о размере исходных данных, или обрабатывать возвращенный код ошибки и циклически увеличивать размер буфера-приемника. Все варианты плохие. Второй огромный минус, что с помощью LZ-функций нельзя распаковывать данные, находящиеся в памяти, в качестве источника у них могут быть только файлы. При этом одновременно могут быть открыты не более 16 упакованных файлов. Даже если упакованные данные хранятся где-то еще, для их извлечения все равно придется создавать локальный файл и записывать их туда. Третий минус в том, что в случае ошибки вам придется довольствоваться той скудной информацией, которую возвращают LZ-функции, вызывать GetLastError бесполезно. Совсем крохотный плюс в том, что если обрабатываемый файл не содержит упакованные данные, то с помощью LZ-функций он просто будет загружен в память или скопирован на диск.

В приложении пример программы с исходным текстом, которая извлекает из файла иконку, упакованную по алгоритму LZ, и выводит ее на форму. Также в архиве утилиты для работы с упакованными файлами.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

LZ.Unpack.Demo.zip (51,250 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 358 | Комментариев: 0

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2022
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0051 сек.) / Память: 4.75 Mb
Наверх