Blog. Just Blog

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

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

FinalRecovery от MeetSoft - хорошая программа для восстановления удаленных файлов. Авторы старательно борются со всеми появляющимися варезными решениями, изменяя алгоритмы генерации серийных номеров. Новые кейгены быстро перестают работать, поэтому я расскажу как подбирать серийники к программе фишингом. Кроме того, в FinalRecovery используется интересная система проверки регистрации, на которой могут срезаться начинающие крякеры. Для исследования потребуется дистрибутив FinalRecovery и отладчик. Устанавливаем программу, смотрим. Исполняемый файл упакован UPX, он распаковывается самим же UPX с ключом "-d", тут никаких сюрпризов нет.

Запускаем распакованную программу под отладчиком, пробуем зарегистрировать какими-нибудь левыми данными. Получаем сообщение "Invalid license code", поищем эту строчку в файле.

Строка найдена
Строка найдена

Теперь посмотрим в пошаговом режиме под отладчиком код, который ссылается на "нехорошую" строчку. Он небольшой и достаточно понятный.
  1. CODE:004A6274                 push    ebp
  2. CODE:004A6275                 mov     ebp, esp
  3. CODE:004A6277                 mov     ecx, 6
  4. CODE:004A627C loc_4A627C:
  5. CODE:004A627C                 push    0
  6. CODE:004A627E                 push    0
  7. CODE:004A6280                 dec     ecx
  8. CODE:004A6281                 jnz     short loc_4A627C
  9. CODE:004A6283                 push    ebx
  10. CODE:004A6284                 push    esi
  11. CODE:004A6285                 mov     ebx, eax
  12. CODE:004A6287                 xor     eax, eax
  13. CODE:004A6289                 push    ebp
  14. CODE:004A628A                 push    offset unk_4A64A7
  15. CODE:004A628F                 push    dword ptr fs:[eax]
  16. CODE:004A6292                 mov     fs:[eax], esp
  17. CODE:004A6295                 lea     edx, [ebp+var_C]
  18. CODE:004A6298                 mov     eax, [ebx+2D8h]
  19. CODE:004A629E                 call    sub_42FCA8
  20. CODE:004A62A3                 mov     eax, [ebp+var_C]
  21. CODE:004A62A6                 lea     edx, [ebp+var_4]
  22. CODE:004A62A9                 call    sub_4085A8
  23. ; Непонятная пауза. С понтом имитация напряженых вычислений :)
  24. CODE:004A62AE                 push    32h             ; dwMilliseconds
  25. CODE:004A62B0                 call    Sleep
  26. CODE:004A62B5                 mov     eax, [ebp+var_4]
  27. CODE:004A62B8                 call    sub_403DB8
  28. CODE:004A62BD                 cmp     eax, 6
  29. ; Проверка длины регистрационного имени, должно быть не менее 6 символов,
  30. ; иначе вывести сообщение об ошибке
  31. CODE:004A62C0                 jge     short loc_4A62DC
  32. CODE:004A62C2                 push    0
  33. CODE:004A62C4                 mov     cx, word_4A64B4
  34. CODE:004A62CB                 mov     dl, 1
  35.                                       ; "Invalid license code."
  36. CODE:004A62CD                 mov     eax, offset aInvalidLicense
  37. CODE:004A62D2                 call    sub_4569F8
  38. CODE:004A62D7                 jmp     loc_4A644A
  39. CODE:004A62DC ; -----------------------------------------------------
  40. CODE:004A62DC loc_4A62DC:
  41. CODE:004A62DC                 lea     eax, [ebp+var_4]
  42. CODE:004A62DF                 push    eax
  43. CODE:004A62E0                 mov     eax, [ebp+var_4]
  44. CODE:004A62E3                 call    sub_403DB8
  45. CODE:004A62E8                 mov     ecx, eax
  46. CODE:004A62EA                 sar     ecx, 1
  47. CODE:004A62EC                 jns     short loc_4A62F1
  48. CODE:004A62EE                 adc     ecx, 0
  49. CODE:004A62F1 loc_4A62F1:
  50. CODE:004A62F1                 mov     edx, 1
  51. CODE:004A62F6                 mov     eax, [ebp+var_4]
  52. CODE:004A62F9                 call    sub_403FC0
  53. ; Опять какая-то непонятная пауза. Хороший понт дороже денег :)
  54. CODE:004A62FE                 push    32h             ; dwMilliseconds
  55. CODE:004A6300                 call    Sleep
  56. CODE:004A6305                 lea     ecx, [ebp+var_8]
  57. CODE:004A6308                 mov     edx, offset unk_4A64E0
  58. CODE:004A630D                 mov     eax, [ebp+var_4]
  59. CODE:004A6310                 call    sub_4753D8
  60. CODE:004A6315                 lea     ecx, [ebp+var_10]
  61. CODE:004A6318                 mov     edx, [ebp+var_8]
  62. CODE:004A631B                 mov     eax, [ebp+var_4]
  63. CODE:004A631E                 call    sub_4753D8
  64. CODE:004A6323                 mov     edx, [ebp+var_10]
  65. CODE:004A6326                 lea     eax, [ebp+var_8]
  66. CODE:004A6329                 call    sub_403BD0
  67. ; И еще немного имитируем напряженные вычисления...
  68. CODE:004A632E                 push    32h             ; dwMilliseconds
  69. CODE:004A6330                 call    Sleep
  70. CODE:004A6335                 lea     edx, [ebp+var_18]
  71. CODE:004A6338                 mov     eax, [ebx+2E0h]
  72. CODE:004A633E                 call    sub_42FCA8
  73. CODE:004A6343                 mov     eax, [ebp+var_18]
  74. CODE:004A6346                 lea     edx, [ebp+var_14]
  75. CODE:004A6349                 call    sub_4085A8
  76. ; В регистре EAX указатель на вычисленный серийник, в регистре EDX
  77. ; наши введенные "левые" данные. Далее выполняется проверка их совпадения
  78. CODE:004A634E                 mov     edx, [ebp+var_14]
  79. CODE:004A6351                 mov     eax, [ebp+var_8]
  80. CODE:004A6354                 call    sub_4040A4
  81. CODE:004A6359                 dec     eax
  82. CODE:004A635A                 jnz     loc_4A6435
  83. ; Проверка успешно пройдена, записать в реестр регистрационные данные
  84. CODE:004A6360                 mov     dl, 1
  85. CODE:004A6362                 mov     eax, off_44FFC0
  86. CODE:004A6367                 call    sub_4500C0
  87. CODE:004A636C                 mov     esi, eax
  88. CODE:004A636E                 mov     edx, 80000002h
  89. CODE:004A6373                 mov     eax, esi
  90. CODE:004A6375                 call    sub_450160
  91. CODE:004A637A                 mov     cl, 1
  92.                               .......
Из алгоритма видно, что берется половина регистрационного имени, над ним выполняются какие-то действия и в результате получается 16-символьный код, который и сравнивается с введенным серийным номером.

Проверка серийного номера
Проверка серийного номера

Сохраним его и попробуем зарегистрировать программу с тем же именем, но с уже пойманным серийником. Ура! Программа сообщает, что успешно зарегистрирована, триальная надпись в заголовке пропадает, окно About показывает ваше имя. Вроде бы все хорошо и можно выкладывать релиз, но вот тут и начинается самое интересное. Попробуем восстановить какой-нибудь удаленный файл нашей свежезарегистрированной программой, например в режиме "Standard Recovery". Что мы видим в логе?

Программа не зарегистрирована и работает с ограничениями
Программа не зарегистрирована и работает с ограничениями

Значит где-то выполняется дополнительная проверка регистрационных данных. Попробуем найти вторую "нехорошую" строчку.

Строка найдена
Строка найдена

Смотрим ссылающийся код и условия появления сообщения об ограничении функционала незарегистрированной версии.
  1.                               .......
  2. CODE:00479517                 mov     eax, [ebp+var_8]
  3. CODE:0047951A                 mov     [ebp+var_14], eax
  4. ; Проверка, если вообще никаких регистрационных данных не вводилось
  5. CODE:0047951D                 cmp     ds:byte_4B49E0, 0
  6. CODE:00479524                 jz      short loc_479533
  7. ; Вот она, вторая проверка. Сраваниваются две строки. В регистре EAX строка
  8. ; из серийного номера, в регистре EDX - вычисленное значение
  9. CODE:00479526                 mov     eax, [ebp+var_74]
  10. CODE:00479529                 mov     edx, [ebp+var_78]
  11. CODE:0047952C                 call    sub_403EC8
  12. ; В случае совпадения файл восстанавливается в обычном режиме
  13. CODE:00479531                 jz      short loc_47956F
  14. CODE:00479533 loc_479533:
  15. CODE:00479533                 mov     eax, [ebp+var_14]
  16. ; Размер файла меньше 64 килобайт? Если да, то восстановить в любом случае
  17. CODE:00479536                 cmp     dword ptr [eax+1Ch], 0FA00h
  18. CODE:0047953D                 jle     short loc_47956F
  19. CODE:0047953F                 lea     eax, [ebp+var_EC]
  20. ; Иначе вывести "нехорошую" надпись
  21. ; ": Unregistered version can recover file"...
  22. CODE:00479545                 mov     ecx, offset aUnregisteredVe
  23. CODE:0047954A                 mov     edx, [ebp+var_C]
  24. CODE:0047954D                 call    sub_403E04
  25. CODE:00479552                 mov     edx, [ebp+var_EC]
  26. CODE:00479558                 mov     cl, 2
  27. CODE:0047955A                 mov     eax, [ebp+arg_0]
  28.                               .......
Таких участков кода в программе всего три, расставим под отладчиком точки останова на все три вызова функции сравнения. Пробуем снова восстановить файл, отладчик остановится на втором вхождении:

Дополнительная проверка серийника
Дополнительная проверка серийника

Кажется странно, потому что фактически вторая строка серийника сравнивается с первой, а такого быть не может. Значит это только часть серийного номера. Попробуем дописать вторую строчку к уже найденному серийному номеру и повторить все проверки. Первая проверка при вводе регистрационного имени и уже 32-символьного серийника проходится успешно. Во второй проверке при восстановлении файла в регистре EAX уже будет правильное значение, значит все сделано правильно. Пойманный серийный номер "2FA02A1773CC30C097AD622D9893F5FA".

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

Вот и очередная рыбалка закончилась успешно, больше не придется ждать посторонних кряков в случае выхода новой версии с новой регистрацией.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (26.07.2013 в 18:52):
Статьи по восстановлению информации должны писать люди, которые в этом профессионально разбираются. Иначе будет только вред и абсолютное зло.
Rice (26.07.2013 в 18:51):
Вам и так-то цены нет, но кабы вы создали тему, посвящённую восстановлению информации с флешек и карт памяти.
Versus (29.07.2010 в 10:26):
С новыми версиями не проходит (
bodrox (08.04.2009 в 18:57):
ManHunter, молодец! Давно ждал хорошего ресурса, на котором можно посмотреть такие туториалы.
ManHunter (08.04.2009 в 08:44):
Твои б слова, да Богу в уши...
SAY (08.04.2009 в 08:15):
ManHunter, спасибо за статью. Все не перестаете удивлять меня своими обзорами защиты. Из Ваших уроков извлек главное для себя: не надо ставить защиту, надо сделать так, чтобы люди захотели тебя отблагодарить за труд. Еще раз спасибо.

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

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

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