Blog. Just Blog

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

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

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

Забираем с офсайта дистрибутив, устанавливаем, запускаем. Сразу появляется окно с напоминанием о шароварности и предложением оплатить лицензию.

Окно регистрации
Окно регистрации

Как видим, серийник состоит из двух частей. На ввод левых регистрационных данных программа реагирует следующим сообщением:

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

Исполняемый файл ничем не упакован, отправляем его в дизассемблер. Строка сообщения обнаруживается в ресурсах под индексом 25224 или 6288h, если представить это число в шестнадцатеричной системе счисления.

Строка сообщения в ресурсах
Строка сообщения в ресурсах

Поиском по индексу строки сообщения в дизассемблерном листинге обнаруживается следующий код:
  1. .text:0042E7F2                 mov     dword ptr [ebp+Data], 0
  2. ; Вызывать функцию проверки
  3. .text:0042E7F9                 call    sub_437F90
  4. ; Если EAX=0, то переход на вывод сообщения
  5. .text:0042E7FE                 test    eax, eax
  6. .text:0042E800                 jz      short loc_42E817
  7. ; Если контрольное значение не равно 5, то переход на вывод сообщения
  8. .text:0042E802                 cmp     dword ptr [ebp+Data], 5
  9. .text:0042E806                 jnz     short loc_42E817
  10. .text:0042E808                 push    [ebp+var_2C]
  11. .text:0042E80B                 mov     ecx, edi
  12. .text:0042E80D                 call    sub_42E2B0
  13. .text:0042E812                 jmp     loc_42E8DA
  14. .text:0042E817 ; ---------------------------------------
  15. .text:0042E817 loc_42E817:
  16. .text:0042E817                 push    [ebp+var_2C]
  17. .text:0042E81A                 call    sub_476693
  18. .text:0042E81F                 add     esp, 4
  19. .text:0042E822                 mov     ebx, eax
  20. .text:0042E824                 mov     dword ptr [ebp+Data], ebx
  21. .text:0042E827                 xor     esi, esi
  22. .text:0042E829                 call    sub_4486F6
  23. .text:0042E82E                 mov     ecx, [eax+10h]
  24. .text:0042E831                 test    ecx, ecx
  25. .text:0042E833                 jz      short loc_42E85D
  26. .text:0042E835                 movzx   eax, word ptr [ecx]
  27. .text:0042E838                 mov     edx, 1
  28. .text:0042E83D                 test    ax, ax
  29. .text:0042E840                 jz      short loc_42E85D
  30. .text:0042E842                 mov     ebx, eax
  31. .text:0042E844 loc_42E844:
  32. .text:0042E844                 movzx   eax, bx
  33. .text:0042E847                 lea     ecx, [ecx+2]
  34. .text:0042E84A                 imul    eax, edx
  35. .text:0042E84D                 inc     edx
  36. .text:0042E84E                 add     esi, eax
  37. .text:0042E850                 movzx   eax, word ptr [ecx]
  38. .text:0042E853                 mov     ebx, eax
  39. .text:0042E855                 test    ax, ax
  40. .text:0042E858                 jnz     short loc_42E844
  41. .text:0042E85A                 mov     ebx, dword ptr [ebp+Data]
  42. .text:0042E85D loc_42E85D:
  43. .text:0042E85D                 mov     eax, ebx
  44. .text:0042E85F                 sub     eax, esi
  45. .text:0042E861                 cmp     eax, 64Dh
  46. .text:0042E866                 jz      short loc_42E88D
  47. .text:0042E868                 cmp     eax, 643h
  48. .text:0042E86D                 jz      short loc_42E88D
  49. .text:0042E86F                 cmp     eax, 65Fh
  50. .text:0042E874                 jz      short loc_42E88D
  51. .text:0042E876                 cmp     eax, 5F0h
  52. .text:0042E87B                 jz      short loc_42E88D
  53. ; Вывести сообщение о неправильном серийном номере
  54. .text:0042E87D                 push    0
  55. .text:0042E87F                 push    30h
  56. .text:0042E881                 push    6288h
  57. .text:0042E886                 call    sub_448009
Что тут происходит? Сперва обнуляется некое контрольное значение, после чего вызывается функция проверки регистрационных данных по адресу 00437F90. Затем выполняется проверка ее результата, он должен быть ненулевым, а также дополнительно проверяется контрольное значение. Как нетрудно предположить, оно устанавливается где-то внутри функции проверки.

Отправляем программу в отладчик, ставим точку останова на адрес начала функции проверки, то есть 00437F90. Запускаем программу, повторяем регистрацию. Функция проверки достаточно объемная и разделена на несколько этапов. В пошаговом режиме видим, что серийный номер на проверку передается единой строкой, сперва считается ее длина, она должна быть 16 юникодных символов. Затем проверяется тип каждого символа, они все должны быть цифрами. А вот потом начинается проверка серийника.
  1. .text:00437FC8                 movzx   eax, word ptr [ebx+esi*2-2]
  2. .text:00437FCD                 dec     esi
  3. .text:00437FCE                 push    eax
  4. .text:00437FCF                 call    sub_475506
  5. .text:00437FD4                 add     esp, 4
  6. .text:00437FD7                 test    eax, eax
  7. .text:00437FD9                 jz      loc_438192
  8. .text:00437FDF                 test    esi, esi
  9. .text:00437FE1                 jnz     short loc_437FC8
  10. .text:00437FE3                 movzx   esi, word ptr [ebx+1Eh]
  11. .text:00437FE7                 mov     ecx, 0Ah
  12. .text:00437FEC                 sub     esi, 30h
  13. .text:00437FEF                 mov     eax, esi
  14. .text:00437FF1                 mov     [esp+20h+var_C], esi
  15. .text:00437FF5                 imul    eax, esi
  16. .text:00437FF8                 cdq
  17. .text:00437FF9                 idiv    ecx
  18. .text:00437FFB                 add     edx, 30h
  19. .text:00437FFE                 cmp     [ebx+esi*2], dx
  20. .text:00438002                 jnz     loc_438192
  21. .text:00438008                 lea     eax, [esi+1]
  22. .text:0043800B                 mov     [esp+20h+var_10], 1
  23. .text:00438013                 cmp     eax, 0Fh
  24. .text:00438016                 mov     edx, 0FFFFFFF2h
  25. .text:0043801B                 mov     ecx, edx
  26. .text:0043801D                 cmovl   ecx, [esp+20h+var_10]
  27. .text:00438022                 add     ecx, esi
  28. .text:00438024                 mov     esi, 3
  29. .text:00438029                 movzx   eax, word ptr [ebx+ecx*2]
  30. .text:0043802D                 sub     eax, 30h
  31. .text:00438030                 mov     [edi], eax
  32. .text:00438032                 lea     eax, [ecx+1]
  33. .text:00438035                 cmp     eax, 0Fh
  34. .text:00438038                 mov     edi, 0FFFFFFF4h
  35. .text:0043803D                 cmovl   edx, [esp+20h+var_10]
  36. .text:00438042                 add     edx, ecx
  37. .text:00438044                 mov     ecx, edi
  38. .text:00438046                 lea     eax, [edx+3]
  39. .text:00438049                 cmp     eax, 0Fh
  40. .text:0043804C                 movzx   eax, word ptr [ebx+edx*2]
  41. .text:00438050                 cmovl   ecx, esi
  42. .text:00438053                 sub     eax, 30h
  43. .text:00438056                 mov     [esp+20h+var_4], eax
  44. .text:0043805A                 lea     esi, [ecx+edx]
  45. .text:0043805D                 mov     edx, edi
  46. .text:0043805F                 lea     eax, [esi+3]
  47. .text:00438062                 cmp     eax, 0Fh
  48. .text:00438065                 mov     eax, 3
  49. .text:0043806A                 cmovl   edx, eax
  50. .text:0043806D                 movzx   eax, word ptr [ebx+esi*2]
  51. .text:00438071                 add     edx, esi
  52. .text:00438073                 lea     ecx, [eax+eax*4]
  53. .text:00438076                 movzx   eax, word ptr [ebx+edx*2]
  54. .text:0043807A                 lea     eax, [eax+ecx*2]
  55. .text:0043807D                 lea     ecx, [eax+eax*4]
  56. .text:00438080                 lea     eax, [edx+3]
  57. .text:00438083                 cmp     eax, 0Fh
  58. .text:00438086                 mov     eax, 3
  59. .text:0043808B                 cmovl   edi, eax
  60. .text:0043808E                 add     edi, edx
  61. .text:00438090                 movzx   eax, word ptr [ebx+edi*2]
  62. .text:00438094                 lea     eax, [eax+ecx*2]
  63. .text:00438097                 cmp     eax, 14DBh
  64. .text:0043809C                 jnz     loc_438192
  65. .text:004380A2                 xor     ebp, ebp
  66. .text:004380A4                 mov     eax, 10h
  67. .text:004380A9                 nop     dword ptr [eax+00000000h]
  68. .text:004380B0 loc_4380B0:
  69. .text:004380B0                 movzx   ecx, word ptr [ebx+eax*2-2]
  70. .text:004380B5                 dec     eax
  71. .text:004380B6                 imul    ecx, eax
  72. .text:004380B9                 add     ebp, ecx
  73. .text:004380BB                 test    eax, eax
  74. .text:004380BD                 jnz     short loc_4380B0
  75. .text:004380BF                 mov     edx, [esp+20h+var_C]
  76. .text:004380C3                 or      ecx, 0FFFFFFFFh
  77. .text:004380C6                 mov     esi, 0Eh
  78. .text:004380CB                 lea     eax, [edx+0Eh]
  79. .text:004380CE                 cmp     eax, 0Fh
  80. .text:004380D1                 cmovl   ecx, esi
  81. .text:004380D4                 lea     esi, [ecx+edx]
  82. .text:004380D7                 movzx   ecx, word ptr [ebx+esi*2]
  83. .text:004380DB                 lea     eax, [esi-1]
  84. .text:004380DE                 sar     eax, 1Fh
  85. .text:004380E1                 lea     edx, [esi-1]
  86. .text:004380E4                 and     eax, 0Fh
  87. .text:004380E7                 imul    ecx, esi
  88. .text:004380EA                 add     edx, eax
  89. .text:004380EC                 movzx   edi, word ptr [ebx+edx*2]
  90. .text:004380F0                 mov     eax, edi
  91. .text:004380F2                 imul    eax, edx
  92. .text:004380F5                 add     ecx, eax
  93. .text:004380F7                 mov     eax, 66666667h
  94. .text:004380FC                 sub     ebp, ecx
  95. .text:004380FE                 imul    ebp
  96. .text:00438100                 sar     edx, 2
  97. .text:00438103                 mov     eax, edx
  98. .text:00438105                 shr     eax, 1Fh
  99. .text:00438108                 add     eax, edx
  100. .text:0043810A                 lea     eax, [eax+eax*4]
  101. .text:0043810D                 add     eax, eax
  102. .text:0043810F                 sub     ebp, eax
  103. .text:00438111                 add     ebp, 30h
  104. .text:00438114                 cmp     bp, di
  105. .text:00438117                 jnz     short loc_438188
  106. .text:00438119                 xor     ebp, ebp
  107. .text:0043811B                 mov     [esp+20h+var_C], 2
  108. .text:00438123                 xor     edi, edi
  109. .text:00438125                 mov     [esp+20h+var_8], 1
  110. .text:0043812D                 xor     esi, esi
  111. .text:0043812F                 nop
  112. .text:00438130 loc_438130:
  113. .text:00438130                 movzx   eax, word ptr [ebx+esi*2]
  114. .text:00438134                 push    eax
  115. .text:00438135                 call    sub_475506
  116. .text:0043813A                 add     esp, 4
  117. .text:0043813D                 test    eax, eax
  118. .text:0043813F                 jz      short loc_438163
  119. .text:00438141                 movzx   eax, word ptr [ebx+esi*2]
  120. .text:00438145                 mov     ecx, [esp+edi*4+20h+var_C]
  121. .text:00438149                 sub     eax, 30h
  122. .text:0043814C                 imul    ecx, eax
  123. .text:0043814F                 cmp     ecx, 0Ah
  124. .text:00438152                 lea     eax, [ecx-9]
  125. .text:00438155                 cmovl   eax, ecx
  126. .text:00438158                 add     ebp, eax
  127. .text:0043815A                 xor     eax, eax
  128. .text:0043815C                 test    edi, edi
  129. .text:0043815E                 setz    al
  130. .text:00438161                 mov     edi, eax
  131. .text:00438163 loc_438163:
  132. .text:00438163                 inc     esi
  133. .text:00438164                 cmp     esi, 10h
  134. .text:00438167                 jl      short loc_438130
  135. .text:00438169                 test    ebp, ebp
  136. .text:0043816B                 jz      short loc_438188
  137. .text:0043816D                 mov     eax, ebp
  138. .text:0043816F                 cdq
  139. .text:00438170                 idiv    [esp+20h+var_4]
  140. .text:00438174                 mov     eax, 0
  141. .text:00438179                 test    edx, edx
  142. .text:0043817B                 cmovz   eax, [esp+20h+var_10]
  143. .text:00438180                 pop     esi
  144. .text:00438181                 pop     edi
  145. .text:00438182                 pop     ebp
  146. .text:00438183                 pop     ebx
  147. .text:00438184                 add     esp, 10h
  148. .text:00438187                 retn
  149. .text:00438188 ; ---------------------------------------
  150. .text:00438188 loc_438188:
  151. .text:00438188                 pop     esi
  152. .text:00438189                 pop     edi
  153. .text:0043818A                 pop     ebp
  154. .text:0043818B                 xor     eax, eax
  155. .text:0043818D                 pop     ebx
  156. .text:0043818E                 add     esp, 10h
  157. .text:00438191                 retn
Даже если пройдете это все под отладчиком, полностью объяснить словами алгоритм будет трудно. К счастью, у IDA есть отличный инструмент - плагин Hex-Rays Decompiler, который мгновенно переводит ассемблерный код во вполне читаемый псевдокод. Он достаточно чистый, чтобы его можно было почти в неизменном виде скопировать и сделать на его основе кейген-брутфорсер. Для разнообразия я сделал его на PHP. Код немного облегчен и оптимизирован.
  1. $serial=array();
  2.  
  3. while(true) {
  4.     for($i=0$i<15$i++) {
  5.         $serial[$i]=mt_rand(0,9);
  6.     }
  7.  
  8.     $serial[15]=mt_rand(0,9);
  9.     $serial[$serial[15]]=($serial[15]*$serial[15]%10);
  10.  
  11.     $v9 = -14;
  12.     $v10 = -14;
  13.     if ( $serial[15] + 15 ) { $v10 1; }
  14.  
  15.     $v11 $serial[15] + $v10;
  16.  
  17.     $v3=$serial[$v11];
  18.     if ($v3!=5) { continue; }
  19.  
  20.     $v12 = -12;
  21.     if ( $v11 15 ) { $v9 1; }
  22.     $v13 $v11 $v9;
  23.     $v14 = -12;
  24.     if ( $v13 15 ) { $v14 3; }
  25.  
  26.     $v31 $serial[$v13];
  27.     if ($v31==0) { continue; }
  28.  
  29.     $v15 $v14 $v13;
  30.     $v16 = -12;
  31.     if ( $v15 15 ) { $v16 3; }
  32.  
  33.     $v17 $v15 $v16;
  34.     if ( $v17 15 ) { $v12 3; }
  35.  
  36.     if ((48+$serial[$v17+$v12]) + 10 *
  37.         ((48+$serial[$v17]) + 10*(48+$serial[$v15])) != 5339 ) {
  38.         continue;
  39.     }
  40.  
  41.     $v18 0;
  42.     for($i=0$i<16$i++) {
  43.         $v18 += $i * ($serial[$i]+48);
  44.     }
  45.  
  46.     $v21 = -1;
  47.     if ( $serial[15] + 14 15 ) { $v21 14; }
  48.     $v22 = ((($v21+$serial[15]-1)>>31)&0xF)+$v21+$serial[15]-1;
  49.  
  50.     if ((($v18 - ($v22 * ($serial[$v22]+48) + ($v21 $serial[15]) *
  51.         ($serial[$v21+$serial[15]]+48))) % 10) != $serial[$v22]) {
  52.         continue;
  53.     }
  54.  
  55.     $v23 0;
  56.     $v29 = array(2,1);
  57.     $v24 0;
  58.     $v30 1;
  59.     $v25 0;
  60.     do {
  61.         $v26 = ($serial[$v25] * $v29[$v24]);
  62.         $v27 $v26 9;
  63.         if ( $v26 10 ) { $v27 = ($serial[$v25] * $v29[$v24]); }
  64.         $v23 += $v27;
  65.         $v24 = ($v24 == 0);
  66.         $v25++;
  67.     }  while ( $v25 16 );
  68.  
  69.     if ($v23) {
  70.         if (!($v23 $v31)) {
  71.             break;
  72.         }
  73.     }
  74. }
  75.  
  76. echo join('',$serial)."\n";
Может быть брутфорс и не самое эффективное решение для поиска серийников, но тем не менее, за несколько секунд я получил пачку рабочих регистрационных номеров, которые проходят все проверки. Вот лишь несколько из них: 0345789009199182, 4129955230098165, 9713016361544609, 9173175945237038, 9745123014152192. Закрываем отладчик, запускаем программу в обычном режиме, повторяем регистрацию. На этот раз никаких сообщений не появляется, окно регистрации просто закрывается.

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

Смотрим в окно "О программе", там пропала надпись о незарегистрированности и счетчик оставшихся дней. При старте больше не появляется наг-окно с предложением покупки, в окне регистрации пропали поля для ввода серийника, перевод системного времени на работоспособность программы не влияет. Цель достигнута.

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (07.12.2020 в 16:16):
Плохо искал. Китайский релиз IDA 6.8.150423 на Doskey Lee, Kingsoft Internet Security Software, там все есть. Свой палить не собираюсь, он куплен на организацию.
1 (07.12.2020 в 16:10):
А можно плагин ваш попросить , в рунете нашел но он как то не так работает
user (04.12.2020 в 11:51):
v7.79 (XP/2003) - Не, под XP/SP2 инсталляция обламывается. Фтопку.
Luna ©orporation (03.12.2020 в 20:19):
@user,
тут у них
_https://basta.com/zmover#oldversions
крайняя версия v7.79 (XP/2003)
user (03.12.2020 в 13:23):
Да, это так.
Тем болеее, для программ, которые не требуют "установки"
и могут храниться в обычных архивах.
brute (03.12.2020 в 09:34):
во всех "исследованиях" дело заканчивется поиском ключа, либо патчем, чтобы подходил любой ключ. В итоге, на каждом компе приходится его "вспоминать". Имхо, лучше искать и патчить "бит проверки", чтобы вылечить навсегда. За пример брутфорсера - спасибо!
user (02.12.2020 в 22:09):
Версия 8, рассмотренная в статье, работает только в Vista+.
Удалось найти две версии, запускающиеся в WinXP - это v.5.5 и v.7.1.
Алгоритм генерации серийного номера в них такой же, как в этой статье.

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

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

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