Исследование защиты программы Cassette Converter Plus
Скриншот программы Cassette Converter Plus
Программа Cassette Converter Plus предназначена для записи звука с линейного входа или с микрофона, что, в принципе, позволяет оцифровать старые кассеты, пластинки и что-нибудь в этом роде. У меня не осталось не то что кассет, но даже ни одного устройства, на котором их можно было бы прокрутить, так что интерес к программе будет чисто академический. Тем более, что цена за нее явно завышена.
Начинаем исследование как обычно со скачивания дистрибутива. Устанавливаем, запускаем, смотрим, этот этап ничем не отличается от исследования других программ. Ну и не забываем сразу же отправить главный исполняемый файл в дизассемблер, предварительно убедившись, что он ничем не запакован. Это тоже уже должно войти в привычку при исследовании программ. Сразу после запуска программа предлагает нам зарегистрироваться:
Окно регистрации
Там же получаем текст сообщения о неправильной регистрации. Поищем строчку в исполняемом файле. Найдется юникодная строчка:
Строка сообщения найдена
Когда строка сообщения о неправильной регистрации найдена, в дизассемблере посмотрим условия ее появления.
Code (Assembler) : Убрать нумерацию
- .text:00521DED mov eax, [ebp-28h]
- .text:00521DF0 mov edx, [eax]
- ; Указатель на переменную
- .text:00521DF2 lea ecx, [ebp-0CCh]
- .text:00521DF8 push ecx
- .text:00521DF9 mov ecx, [esi+3Ch]
- .text:00521DFC push ecx
- .text:00521DFD mov ecx, [esi+34h]
- .text:00521E00 push ecx
- .text:00521E01 mov ecx, [ebp-2Ch]
- .text:00521E04 push ecx
- .text:00521E05 mov ecx, [ebp-30h]
- .text:00521E08 push ecx
- .text:00521E09 push eax
- ; Вызвать неявно какую-то функцию
- .text:00521E0A call dword ptr [edx+0A8h]
- .text:00521E10 fnclex
- ; По ее результатам принять решение о переходе
- .text:00521E12 test eax, eax
- .text:00521E14 jge short loc_521E2B
- .text:00521E16 push 0A8h
- .text:00521E1B push offset dword_43153C
- .text:00521E20 mov edx, [ebp-28h]
- .text:00521E23 push edx
- .text:00521E24 push eax
- .text:00521E25 call ds:__vbaHresultCheckObj
- .text:00521E2B loc_521E2B:
- ; Записать в EAX значение переменной, которое передавалось в неявную функцию
- .text:00521E2B mov eax, [ebp-0CCh]
- ; Сохранить его в сухом прохладном месте
- .text:00521E31 mov [ebp-20h], eax
- .text:00521E34 lea ecx, [ebp-30h]
- .text:00521E37 call ds:__vbaFreeStr
- .text:00521E3D lea ecx, [ebp-50h]
- .text:00521E40 call ds:__vbaFreeObj
- ; Восстановить значение из сухого прохладного места
- .text:00521E46 mov eax, [ebp-20h]
- ; Если EAX не равно 0, то переход на сообщение о неправильной регистрации
- .text:00521E49 test eax, eax
- .text:00521E4B jnz loc_522373
- ...
- ; Часть кода пропущена
- ...
- .text:00522373 loc_522373:
- .text:00522373 mov ecx, 80020004h
- .text:00522378 mov [ebp-8Ch], ecx
- .text:0052237E mov eax, 0Ah
- .text:00522383 mov [ebp-94h], eax
- .text:00522389 mov [ebp-7Ch], ecx
- .text:0052238C mov [ebp-84h], eax
- .text:00522392 mov edx, [esi+34h]
- .text:00522395 push edx
- .text:00522396 push offset dword_42CAD4
- .text:0052239B call edi ; __vbaStrCat
- .text:0052239D mov edx, eax
- .text:0052239F lea ecx, [ebp-4Ch]
- .text:005223A2 call ebx ; __vbaStrMove
- .text:005223A4 push eax
- .text:005223A5 mov eax, [esi+3Ch]
- .text:005223A8 push eax
- .text:005223A9 call edi ; __vbaStrCat
- .text:005223AB mov [ebp-6Ch], eax
- .text:005223AE mov dword ptr [ebp-74h], 8
- .text:005223B5 push offset aErrorRegistrat
- ; "Error registration key."
- .text:005223BA mov ecx, [ebp-20h]
- .text:005223BD push ecx
- .text:005223BE call ds:__vbaStrI4
- ...
Когда точка останова сработает, переходим в пошаговый режим трассировки с заходом в процедуры и попадаем сперва на команду JMP, а затем уже на саму функцию проверки:
Code (Assembler) : Убрать нумерацию
- ...
- ; Переход на функцию проверки
- .text:0040E4CE jmp loc_4AD630
- ...
Code (Assembler) : Убрать нумерацию
- ; Функция проверки
- .text:004AD630 push ebp
- .text:004AD631 mov ebp, esp
- .text:004AD633 sub esp, 18h
- .text:004AD636 push offset __vbaExceptHandler
- .text:004AD63B mov eax, large fs:0
- .text:004AD641 push eax
- .text:004AD642 mov large fs:0, esp
- .text:004AD649 mov eax, 0A4h
- .text:004AD64E call __vbaChkstk
- .text:004AD653 push ebx
- .text:004AD654 push esi
- .text:004AD655 push edi
- .text:004AD656 mov [ebp-18h], esp
- .text:004AD659 mov dword ptr [ebp-14h], offset dword_4031B0
- .text:004AD660 mov dword ptr [ebp-10h], 0
- .text:004AD667 mov dword ptr [ebp-0Ch], 0
- .text:004AD66E mov eax, [ebp+8]
- .text:004AD671 mov ecx, [eax]
- .text:004AD673 mov edx, [ebp+8]
- .text:004AD676 push edx
- .text:004AD677 call dword ptr [ecx+4]
- .text:004AD67A mov dword ptr [ebp-4], 1
- .text:004AD681 mov edx, [ebp+0Ch]
- .text:004AD684 lea ecx, [ebp-40h]
- .text:004AD687 call ds:__vbaStrCopy
- .text:004AD68D mov edx, [ebp+10h]
- .text:004AD690 lea ecx, [ebp-3Ch]
- .text:004AD693 call ds:__vbaStrCopy
- .text:004AD699 mov edx, [ebp+14h]
- .text:004AD69C lea ecx, [ebp-44h]
- .text:004AD69F call ds:__vbaStrCopy
- .text:004AD6A5 mov edx, [ebp+18h]
- .text:004AD6A8 lea ecx, [ebp-28h]
- .text:004AD6AB call ds:__vbaStrCopy
- .text:004AD6B1 mov dword ptr [ebp-4], 2
- .text:004AD6B8 push 1
- .text:004AD6BA call ds:__vbaOnError
- .text:004AD6C0 mov dword ptr [ebp-4], 3
- .text:004AD6C7 lea eax, [ebp-4Ch]
- .text:004AD6CA push eax
- .text:004AD6CB mov ecx, [ebp-3Ch]
- .text:004AD6CE push ecx
- .text:004AD6CF mov edx, [ebp+8]
- .text:004AD6D2 mov eax, [edx]
- .text:004AD6D4 mov ecx, [ebp+8]
- .text:004AD6D7 push ecx
- .text:004AD6D8 call dword ptr [eax+0C0h]
- .text:004AD6DE mov edx, [ebp-4Ch]
- .text:004AD6E1 mov [ebp-0C0h], edx
- .text:004AD6E7 mov dword ptr [ebp-4Ch], 0
- .text:004AD6EE mov edx, [ebp-0C0h]
- .text:004AD6F4 lea ecx, [ebp-24h]
- .text:004AD6F7 call ds:__vbaStrMove
- .text:004AD6FD mov dword ptr [ebp-4], 4
- .text:004AD704 mov dword ptr [ebp-74h], offset dword_42D054
- .text:004AD70B mov dword ptr [ebp-7Ch], 8
- .text:004AD712 lea edx, [ebp-7Ch]
- .text:004AD715 lea ecx, [ebp-5Ch]
- .text:004AD718 call ds:__vbaVarDup
- .text:004AD71E push 0
- .text:004AD720 push 0FFFFFFFFh
- .text:004AD722 lea eax, [ebp-5Ch]
- .text:004AD725 push eax
- .text:004AD726 mov ecx, [ebp-24h]
- .text:004AD729 push ecx
- .text:004AD72A lea edx, [ebp-6Ch]
- .text:004AD72D push edx
- .text:004AD72E call ds:rtcSplit
- .text:004AD734 lea edx, [ebp-6Ch]
- .text:004AD737 lea ecx, [ebp-38h]
- .text:004AD73A call ds:__vbaVarMove
- .text:004AD740 lea ecx, [ebp-5Ch]
- .text:004AD743 call ds:__vbaFreeVar
- .text:004AD749 mov dword ptr [ebp-4], 5
- .text:004AD750 lea eax, [ebp-38h]
- .text:004AD753 push eax
- .text:004AD754 call ds:__vbaRefVarAry
- .text:004AD75A mov ecx, [eax]
- .text:004AD75C push ecx
- .text:004AD75D push 1
- .text:004AD75F call ds:__vbaUbound
- .text:004AD765 cmp eax, 5
- ; Какая-то проверка
- .text:004AD768 jz short loc_4AD77D
- ; Вернуть в переменную-приемник значение -2
- .text:004AD76A mov dword ptr [ebp-4], 6
- .text:004AD771 mov dword ptr [ebp-48h], 0FFFFFFFEh
- ; Переход на выход из функции
- .text:004AD778 jmp loc_4AD9BB
- .text:004AD77D ; -----------------------------------
- ; Какие-то следующие проверки
- .text:004AD77D loc_4AD77D:
- .text:004AD77D mov dword ptr [ebp-4], 9
- .text:004AD784 mov dword ptr [ebp-74h], 1
- ...
Code (Assembler) : Убрать нумерацию
- .text:004AD765 cmp eax, 5
- .text:004AD768 nop
- .text:004AD769 nop
- .text:004AD76A mov dword ptr [ebp-4], 6
- .text:004AD771 mov dword ptr [ebp-48h], 0
- .text:004AD778 jmp loc_4AD9BB
Программа успешно "зарегистрирована"
После успешной "регистрации" запускаем наш исправленный вариант и проверяем его на работоспособность. Исчезло окно регистрации при старте, в главном окне программы не показывается сообщений о триальном режиме и ограничении по времени записи, а также убран лимит на количество записываемых треков. Перевод системной даты за 14-дневный триальный период также никак не сказывается на работоспособности программы. Цель достигнута, а мы научились работать с неявными вызовами функций.
Просмотров: 4822 | Комментариев: 4
Метки: исследование защиты
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Евгений
(24.06.2013 в 16:07):
С какой легкостью! Мастер-класс! Очень инересное исследование защиты программы. СПС
brute
(18.06.2013 в 06:59):
как оказалось, анализу прог на VB очень способствует "VB Decompiler Pro v9.2"..
ManHunter
(17.06.2013 в 21:22):
Смотри код снизу вверх. Это единственная функция, которая не относится к стандартным функциям визуального басица, результат которой сохраняется и затем проверяется. Я эти места специально прокомментировал.
brute
(17.06.2013 в 20:27):
как был найден адрес 00521E0A? Функция проверки начинается гораздо раньше, по адресам 00412F1A, 005217E0. Начиная с адреса 005218DD считывается введенный логин..Ида граф не строит, Ctrl+X не работает, алгоритм (что происходит после адреса 005218DD) туманен и очень длинен до вызова сообщения об ошибке.. А тут так просто в два действия.. Как?!
Добавить комментарий
Заполните форму для добавления комментария