Blog. Just Blog

gzuncompress и gzinflate: Assembler vs PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
При разработке проекта Massacre возникла необходимость реализовать функции распаковки PHP-кода на Ассемблере. В этой статье я распишу все выкладки по этому вопросу. Кому-нибудь пригодится - хорошо, не пригодится - оставлю для себя, чтобы не забыть. Как всегда, начнем с теории. Функции gzuncompress и gzinflate обратны к функциям gzcompress и gzdeflate, соответственно. Все они используют алгоритм сжатия LZW, который также используется в бесплатной библиотеке zlib. Сперва скачаем эту библиотеку и воспользуемся Ассемблером, чтобы сжать какую-нибудь эталонную строку.
  1. format PE GUI 4.0
  2. entry start
  3.  
  4. include 'win32a.inc'
  5.  
  6. section '.data' data readable writeable
  7.  
  8. strr    db 'ManHunter'  ; Строка для компрессии
  9. lend    = $-strr
  10. bsize   = 1000
  11.  
  12. blen    dd bsize
  13.  
  14. tmp     rb bsize
  15. tmp2    rb bsize
  16. tmp3    rb bsize
  17.  
  18. mask    db '%.2X ',0
  19.  
  20. ;----------------------------------------------------------
  21.  
  22. section '.code' code readable executable
  23. start:
  24.  
  25.         invoke  compress,tmp,blen,strr,dword lend
  26.  
  27.         mov     ecx,[blen]
  28.         mov     esi,tmp
  29. @@:
  30.         push    ecx
  31.         movzx   eax,byte [esi]
  32.         invoke  wsprintf,tmp2,mask,eax
  33.         add     esp,12
  34.         invoke  lstrcat,tmp3,tmp2
  35.         inc     esi
  36.         pop     ecx
  37.         loop    @b
  38.  
  39.         invoke  MessageBox,HWND_DESKTOP,tmp3,NULL,MB_OK
  40.         invoke  ExitProcess,0
  41.  
  42. ;----------------------------------------------------------
  43.  
  44. section '.idata' import data readable writeable
  45.  
  46. library kernel32,"kernel32.dll",\
  47.         user32,"user32.dll",\
  48.         zlib,"zlib1.dll"
  49.  
  50. include "apia\kernel32.inc"
  51. include "apia\user32.inc"
  52.  
  53.   import zlib,\
  54.          compress,'compress'
В окне будет показана следующая строка:

78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
Часть строки я специально выделил красным цветом, дальше будет понятно зачем это сделано.

А теперь проделаем то же самое, но на PHP. Простенький скрипт покажет результаты работы обеих функций с разными параметрами сжатия. Строка, естественно, та же самая.
  1. <?
  2. $str="ManHunter";
  3.  
  4. for ($cl=0$cl<=10$cl++) {
  5.   if ($cl==10) {
  6.     echo "DFLT - ";
  7.     $tmp=gzdeflate($str);
  8.   }
  9.   else {
  10.     echo "CL=".$cl." - ";
  11.     $tmp=gzdeflate($str,$cl);
  12.   }
  13.   for ($i=0$i<strlen($tmp); $i++) {
  14.     printf("%02X ",ord(substr($tmp,$i,1)));
  15.   }
  16.   echo "<br>";
  17. }
  18.  
  19. echo "<br>";
  20.  
  21. for ($cl=0$cl<=10$cl++) {
  22.   if ($cl==10) {
  23.     echo "DFLT - ";
  24.     $tmp=gzcompress($str);
  25.   }
  26.   else {
  27.     echo "CL=".$cl." - ";
  28.     $tmp=gzcompress($str,$cl);
  29.   }
  30.   for ($i=0$i<strlen($tmp); $i++) {
  31.     printf("%02X ",ord(substr($tmp,$i,1)));
  32.   }
  33.   echo "<br>";
  34. }
  35. ?>
Результаты работы скрипта:

CL=0 - 01 09 00 F6 FF 4D 61 6E 48 75 6E 74 65 72
CL=1 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=2 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=3 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=4 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=5 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=6 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=7 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=8 - F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=9 - F3 4D CC F3 28 CD 2B 49 2D 02 00
DFLT - F3 4D CC F3 28 CD 2B 49 2D 02 00

CL=0 - 78 01 01 09 00 F6 FF 4D 61 6E 48 75 6E 74 65 72 11 11 03 93
CL=1 - 78 01 F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=2 - 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=3 - 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=4 - 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=5 - 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=6 - 78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=7 - 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=8 - 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=9 - 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
DFLT - 78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93

Здесь тоже выделены некоторые строки. Они частично совпадают в случае использования gzdeflate и gzcompress, а в случае gzcompress с дефолтной степенью сжатия строка вообще полностью идентична результатам вызова функции compress библиотеки zlib. Можно сделать первые выводы: результат работы gzdeflate - только упакованные данные, а gzcompress - заголовок + упакованные данные + служебные данные. Возможно, служебные данные - это контрольная сумма или что-то около того, потому что при ее изменении распаковка вылетает с ошибкой. Но упакованные данные, выделенные красным цветом, во всех трех случаях одинаковые. Отсюда следует, что строка, сжатая командой gzcompress, распаковывается функцией uncompress библиотеки zlib без каких-либо изменений, и если в коде PHP-скрипта встречается функция gzuncompress, то ее аргументы можно смело распаковывать штатными средствами. А как быть с gzinflate, если у ее аргументов отсутствуют служебные данные? Попробуем просто дописать их и распаковать полученную строку.
  1. format PE GUI 4.0
  2. entry start
  3.  
  4. include 'win32a.inc'
  5.  
  6. section '.data' data readable writeable
  7.  
  8. strr    db 078h,09Ch  ; Заголовок
  9.         db 0F3h,04Dh,0CCh,0F3h,028h,0CDh,02Bh,049h,02Dh,002h,000
  10.         db 0,0,0,0    ; Служебные данные неизвестны, просто заменим их нулями
  11. lend    = $-strr
  12.  
  13. bsize   = 1000
  14.  
  15. blen    dd bsize
  16.  
  17. tmp     rb bsize
  18.  
  19. ;----------------------------------------------------------
  20.  
  21. section '.code' code readable executable
  22. start:
  23.         invoke  uncompress,tmp,blen,strr,dword lend
  24.  
  25.         invoke  MessageBox,HWND_DESKTOP,tmp,NULL,MB_OK
  26.         invoke  ExitProcess,0
  27.  
  28. ;----------------------------------------------------------
  29.  
  30. section '.idata' import data readable writeable
  31.  
  32. library kernel32,"kernel32.dll",\
  33.         user32,"user32.dll",\
  34.         zlib,"zlib1.dll"
  35.  
  36. include "apia\kernel32.inc"
  37. include "apia\user32.inc"
  38.  
  39.   import zlib,\
  40.          uncompress,'uncompress'
Компилируем, запускаем, опа! Получаем распакованную исходную строку. Отсюда следует, что для распаковки строки, запакованной gzdeflate, к ней в начало достаточно дописать два байта заголовка 078h и 09Ch, а служебную информацию в конец строки можно записывать любую. После этого строка легко распаковывается функцией uncompress библиотеки zlib. Во всех виденных мной протекторах и зашифрованных скриптах, функции упаковки вызываются с дефолтными параметрами, а значит и распаковываются по описанной выше схеме.

В приложении скрипт на PHP и примеры программ на Ассемблере, использованные в статье. Исходники без комментариев, все параметры вызова функций zlib можно посмотреть на офсайте или в прилагаемой к дистрибутиву документации.

Assembler vs PHP - примеры к статьеAssembler vs PHP - примеры к статье

Assembler.vs.PHP.zip (36,666 bytes)


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

Метки: Assembler, PHP
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
NeshAliNehrin (29.08.2017 в 17:06):
Статья gzuncompress и gzinflate: Assembler vs PHP
ссылка http://www.zlib.net/zlib123-dll.zip недоступна
на 29/08/2017 актуальная ссылка www.winimage.com/zLibDll/zlib123dll.zip
zlib (29.06.2015 в 20:08):
спасибо работает
Redee (08.01.2014 в 01:14):
Интересно!
JokerBaD (16.05.2012 в 05:00):
Спасибо)Интересная статья.
shomeax (13.11.2011 в 07:41):
хех. ну там как бы не просто "служебная информация", а паддинг. если этот код исполнялся бы на уровне ядра, то мог бы иногда падать из-за выхода за границы страницы. а в случае приложения - ок, там сегмент данных ещё приличный сзади =)
Zummenix (10.08.2009 в 16:22):
Обязательно пригодится :)

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

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

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