Blog. Just Blog

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

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
AppToService от Basta Computing - полезная программа, позволяющая запускать любые приложения как сервисы Windows. Но, как и большинство полезных программ, требует денег после испытательного срока. Будем это исправлять. Скачать пациента можно с офсайта, последняя версия на сегодняшний день 3.0. После установки запускаем программу, видим список параметров запуска и нехорошую строчку, предупреждающую, что надо бы заплатить.

Скриншот программы AppToService
Скриншот программы AppToService

Если посмотреть повнимательнее, то там же будет ключ командной строки для регистрации:

/Key:x Unlock AppToService.
Программа написана на C++ и ничем не упакована. Сперва попробуем найти строчку с ключом "Key:" и посмотреть как она обрабатывается. Строка в юникоде, поэтому символы разделены нулевым байтом. Участок кода, где идет обращение к этой строке, будет только один.
  1. .text:00403074                 mov     edx, offset aKey ; "Key:"
  2. .text:00403079                 call    sub_402BE0
  3. .text:0040307E                 add     esp, 4
  4. .text:00403081                 test    eax, eax
  5. ; Если параметр в командной строке не равен "Key:", то перейти дальше
  6. .text:00403083                 jz      short loc_4030E7
  7. .text:00403085                 or      dword ptr [esp+10h], 2
  8. .text:0040308A                 call    sub_40A54B
  9. .text:0040308F                 mov     eax, [eax+4]
  10. .text:00403092                 lea     ecx, [esp+46h]
  11. .text:00403096                 push    ecx
  12. .text:00403097                 add     eax, 0A4h
  13. .text:0040309C                 push    eax
  14. ; Вот это интересная функция, похоже тут проверяется валидность ключа, и
  15. ; в зависимости от результатов выполняется прыжок на выход или сообщение об
  16. ; успешной регистрации программы
  17. .text:0040309D                 call    sub_4017B0
  18. .text:004030A2                 test    eax, eax
  19. .text:004030A4                 jz      loc_403B0D
  20. .text:004030AA                 call    sub_40A54B
  21. .text:004030AF                 mov     eax, [eax+4]
  22. ; Установить флажок зарегистрированности
  23. .text:004030B2                 mov     dword ptr [eax+0C0h], 1
  24. .text:004030BC                 call    sub_40A54B
  25. .text:004030C1                 mov     eax, [eax+4]
  26. .text:004030C4                 lea     ecx, [eax+0CCh]
  27. .text:004030CA                 call    sub_402590
  28. ; Вывести на экран сообщение об удачной регистрации
  29. .text:004030CF                 push    offset aOk      ; "OK\n"
  30. .text:004030D4                 mov     dword_4402AC, ebx
  31. .text:004030DA                 call    sub_413BCB
  32. .text:004030DF                 add     esp, 4
  33. ; И потом пойти куда-то дальше, это нам уже не очень интересно
  34. .text:004030E2                 jmp     loc_403A95
Посмотрим функцию проверки валидности ключа поподробнее. Кроме всего прочего в ней обнаруживается такой вот интересный кусочек кода:
  1. .text:004019CD                 sar     eax, 1
  2. .text:004019CF                 lea     ecx, [eax+eax+2]
  3. .text:004019D3                 push    ecx             ; cbData
  4. .text:004019D4                 push    edi             ; lpData
  5. .text:004019D5                 push    1               ; dwType
  6. .text:004019D7                 push    0               ; Reserved
  7. .text:004019D9                 push    offset aReserved2 ; "Reserved2"
  8. .text:004019DE                 push    esi             ; hKey
  9. .text:004019DF                 call    ds:RegSetValueExW
  10. .text:004019E5                 push    esi             ; hKey
  11. .text:004019E6                 mov     edi, eax
  12. .text:004019E8                 call    ds:RegCloseKey
  13. .text:004019EE                 push    edi             ; dwErrCode
  14. .text:004019EF                 call    ds:SetLastError
То есть устанавливается ключ в реестре, в который записываются данные регистрации. Под отладчиком можно убедиться, что это так и есть, причем запишется только правильный серийный номер. Что ж, раз ключ записывается, значит он должен где-то потом читаться. Находим еще один код, в котором идет обращение к ключу "Reserved2".
  1. .text:004013AE                 xor     eax, esp
  2. .text:004013B0                 push    eax
  3. .text:004013B1                 lea     eax, [esp+54h+var_C]
  4. .text:004013B5                 mov     large fs:0, eax
  5. .text:004013BB                 mov     eax, offset aReserved2 ; "Reserved2"
  6. .text:004013C0                 lea     esi, [esp+54h+var_48]
  7. .text:004013C4                 mov     ecx, edi
  8. ; Где-то тут читается значение ключа из реестра
  9. .text:004013C6                 call    sub_401000
  10. .text:004013CB                 xor     ebx, ebx
  11. .text:004013CD                 mov     [esp+54h+var_4], ebx
  12. .text:004013D1                 call    loc_401160
  13. .text:004013D6                 lea     eax, [esp+54h+Data]
  14. .text:004013DA                 push    eax
  15. .text:004013DB                 mov     eax, [esp+58h+var_48]
  16. .text:004013DF                 mov     dword ptr [esp+58h+Data], ebx
  17. ; Тут вызывается проверка валидности ключа
  18. .text:004013E3                 call    sub_4074F0
  19. .text:004013E8                 add     esp, 4
  20. .text:004013EB                 test    eax, eax
  21. ; Если проверка не пройдена, то переход
  22. .text:004013ED                 jz      short loc_4013FA
  23. ; Тут какая-то дополнительная проверка данных из ключа
  24. .text:004013EF                 xor     eax, eax
  25. .text:004013F1                 cmp     dword ptr [esp+54h+Data], ebx
  26. ; Регистр AL устанавливается в зависимости от результатов проверки.
  27. ; 0 - все плохо, 1 - программа зарегистрирована
  28. .text:004013F5                 setnl   al
  29. .text:004013F8                 jmp     short loc_4013FC
  30. .text:004013FA loc_4013FA:
  31. ; Сюда мы попадаем, если ключ регистрации не найден или он неправильный
  32. .text:004013FA                 xor     eax, eax
  33. .text:004013FC loc_4013FC:
  34. .text:004013FC                 cmp     eax, ebx
  35. ; Сохранить куда-то в память флажок "зарегистрировано"
  36. .text:004013FE                 mov     [edi+1Ch], eax
  37. ; Переход, если программа не зарегистрирована
  38. .text:00401401                 jz      short loc_401424
  39. .text:00401403                 mov     [esp+54h+var_4], 0FFFFFFFFh
  40. .text:0040140B                 mov     eax, [esp+54h+var_48]
  41. .text:0040140F                 add     eax, 0FFFFFFF0h
  42. .text:00401412                 lea     ecx, [eax+0Ch]
  43. .text:00401415                 or      edx, 0FFFFFFFFh
  44. .text:00401418                 lock xadd [ecx], edx
  45. .text:0040141C                 dec     edx
  46. .text:0040141D                 test    edx, edx
  47. .text:0040141F                 jmp     loc_401589
  48. .text:00401424 loc_401424:
  49. ; Программа не зарегистрирована, вычисляется триальный срок и записывается 
  50. ; в другой ключ реестра - "Reserved0"
  51. .text:00401424                 push    ebx             ; Time
  52. .text:00401425                 call    __time64
  53. .text:0040142A                 add     esp, 4
  54. .text:0040142D                 push    ebx             ; dwDisposition
  55. .text:0040142E                 mov     ebx, edi
  56. .text:00401430                 mov     [esp+58h+var_3C], eax
  57. .text:00401434                 mov     [esp+58h+var_38], edx
  58. .text:00401438                 call    sub_406700
  59. .text:0040143D                 mov     esi, eax
  60. .text:0040143F                 test    esi, esi
  61. .text:00401441                 jz      short loc_40147A
  62. .text:00401443                 push    0               ; lpcbData
  63. .text:00401445                 push    0               ; lpData
  64. .text:00401447                 push    0               ; lpType
  65. .text:00401449                 push    0               ; lpReserved
  66. .text:0040144B                 push    offset aReserved0 ; "Reserved0"
  67. .text:00401450                 push    esi             ; hKey
  68. .text:00401451                 call    ds:RegQueryValueExW
  69. .text:00401457                 push    esi             ; hKey
  70. .text:00401458                 mov     ebx, eax
  71. .text:0040145A                 call    ds:RegCloseKey
  72. .text:00401460                 push    ebx             ; dwErrCode
Алгоритм проверки теперь понятен. Заодно выяснили ключ, в котором хранится триальный срок. Если его периодически стирать из реестра, то программа будет работать свои 30 дней вечно. Но мы пойдем другим путем, мы просто пропатчим саму проверку. Удобнее всего патч сделать на этом участке кода:
  1. .text:004013EB                 test    eax, eax
  2. ; Заменить JZ на JMP, теперь переход будет выполняться в любом случае
  3. .text:004013ED                 jz      short loc_4013FA ; <-- JMP
  4. .text:004013EF                 xor     eax, eax
  5. .text:004013F1                 cmp     dword ptr [esp+54h+Data], ebx
  6. .text:004013F5                 setnl   al
  7. .text:004013F8                 jmp     short loc_4013FC
  8. .text:004013FA loc_4013FA:
  9. ; Сюда будет выполняться переход после патча. В регистре EAX должно быть
  10. ; ненулевое значение, тогда программа будет считать, что она зарегистрирована.
  11. ; Размер команды XOR EAX,EAX равен 2 байта, проще всего заменить ее на MOV AL,1
  12. .text:004013FA                 xor     eax, eax   ; <-- MOV AL,1
Вносим изменения в файл, проверяем. Нехорошая надпись пропала. Для чистоты эксперимента переводим часы на год вперед - все работает как надо.

Программа успешно "зарегистрирована"
Программа успешно "зарегистрирована"

Очередной гвоздь в гроб капитализма забит, теперь программа будет работать без всяких ограничений по времени. А на сэкономленные деньги покупаем букет любимой девушке :)

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

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

Комментарии

Отзывы посетителей сайта о статье
DT (24.08.2011 в 19:51):
СПС! Решение воркает и по сей день :)
ManHunter (04.09.2009 в 12:30):
Это просто для примера
Kemper (04.09.2009 в 10:55):
бесплатные аналоги предлагать? ) - или это просто для примера ?
sasha (05.06.2009 в 21:41):
молоток!))
Шурик (20.03.2009 в 23:52):
i like it
ManHunter (10.03.2009 в 17:51):
Распространение патчей попадает под действие ст.273 УК РФ, так что никаких готовых патчей на этом сайте не будет. Кто хочет - сам сделает, под свою ответственность.
ratatui (10.03.2009 в 17:39):
а мона патчег? :)

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

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

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