Blog. Just Blog

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

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

Ahnenblatt - программа для ведения генеалогического дерева с очень простым интерфейсом, но при этом с очень богатыми возможностями. Одинаково хорошо подходит как для начинающих, так и для опытных специалистов. Без регистрации имеются ограничения по функционалу, а за лицензию требуется отдать почти 40 евро. Лично я бы предпочел найти деньгам более полезное применение.

Забираем с офсайта дистрибутив, устанавливаем, смотрим, что и как. Главный исполняемый файл ничем не упакован, отправляем его в дизассемблер. Файл большой, придется подождать, пока будет произведен его полный анализ. Пока попробуем зарегистрировать программу какими-нибудь левыми данными и посмотрим, как она на это отреагирует.

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

Хех, в форме регистрации программа любезно подсказывает нам формат серийника, который надо ввести. Вот она немецкая педантичность. У нас есть строка сообщения, но программа многоязычная, так что надо определить, каким образом эта строка загружается. Долго искать не пришлось, в файле English.lng обнаруживается следующая конструкция.

Строки в языковом файле
Строки в языковом файле

По своей внутренней структуре языковые файлы соответствуют формату ini-файлов, строки загружаются по фиксированным индексам. Значит надо искать в исполняемом файле индексы этих строк и код, который с ними работает. Начнем с InputIncorrect, который соответствует строке о неправильной регистрации. К этому времени дизассемблер как раз должен закончить работу. Найденный код достаточно длинный, я его немного сокращу для удобства понимания.
  1. .text:0053903B                 inc     [ebp+var_214]
  2. .text:00539041                 mov     ecx, [ebp+var_234]
  3. .text:00539047                 mov     eax, [ecx+368h]
  4. .text:0053904D                 call    sub_C58104
  5. .text:00539052                 lea     eax, [ebp+var_154]
  6. .text:00539058                 pop     edx
  7. ; Вызвать функцию сравнения
  8. .text:00539059                 call    sub_D96568
  9. .text:0053905E                 test    al, al
  10. .text:00539060                 jz      loc_5390FB
  11. .text:00539066                 lea     eax, [ebp+var_160]
  12. .text:0053906C                 call    unknown_libname_153
  13. .text:00539071                 mov     edx, eax
  14. .text:00539073                 inc     [ebp+var_214]
  15. .text:00539079                 mov     ecx, [ebp+var_234]
  16. .text:0053907F                 mov     eax, [ecx+38Ch]
  17. .text:00539085                 call    sub_C58104
  18. .text:0053908A                 lea     edx, [ebp+var_160]
  19. .text:00539090                 lea     eax, [ebp+var_15C]
  20. .text:00539096                 push    edx
  21. .text:00539097                 call    unknown_libname_153
  22. .text:0053909C                 mov     edx, eax
  23. .text:0053909E                 inc     [ebp+var_214]
  24. .text:005390A4                 mov     ecx, [ebp+var_234]
  25. .text:005390AA                 mov     eax, [ecx+384h]
  26. .text:005390B0                 call    sub_C58104
  27. .text:005390B5                 lea     eax, [ebp+var_15C]
  28. .text:005390BB                 pop     edx
  29. ; Вызвать функцию сравнения
  30. .text:005390BC                 call    sub_D96568
  31. .text:005390C1                 test    al, al
  32. .text:005390C3                 lea     eax, [ebp+var_15C] ; block
  33. .text:005390C9                 setnz   cl
  34. .text:005390CC                 and     ecx, 1
  35. .text:005390CF                 mov     edx, 2
  36. .text:005390D4                 push    ecx
  37. .text:005390D5                 dec     [ebp+var_214]
  38. .text:005390DB                 call    sub_D96484
  39. .text:005390E0                 dec     [ebp+var_214]
  40. .text:005390E6                 lea     eax, [ebp+var_160] ; block
  41. .text:005390EC                 mov     edx, 2
  42. .text:005390F1                 call    sub_D96484
  43. .text:005390F6                 pop     ecx
  44. .text:005390F7                 test    ecx, ecx
  45. .text:005390F9                 jnz     short loc_5390FF
  46. .text:005390FB loc_5390FB:
  47. .text:005390FB                 xor     eax, eax
  48. .text:005390FD                 jmp     short loc_539104
  49. .text:005390FF ; ---------------------------------------
  50. .text:005390FF loc_5390FF:
  51. .text:005390FF                 mov     eax, 1
  52. .text:00539104 loc_539104:
  53. .text:00539104                 push    eax
  54. .text:00539105                 dec     [ebp+var_214]
  55. .text:0053910B                 lea     eax, [ebp+var_154] ; block
  56. .text:00539111                 mov     edx, 2
  57. .text:00539116                 call    sub_D96484
  58. .text:0053911B                 dec     [ebp+var_214]
  59. .text:00539121                 lea     eax, [ebp+var_158] ; block
  60. .text:00539127                 mov     edx, 2
  61. .text:0053912C                 call    sub_D96484
  62. .text:00539131                 pop     ecx
  63. .text:00539132                 test    ecx, ecx
  64. .text:00539134                 jnz     short loc_53913A
  65. .text:00539136                 xor     eax, eax
  66. .text:00539138                 jmp     short loc_53913F
  67. .text:0053913A ; ---------------------------------------
  68. .text:0053913A loc_53913A:
  69. .text:0053913A                 mov     eax, 1
  70. .text:0053913F loc_53913F:
  71. .text:0053913F                 push    eax
  72. .text:00539140                 dec     [ebp+var_214]
  73. .text:00539146                 lea     eax, [ebp+var_14C] ; block
  74. .text:0053914C                 mov     edx, 2
  75. .text:00539151                 call    sub_D96484
  76. .text:00539156                 pop     ecx
  77. .text:00539157                 test    cl, cl
  78. .text:00539159                 jz      short loc_53915D
  79. .text:0053915B                 xor     ebx, ebx
  80. .text:0053915D loc_53915D:
  81. .text:0053915D                 test    bl, bl
  82. .text:0053915F                 jz      loc_5399D6
  83. .text:00539165                 call    sub_422F30
  84. .text:0053916A                 test    al, al
  85. .text:0053916C                 jz      loc_5394E9
  86. ...
  87. ...
  88. ...
  89. .text:005399D6 ; -------------------------------------------------
  90. .text:005399D6 loc_5399D6:
  91. .text:005399D6                 push    30h             ; uType
  92. .text:005399D8                 mov     edx, offset aInputincorrect
  93. ; "InputIncorrect"
  94. .text:005399DD                 mov     [ebp+var_220], 198h
  95. .text:005399E6                 lea     eax, [ebp+var_1F4]
  96. .text:005399EC                 call    @System@AnsiString@$bctr$qqrpxc
  97. ; System::AnsiString::AnsiString(char *)
Итак, что тут происходит. Если раскручивать код с конца, то выясняется, что все завязано на результатах двух функций проверки, они отмечены в коде комментариями. В свою очередь, если посмотреть эти функции, то там будет ни что иное, как самое обычное сравнение двух юникодных строк. Их результаты сохраняются и используются в нескольких сравнениях далее по коду. Отправляем программу в отладчик и поставим точку останова на начало всей этой большой функции обработки нажатия на кнопку, то есть по адресу 00537BA0. Это необходимо, чтобы выяснить все производимые тут сравнения. Отпускаем программу на выполнение, повторяем регистрацию с левыми данными, после срабатывания точки останова надо поставить дополнительную точку останова на начало функции сравнения. Когда она сработает в первый же раз, в пошаговом режиме смотрим что и с чем сравнивается.

Сравнение строк
Сравнение строк

Это ни что иное, как строка введенного левого серийника, из которой удалены символы-разделители, и строка "EAD187AF409665050ED17DD6", которая по длине соответствует длине серийника.

Таким образом у нас получается полный блок регистрационных данных. Имя "ManHunter", фамилия "PCL", почта "manhunter@pcl.pcl" и серийник "EAD187-AF4096-65050E-D17DD6". Закрываем отладчик, запускаем программу в обычном режиме и повторяем регистрацию с найденными данными.

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

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

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

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

Комментарии

Отзывы посетителей сайта о статье
Накойхер (19.08.2023 в 23:47):
Спасибо, рега и ключ от ManHunter подошли
ManHunter (02.07.2023 в 13:55):
Так программа еще с 90-х годов, автор один раз регистрацию написал и на этом успокоился, остальное время тратит на совершенствование самого софта. Это всяко лучше, чем когда всякие говноразрабы на каждую версию своих поделий меняют схему лицензирования.
daxx0r (02.07.2023 в 08:23):
Вроде 23 год на дворе, а некоторые до сих пор используют сравнение строк в явном виде)

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

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

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