Blog. Just Blog

Исследование защиты программы PHP LockIt!

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы PHP LockIt!
Скриншот программы PHP LockIt!

Программа PHP LockIt! предназначена для защиты исходных текстов PHP-скриптов от исследования и модификации. В качестве защиты применяется обфускация имен функций и переменных, а также шифрование исходного кода. В более ранних версиях была еще возможность сжимать полученные скрипты, но разработчики по какой-то причине от этого отказались. Зашифрованные скрипты не требуют установки на сервер дополнительного программного обеспечения, поэтому PHP LockIt! пользуется большой популярностью как у зарубежных, так и у отечественных копирастов. Я давно наблюдаю за развитием этой защиты, и среди других аналогичных поделок она кажется мне наиболее стабильной и надежной. Мне даже довелось встретить китайскую подделку PHP LockIt!, когда интерфейс программы был изменен в редакторе ресурсов, копирайты исправлены на свои, а затем на изуродованный файл был навешан протектор. При этом полученный китайский гибрид позиционировался как авторская разработка и распространялся как самостоятельный продукт с другим названием.

С офсайта PHP LockIt! можно скачать только демо-версию программы для ознакомления, или же раскошелиться на три десятка баксов для покупки ее коммерческого варианта. Поскольку к полной версии у нас доступа нет, попробуем что-нибудь сделать с демо-версией. Скачиваем дистрибутив, устанавливаем, запускаем. Получаем окно с таймером и сообщением сколько дней нам осталось:

Сообщение демо-версии
Сообщение демо-версии

Как пишут сами разработчики программы, ограничение по времени - это единственное различие демонстрационной и полной версии. По истечение отведенного триального срока окно меняется на сообщение, что время вышло, и PHP LockIt! перестает запускаться.

Демонстрационный период закончился
Демонстрационный период закончился

Ну раз других отличий нет, то попробуем убрать ограничение по времени и надоедливые сообщения, превратив тем самым демо-версию в некое подобие коммерческой. Тем более, что в демо-версии не предусмотрено никакой возможности регистрации, а коммерческую версию никто не видел :) Предварительный анализ главного исполняемого файла показывает, что он ничем не упакован, значит просто отдаем его на растерзание дизассемблеру. Параллельно поищем в ресурсах строки или сообщения демонстрационной версии. Найдется два диалога с характерными заголовками:

Триальное окно в ресурсах
Триальное окно в ресурсах

Окно окончания демонстрационного периода
Окно окончания демонстрационного периода

Текстовые строки в них заменены заглушками, так как они подставляются потом, перед выводом окон на экран. Видимо авторы задумывали поддержу многоязычности, но так и не реализовали эту функцию. Мы знаем индекс окна со счетчиком триального периода - это число 133 или 85h в шестнадцатеричной системе счисления. Посмотрим в дизассемблере, где он используется. В сегменте кода найдется только одно вхождение:
  1. .text:0040546A                 push    ebx
  2. .text:0040546B                 push    ebp
  3. .text:0040546C                 push    esi
  4. .text:0040546D                 push    edi
  5. .text:0040546E                 mov     esi, ecx
  6. ; Вызвать функцию открытия диалогового окна CDialog
  7. .text:00405470                 push    eax  ; На стек хэндл владельца 
  8. .text:00405471                 push    85h  ; На стек идентификатор ресурса
  9. .text:00405476                 mov     [esp+28h+var_10], esi
  10. .text:0040547A                 call    ??0CDialog@@QAE@IPAVCWnd@@@Z
  11. ; CDialog::CDialog(uint,CWnd *)
  12. .text:0040547F                 lea     edi, [esi+5Ch]
  13. .text:00405482                 mov     [esp+20h+var_4], 0
  14. .text:0040548A                 mov     ecx, edi
  15. .text:0040548C                 call    sub_4214F4
  16. .text:00405491                 mov     dword ptr [edi], offset off_42CCA4
  17. .text:00405497                 mov     ecx, off_44215C
  18. .text:0040549D                 lea     edi, [esi+98h]
Дизассемблер показывает, что для открытия диалогового окна вызывается функция CDialog, значит если ее вырезать, то окно не появится. У функции CDialog два параметра, то есть предварительно перед вызовом на стек кладутся два числа. Чтобы корректно удалить это открытие диалога, придется забить NOP'ами не только сам вызов функции по адресу 0040547A, но и две команды PUSH по адресам 00405470 и 00405471. Сохраняем изменения, запускаем. Триальное окно при старте пропало. Едем дальше. После окончания демонстрационного периода появляется уже другое сообщение, но просто удалять его по аналогии с триальным окном нельзя, надо полностью отключить ветку алгоритма, которая получает управление после 30 дней пользования программой. Поищем в дизассемблере условие срабатывания. Диалоговое окно с нужным нам сообщением появляется по адресу:
  1. .text:00405790 sub_405790      proc near
  2. .text:00405790
  3. .text:00405790 var_10          = dword ptr -10h
  4. .text:00405790 var_C           = dword ptr -0Ch
  5. .text:00405790 var_4           = dword ptr -4
  6. .text:00405790 arg_0           = dword ptr  4
  7. .text:00405790
  8. .text:00405790                 push    0FFFFFFFFh
  9. .text:00405792                 push    offset SEH_405790
  10. .text:00405797                 mov     eax, large fs:0
  11. .text:0040579D                 push    eax
  12. .text:0040579E                 mov     large fs:0, esp
  13. .text:004057A5                 push    ecx
  14. .text:004057A6                 mov     eax, [esp+10h+arg_0]
  15. .text:004057AA                 push    ebx
  16. .text:004057AB                 push    esi
  17. .text:004057AC                 push    edi
  18. .text:004057AD                 mov     esi, ecx
  19. ; Вызвать функцию открытия диалогового окна CDialog
  20. .text:004057AF                 push    eax  ; На стек хэндл владельца
  21. .text:004057B0                 push    84h  ; На стек идентификатор ресурса
  22. .text:004057B5                 mov     [esp+24h+var_10], esi
  23. .text:004057B9                 call    ??0CDialog@@QAE@IPAVCWnd@@@Z
  24. ; CDialog::CDialog(uint,CWnd *)
  25. .text:004057BE                 mov     ecx, off_44215C
  26. .text:004057C4                 lea     edi, [esi+5Ch]
  27. .text:004057C7                 mov     [esp+1Ch+var_4], 0
  28. ...
Эта процедура в свою очередь вызывается только из одного места:
  1. .text:00409F27                 mov     ecx, dword ptr [esp+0BACh+cbData]
  2. .text:00409F2B                 cmp     ecx, eax
  3. ; Если одно значение больше другого, то триальный срок окончен
  4. .text:00409F2D                 jg      loc_40A0CC
  5. .text:00409F33                 lea     edx, [eax-28DE80h]
  6. .text:00409F39                 cmp     ecx, edx
  7. ; Если одно значение меньше другого, то триальный срок окончен
  8. .text:00409F3B                 jl      loc_40A0CC
  9. .text:00409F41 loc_409F41:
  10. ; Триальная ветка алгоритма
  11. .text:00409F41                 sub     eax, ecx
  12. .text:00409F43                 lea     esi, [edi+0C0h]
  13. .text:00409F49                 mov     ecx, eax
  14. .text:00409F4B                 mov     eax, 0C22E4507h
  15. .text:00409F50                 imul    ecx
  16. .text:00409F52                 add     edx, ecx
  17. .text:00409F54                 mov     ecx, esi
  18. .text:00409F56                 sar     edx, 10h
  19. .text:00409F59                 mov     eax, edx
  20. .text:00409F5B                 shr     eax, 1Fh
  21. ; ............
  22. ; Часть кода пропущена для экономии места
  23. ; ............
  24. .text:0040A0A6                 call    sub_424911
  25. .text:0040A0AB                 mov     byte ptr [esp+0BACh+var_4], 1Ch
  26. .text:0040A0B3                 lea     ecx, [esp+0BACh+var_874]
  27. .text:0040A0BA                 call    sub_401590
  28. .text:0040A0BF                 mov     byte ptr [esp+0BACh+var_4], 1Bh
  29. .text:0040A0C7                 jmp     loc_40A2E0
  30. .text:0040A0CC ; -----------------------------------------------
  31. ; Нужная нам ветка алгоритма, в которой показывается сообщение об
  32. ; окончании триального периода, после чего программа завершает работу
  33. .text:0040A0CC loc_40A0CC:
  34. .text:0040A0CC                 push    esi
  35. .text:0040A0CD                 lea     ecx, [esp+0BB0h+var_B8C]
  36. ; Вызвать функцию открытия диалогового окна
  37. .text:0040A0D1                 call    sub_405790
  38. .text:0040A0D6                 lea     ecx, [esp+0BACh+var_B8C]
  39. .text:0040A0DA                 mov     byte ptr [esp+0BACh+var_4], 4
  40. .text:0040A0E2                 call    sub_420FF7
  41. ...
Получается, что если забить NOP'ами два условных перехода по адресам 00409F2D и 00409F3B, то программа будет всегда считать, что ее демонстрационный период не закончился. Сохраняем изменения, переводим часы на год вперед, запускаем. Все работает как надо, у нас получилась почти что коммерческая версия. Почему почти? Потому что мы не заплатили за нее ни копейки :)

Напоследок попробуем разобраться с ограничением по времени. Запустим первоначальный вариант программу под управлением монитора RegMon или Process Monitor. В любом случае нас интересуют только обращения к реестру. Обращений не так много, в основном это стандартные вызовы. Но в списке присутствует один интересный ключ, к которому фиксируется обращение при старте программы и сразу перед появлением сообщения об истечении триального срока.

[HKEY_LOCAL_MACHINE\SOFTWARE\{A77633C1-E8C8-6A41-12CA-BADFE4FA2760}]
@="0x448ac29f"

Ключ вызывает интерес хотя бы даже потому, что ключей с таким именем в этой ветке реестра быть не должно. Видимо разработчики задумывали спрятать этот ключ где-то в дебрях ветки CLSID, но забыли или не смогли сделать это правильно. Если удалить этот ключ, то триальный срок снова сбрасывается на 30 дней. В принципе, можно обойтись и без вмешательства в исполняемый код, просто периодически удаляя этот ключ из реестра. В этом случае даже демо-версией можно будет пользоваться неограниченное время, если не обращать внимания на надоедливые наг-окна.

Разбирать снятие защиты с самих скриптов я не буду по личным соображениям. При наличии знаний языка PHP и свободного времени вы можете сделать это самостоятельно. Написать автоматический распаковщик для PHP LockIt! также не составит большого труда.

Поделиться ссылкой ВКонтакте
Просмотров: 9952 | Комментариев: 21

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (19.02.2019 в 12:54):
Решение: никому не давать свои скрипты. В остальных случаях все будет зависеть только от заинтересованности заказчика и бюджета вечеринки.
YaBlogo (19.02.2019 в 12:52):
"Написать автоматический распаковщик для PHP LockIt! также не составит большого труда"

Хм, а есть альтернативное решение благодаря котрому можно быть уверенным что не разберут код?
ManHunter (10.04.2013 в 21:26):
Стереть нахер такой ущербный антивирус. Вот и все решение.
Tezarius (10.04.2013 в 19:28):
Раньше найдя вашу статью скачал эту программу и пользовался ей без проблем.
Сейчас перешол на сервера с PHP 5.3  и старая программа уже не подходит (выходит информация об использовании устареших функций)
попробовал скачать новую версию 2.2 но не смог проверить так как после обработки результативный файл почемуто получается с трояном и антивирусник на стадии его создания сразу же уничтожает :(
Версия системы Вин 7 32б была ли у кого такая проблема ? и как ее решили ?
Злой Одиночка (10.12.2011 в 20:21):
Неплохая вещь. Самое то для защиты паблика от кривожопокриворуких редакторов =)
Димас (24.10.2011 в 08:02):
Сори.
как с вами связатся?
очина нада
64-ядерный процессор (04.02.2011 в 13:16):
ManHunter, ок, я офф. Но помни прописную истину: от выбора ОС зависит функциональность компьютера. И если ты полностью осознаёшь это, то я рад за тебя, что ты выбрал хорошую ОС =))
ManHunter (04.02.2011 в 13:03):
Которое слово из написанного мной вызывает сомнение?
64-ядерный процессор (04.02.2011 в 13:01):
AyTkACT, Да, я в своё время тоже через силу отказался от ME, в силу большей совместимости. Да, производительность системы несколько упала на ХР по сравнению с МЕ. Но если сравнивать ХР с вистой и 7, то виста - это постоянно загруженные на 100 процентов 4 ядра, а семёрка - примерно то же самое. Хоть и работает немного быстрее - всё равно далеко от висты не ушла. А по поводу прогресса, то я думаю что виртуальная машина теперь будет моим надёжным спутником так долго, пока не будет выпущена нормальная ОС.
P.S. У большинства моих знакомых при переходи с ХР на 7 постоянно возникали какие-то проблемы с работой железа.
ManHunter (04.02.2011 в 11:36):
Прекращайте холиварить, все уже обсуждено не один раз.
AyTkACT (04.02.2011 в 11:35):
64-ядерный процессор, по части красивилок и ненужностей - согласен, хотя можно допилить и под себя.
По части совместимости - нет, у меня не нашлось ни одного приложения работающего на XP и отказавшегося работать на семёрке.
Люди пересаживаясь с Win Me на Win XP тоже извергали тонны ненависти, но теперь уже никто и помыслить не может о том чтобы пересесть на Me.
За семеркой и восьмёркой будущее, так что бежать от "прогресса" можно, но не далеко и не долго.
Но это уже все оффтоп.
64-ядерный процессор (04.02.2011 в 00:25):
AyTkACT, потому, что 7 не обеспечивает надлежащей совместимости, и потому что на ней некоторые программы, мягко говоря, работают как-то странно. +Её чертовски неудобные меню, в которых, как и в виста, всё ненужное выброшено на видное место, а всё необходимое спрятано чёрт знает куда.
P.S. Ещё нет такой незаменимой программы, которая отказывалась бы работать под ХР.
ManHunter (01.02.2011 в 11:17):
"Кто-то любит попадью, а кто-то свиной хрящик" :)
AyTkACT (01.02.2011 в 00:25):
>>>>>Вот чего нужно бояться, а не кряков.
Кряки наносят урон (материальный) автору говнософта, а "ребрендинг" - ментальный урон.  В нашем мире первое (материальное(читать БАБЛО)) очень волнует авторов говнософта, посему утверждение несостоятельно.

з.ы. XP - хорошая ось, но и 7ка тоже очень даже хороша.
з.з.ы. Vista - это вообще не ось, а #@^та! Не зря мелкомягкие от неё отказались.
з.з.з.ы. 64-ядерный процессор, интересный ник, какбэ намекающий что носитель положительно относится к этой разрядности... Непонятно почему тогда так негативно относится к Windows 7.
64-ядерный процессор (31.01.2011 в 20:57):
jnpe, да я сижу на пиратской хп всего лишь из за того, что все магазины перешли на эту ублюдскую 7! Будь у меня возможность купить лицуху XP SP3 - я бы сделал это не задумываясь.

jnpe, плюс ко всему я имел в виду не то, что её просто крякнут и будут пользоваться на халяву. Да и фиг бы то с ним. Но есть такие ублюдки, которые выдают чужой софт за свой. Вот чего нужно бояться, а не кряков.
jnpe (31.01.2011 в 20:21):
>> 64-ядерный процессор
>>в противном случае твоя программа всегда может стать чьей-то другой... >>Печально.

сам то небось на ломаной винде сидишь? Биллу от этого тоже печально.
64-ядерный процессор (31.01.2011 в 02:57):
Блин всё так просто присваевается. Самое надёжное - это онлайн сервис, в противном случае твоя программа всегда может стать чьей-то другой... Печально.
ManHunter (30.01.2011 в 22:26):
Совершенно справедливое замечание. Правильнее будет также удалить эту команду, хотя на работоспособности это не сказывается.
егорыч (30.01.2011 в 22:20):
ManHunter, спасибо за статьи!
Извини, если глупый вопрос задам. В статье написано, чтобы корректно удалить вызов функции CDialog, надо еще удалить два пуша перед ней. Но сразу после пушей по адресу 00405476 идет вроде бы запись в стек. Если пуши удаляем, то надо изменять и смещение, которое добавляется к esp, и заменять 28h на 20h. Правильно?
ManHunter (30.01.2011 в 08:13):
Совершено верно, только за все время не было ни одного ретайлового релиза. Так что и рад бы, да "бы" мешает :) Хотя в китайской подделке вроде бы использовалась ретайловая версия, но там файл слишком покорежен, чтобы на его основе что-то утверждать.
AyTkACT (30.01.2011 в 06:23):
Как я разумею, единственным вариантом проверки того, что демка и Retail отличаются только счётчиком триала (с соответствующими окнами), является покупка сабжа и разбор кода?

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

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

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