Blog. Just Blog

Распаковка данных в формате LZE на Ассемблере

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

Продолжаем тему о распаковке сжатых данных. Сегодня это будет алгоритм LZE. Этот алгоритм разработал в далеком 1989 году Fabrice Bellard, известный как один из разработчиков проекта FFmpeg и упаковщика исполняемых файлов LZEXE, популярного во времена MS-DOS. В этом упаковщике и применялся указанный алгоритм. Fabrice Bellard не стал выкладывать описание LZE в публичный доступ, но в 1995 году японец Hiroaki Goto отреверсил алгоритм и опубликовал его на своем сайте. Я перевел его функцию распаковки с 16-битного Ассемблера на 32-битный, теперь ее, так же как и LZ4, можно использовать в своих проектах.

Для упаковки данных надо использовать утилиту из прилагаемого архива. Чтобы получить размер памяти, необходимой для распаковки, никаких дополнительных танцев с бубном совершать не надо. Размер исходной информации записан в первом DWORD'е упакованных данных, только к нему надо будет применить команду BSWAP, чтобы установить правильный порядок байт. С 4-го байта идут сами упакованные данные. Коэффициент сжатия получается неплохим, на некоторых файлах он превосходит LZ4, на некоторых уступает ему, так что подбирайте инструмент под задачу.
  1. ;------------------------------------------------------------
  2. ; Распаковка данных в формате LZE
  3. ;------------------------------------------------------------
  4. ; Оригинальный код: Hiroaki Goto, модификация: ManHunter / PCL
  5. ;------------------------------------------------------------
  6. ; На входе:
  7. ;   lpCompressed - указатель на упакованные данные
  8. ;   lpOut - указатель на буфер для распакованных данных
  9. ; На выходе:
  10. ;   EAX = размер распакованных данных
  11. ;------------------------------------------------------------
  12. proc lze_unpack lpCompressed:DWORD,lpOut:DWORD
  13.         pusha
  14.  
  15.         mov     esi,[lpCompressed]
  16.         lodsd
  17.         mov     edi,[lpOut]
  18.  
  19.         mov     ebx,esi
  20.         cld
  21.         mov     dh,1
  22. .decode_lze_1:
  23.         mov     al,byte[ebx]
  24.         inc     ebx
  25.         stosb
  26. .decode_lze_2:
  27.         stdcall .decode_bit_test
  28.         jc      .decode_lze_1
  29.         xor     eax,eax
  30.         dec     ax
  31.         stdcall .decode_bit_test
  32.         jc      .decode_lze_5
  33.         xor     ecx,ecx
  34.         stdcall .decode_bit_test
  35.         adc     ecx,ecx
  36.         stdcall .decode_bit_test
  37.         adc     ecx,ecx
  38.         mov     al,byte[ebx]
  39.         inc     ebx
  40. .decode_lze_3:
  41.         inc     ecx
  42. .decode_lze_4:
  43.         mov     esi,edi
  44.         movsx   eax,ax
  45.         add     esi,eax
  46.         inc     ecx
  47.         rep     movsb
  48.         jmp     .decode_lze_2
  49. .decode_lze_5:
  50.         mov     ah,byte[ebx]
  51.         inc     ebx
  52.         mov     al,byte[ebx]
  53.         inc     ebx
  54.  
  55.         mov     ecx,eax
  56.         shr     eax,3
  57.         or      ah,0E0h
  58.         and     ecx,7
  59.         jnz     .decode_lze_3
  60.         mov     cl,byte[ebx]
  61.         inc     ebx
  62.         or      cl,cl
  63.         jnz     .decode_lze_4
  64.  
  65.         sub     edi,[lpOut]
  66.         mov     [esp+28],edi
  67.         popa
  68.         ret
  69.  
  70. .decode_bit_test:
  71.         dec     dh
  72.         jnz     @f
  73.         mov     dl,byte[ebx]
  74.         inc     ebx
  75.         mov     dh,8
  76. @@:
  77.         add     dl,dl
  78.         retn
  79. endp
В качестве параметров передается указатель на упакованные данные и указатель на буфер-приемник. На выходе в регистре EAX возвращается количество байт, которое было извлечено из сжатых данных. Размер принимающего буфера в процессе распаковки никак не проверяется, об этом вы должны позаботиться самостоятельно.

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

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

LZE.Unpack.Demo.zip (56,226 bytes)


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

Метки: Assembler

Комментарии

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

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

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

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