Blog. Just Blog

Исследование защиты программы Ping Manager

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

Ping Manager - это набор сетевых инструментов, основанных на ICMP-запросах, включающий: обычный пинг, сканирование диапазона IP-адресов, трассировку маршрута и ping-тестирование пути. Каждая страница имеет уникальные настройки как для ручного, так и для автоматического режима работы. Никак не могу привыкнуть к тому, что за хорошие программы почему-то требуют денег.

Забираем дистрибутив, устанавливаем, запускаем, смотрим. Главный исполняемый файл ничем не упакован, отправляем его на анализ в дизассемблер. Заодно посмотрим, какие функции там используются.

Триальный текст
Триальный текст

В тексте окна появляется строка о триальном времени, а если установить системное время на несколько месяцев вперед, появится сообщение об окончании пробного периода.
  1. .text:00437378                 mov     [ebp+var_17800], 264h
  2. .text:00437381                 mov     edx, offset aUnregisteredVe
  3. ; " - Unregistered version"
  4. .text:00437386                 lea     eax, [ebp+var_177DC]
  5. .text:0043738C                 call    @System@AnsiString@$bctr$qqrpxc
  6. .text:00437391                 inc     [ebp+var_177F4]
  7. .text:00437397                 lea     edx, [ebp+var_177DC]
Ищем строку по имени "Unregistered", сразу же находим и эту. В листинге дизассемблера выше нее расположено несколько строк с готовыми надписями вроде "(Enterprise License)", "(Site License)" и им подобными. Нас интересует строка, находящаяся непосредственно над ними - "Registered version".
  1. .text:00436CD3                 mov     edx, 2
  2. .text:00436CD8                 call    sub_597D98
  3. .text:00436CDD                 xor     ecx, ecx
  4. ; Строка с байтом проверки
  5. .text:00436CDF                 mov     cl, byte_60C33C
  6. .text:00436CE5                 test    ecx, ecx
  7. .text:00436CE7                 jle     loc_437378
  8. .text:00436CED                 mov     [ebp+var_17800], 168h
  9. .text:00436CF6                 mov     edx, offset aRegisteredVers
  10. ; " - Registered version"
  11. .text:00436CFB                 lea     eax, [ebp+var_17788]
  12. .text:00436D01                 call    @System@AnsiString@$bctr$qqrpxc
  13. .text:00436D06                 inc     [ebp+var_177F4]
  14. .text:00436D0C                 lea     edx, [ebp+var_17788]
  15. .text:00436D12                 lea     eax, [ebp+var_17720]
  16. .text:00436D18                 call    sub_597DDC
  17. .text:00436D1D                 dec     [ebp+var_177F4]
  18. .text:00436D23                 lea     eax, [ebp+var_17788]
  19. .text:00436D29                 mov     edx, 2
  20. .text:00436D2E                 call    sub_597D98
  21. .text:00436D33                 xor     ecx, ecx
  22. .text:00436D35                 mov     cl, byte_60C33C
Нас интересует код, в котором выполняется проверка байта по адресу 00436CDF. Если проверка проходит успешно, то выводится строка "Registered version". В случае ее неудачи, выполнение сразу переходит на отображение строки "Unregistered version". Посмотрим код mov cl, byte_60C33C, а в дизассемблере перекрестные ссылки на эту ячейку памяти.

Перекрестные ссылки на ячейку памяти
Перекрестные ссылки на ячейку памяти

Как видите, в двух местах кода устанавливается значение флага регистрации, и в двух других местах этот флаг инициализируется нужным значением. Все остальное - это проверки и сопутствующие операции.
  1. .text:00407600                 mov     [ebp+var_18], 18h
  2. .text:00407606                 xor     ecx, ecx
  3. .text:00407608                 mov     byte_60C334, 1
  4. .text:0040760F                 mov     dword_60C338, ecx
  5. ; Такой флаг инициализируется
  6. .text:00407615                 mov     byte_60C33C, 0
  7. .text:0040761C                 mov     eax, [ebp+var_4]
  8. .text:0040761F                 mov     byte_60C33E, 0
  9. .text:00407626                 mov     byte_60C33F, 0
  10. .text:0040762D                 mov     byte_60C340, 0
  1. .text:00435BC3                 mov     [ebp+var_17C30], 0
  2. ; Такой флаг инициализируется
  3. .text:00435BCA                 mov     byte_60C33C, 0
  4. .text:00435BD1                 lea     edx, [ebp+var_17C30] ; dest
  5. .text:00435BD7                 lea     eax, [ebp+dest] ; dest
  6. .text:00435BDD                 call    sub_4078AC
  7. .text:00435BE2                 test    al, al
  8. .text:00435BE4                 jz      short loc_435BFD
  9. .text:00435BE6                 mov     [ebp+var_17BF0], 0
  10. .text:00435BED                 lea     eax, [ebp+dest]
  11. .text:00435BF3                 call    loc_407BA4
  12. .text:00435BF8                 mov     byte_60C33C, al
Чтобы обойти проверку и активировать зарегистрированную версию, нужно изменить обе инструкции mov byte_60C33C на запись значения 0 на, например, 1 или 2. После внесения этих двух правок программа должна корректно определить себя как зарегистрированную и отобразить надпись "Registered version" в заголовок окна. Проверяем.

Триальное окно
Триальное окно

При попытке вызвать любую функцию программы появляется сообщение "Evaluation period is over.", и, по сути, все функции программы становятся недоступными, они не работают, несмотря на возможные визуальные элементы интерфейса. Чтобы программа действительно работала, требуется следующий анализ, поиск и модификация реальной проверки срока действия.

Посмотрим на строку "Evaluation period is over.", она, как выясняется, встречается не один раз, а в нескольких экземплярах в коде. Эти вхождения выглядят похоже, но расположены отдельно для разных элементов интерфейса, вкладки или функции программы. То есть, проверка реализована локально в каждом обработчике, а не централизованно. Возьмем, например, вот такой кусок:
  1. .text:0042824C                 inc     [ebp+var_44]
  2. .text:0042824F                 mov     [ebp+var_50], 18h
  3. .text:00428255                 mov     [ebp+var_50], 24h
  4. ; Проверка флага
  5. .text:0042825B                 cmp     byte_60C334, 0
  6. ; Проверка перехода
  7. .text:00428262                 jnz     loc_42888B
  8. .text:00428268                 mov     eax, dword_60B38C
  9. .text:0042826D                 test    eax, eax
  10. ...
  11. ...
  12. ...
  13. .text:0042888B loc_42888B:
  14. .text:0042888B                 lea     eax, [ebp+s]    ; s
  15. .text:0042888E                 call    sub_426C34
  16. .text:00428893                 mov     [ebp+var_50], 24h
  17. .text:00428899                 push    2               ; n
  18. .text:0042889B                 push    0               ; c
  19. .text:0042889D                 lea     edx, [ebp+s]
  20. .text:004288A0                 push    edx             ; s
  21. .text:004288A1                 call    _memset
  22. .text:004288A6                 add     esp, 0Ch
  23. .text:004288A9                 mov     edx, offset aEvaluationPe_3
  24. ; "Evaluation period is over.\r\nPlease regi"...
  25. .text:004288AE                 or      byte ptr [ebp+s], 4
  26. .text:004288B2                 push    0
  27. .text:004288B4                 lea     eax, [ebp+var_3C]
Значение byte_60C334, 1 - это ключевой индикатор окончания пробного периода. Чтобы программа работала, нужно найти все места, где это значение устанавливается, и заблокировать такую установку, заменив 1 на 0 или устранив условие, ведущее к этому. Вместо того чтобы искать и патчить все места, где byte_60C334 может быть установлено в 1, достаточно один раз задать правильное значение при запуске. Надо еще проверить, что после инициализации флаг не переустанавливается другой частью кода.

Перекрестные ссылки на ячейку памяти
Перекрестные ссылки на ячейку памяти

По адресу 00407608 устанавливается байт флага mov byte_60C334,1, причем находится всего на несколько строк выше, в уже знакомом нам участке кода, где он инициализируется.
  1. .text:00407600                 mov     [ebp+var_18], 18h
  2. .text:00407606                 xor     ecx, ecx
  3. ; Такой флаг инициализируется
  4. .text:00407608                 mov     byte_60C334, 1
  5. .text:0040760F                 mov     dword_60C338, ecx
  6. .text:00407615                 mov     byte_60C33C, 0
  7. .text:0040761C                 mov     eax, [ebp+var_4]
  8. .text:0040761F                 mov     byte_60C33E, 0
  9. .text:00407626                 mov     byte_60C33F, 0
  10. .text:0040762D                 mov     byte_60C340, 0
Заменяем mov byte_60C334,1 на mov byte_60C334,0 и сохраняем изменения. Запускаем программу, проверяем ее работу. Патч успешен, все функции работают. Сообщение "Evaluation period is over." больше не появляется, интерфейс откликается, инструменты выполняют свои задачи без ограничений. Цель достигнута.

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (19.09.2025 в 11:47):
Варианты есть всегда, но бывает сложно их толково написать, да и чтобы поняли :)
0101 (19.09.2025 в 10:23):
На сайте программы есть и другие программы поинтереснее, ничем не накрытые и лечатся правкой одного байта.
kaktustv (18.09.2025 в 22:28):
Если изменить вторую инструкцию mov byte_60C33C на запись значения 0 на 28, получим в заголовке "Registered version (Enterprise License)".
Мелочь, конечно, но приятно!

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

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

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