Исследование защиты программы Visual Watermark
Скриншот программы Visual Watermark
Программа Visual Watermark предназначена для нанесения текстовых и графических водяных знаков или подписей на цифровые фотографии. Программа очень проста в использовании, имеет простой и дружественный интерфейс, поддерживает все популярные графические форматы, имеет функцию пакетной обработки изображений. Все это можно сделать совершенно бесплатно в любых графических программах, а можно выложить денежку и сделать в программе Visual Watermark. А можно и не выкладывать ничего, и точно так же сделать в программе Visual Watermark. Последний вариант мне нравится больше.
Скачиваем дистрибутив, устанавливаем, запускаем. Исполняемый файл ничем не упакован, поэтому параллельно открываем его на анализ в дизассемблере. А пока посмотрим, как программа реагирует на неправильную регистрацию:
Сообщение о неправильной регистрации
Нужная строка легко находится в файле:
Строка сообщения найдена
Дальше в дизассемблере по перекрестным ссылкам находим код, где она используется и смотрим условия ее появления:
Code (Assembler) : Убрать нумерацию
- .text:00457360 sub_457360 proc near
- .text:00457360 arg_0 = dword ptr 8
- .text:00457360 push ebp
- .text:00457361 mov ebp, esp
- .text:00457363 mov eax, [ebp+arg_0]
- .text:00457366 inc dword ptr [eax+30Ch]
- .text:0045736C mov edx, [ebp+arg_0]
- .text:0045736F cmp dword ptr [edx+30Ch], 3
- .text:00457376 jge short loc_457394
- .text:00457378 push 10h ; uType
- .text:0045737A push offset aRegistration_1
- ; "Registration"
- .text:0045737F push offset aTheKeyYouEnter
- ; "The key you entered is not valid. Pleas"...
- .text:00457384 mov eax, [ebp+arg_0]
- .text:00457387 call @Controls@TWinControl@GetHandle$qqrv
- .text:0045738C push eax ; hWnd
- .text:0045738D call MessageBoxA
- .text:00457392 pop ebp
- .text:00457393 retn
Code (Assembler) : Убрать нумерацию
- ; Вызвать процедуру проверки
- .text:004572B5 call sub_42920C
- .text:004572BA pop ecx
- ; ПоXORить результат функции с константой 35h
- .text:004572BB xor eax, 35h
- ; Сохранить результат в ячейку памяти
- .text:004572BE mov [ebp+var_44], eax
- .text:004572C1 mov [ebp+var_28], 14h
- ; Сравнить результат с числом 24h
- .text:004572C7 cmp [ebp+var_44], 24h
- ; Если не равно, то показать сообщение о неправильной регистрации
- .text:004572CB jz short loc_4572D8
- .text:004572CD push [ebp+var_3C]
- ; Сообщение о неправильной регистрации
- .text:004572D0 call sub_457360
Code: Убрать нумерацию
- int __cdecl sub_42920C(char a1)
- {
- __InitExceptBlockLDTC();
- System__AnsiString__AnsiString(&a1, &a1);
- v12 = 2;
- v11 = 8;
- v9 = sub_42919C(a1);
- if ( sub_429350(&unk_6D71F8, &unk_6E0E38, &v9) > (unsigned int)&unk_6E0E34
- || (v8 = sub_42919C(a1),
- v2 = __rwstd____RW_array(&unk_732B08),
- v3 = unknown_libname_34(&unk_732B08),
- v4 = sub_429350(v3, v2, &v8),
- v4 != __rwstd____RW_array(&unk_732B08))
- || System__AnsiString__Length(&a1, v1, v7) != 19
- || *(_BYTE *)System__AnsiString__operator__(&a1, 5) != 45
- || *(_BYTE *)System__AnsiString__operator__(&a1, 10) != 45
- || *(_BYTE *)System__AnsiString__operator__(&a1, 15) != 45 )
- v10 = 6681;
- else
- v10 = 17;
- v6 = v10;
- --v12;
- sub_6C8040(&a1, 2);
- return v6;
- }
Code (Assembler) : Убрать нумерацию
- .text:0042919C sub_42919C proc near
- .text:0042919C push ebp
- .text:0042919D mov ebp, esp
- .text:0042919F add esp, 0FFFFFFD4h
- .text:004291A2 mov eax, offset stru_6E0F50
- .text:004291A7 call @__InitExceptBlockLDTC
- .text:004291AC mov [ebp+var_8], 1
- .text:004291B3 lea edx, [ebp+arg_0]
- .text:004291B6 lea eax, [ebp+arg_0]
- .text:004291B9 call @System@AnsiString@AnsiString
- .text:004291BE inc [ebp+var_8]
- .text:004291C1 mov [ebp+var_14], 8
- .text:004291C7 lea eax, [ebp+arg_0]
- .text:004291CA call @System@AnsiString@c_str$xqqrv
- .text:004291CF push eax
- .text:004291D0 lea edx, [ebp+var_2C]
- .text:004291D3 push edx
- .text:004291D4 call sub_4291FC
- .text:004291D9 add esp, 8
- .text:004291DC push eax
- .text:004291DD dec [ebp+var_8]
- .text:004291E0 lea eax, [ebp+arg_0]
- .text:004291E3 mov edx, 2
- .text:004291E8 call sub_6C8040
- .text:004291ED pop eax
- .text:004291EE mov edx, [ebp+var_24]
- .text:004291F1 mov large fs:0, edx
- .text:004291F8 mov esp, ebp
- .text:004291FA pop ebp
- .text:004291FB retn
- .text:004291FB sub_42919C endp
- ;-------------------------------------------------------
- .text:004291FC sub_4291FC proc near
- .text:004291FC push ebp
- .text:004291FD mov ebp, esp
- .text:004291FF push [ebp+arg_4]
- .text:00429202 call sub_429FC0
- .text:00429207 pop ecx
- .text:00429208 pop ebp
- .text:00429209 retn
- .text:00429209 sub_4291FC endp
- ;-------------------------------------------------------
- .text:00429FC0 push ebp
- .text:00429FC1 mov ebp, esp
- .text:00429FC3 push ecx
- .text:00429FC4 xor eax, eax
- .text:00429FC6 mov [ebp+var_4], eax
- .text:00429FC9 jmp short loc_429FDF
- .text:00429FCB ; ---------------------------------
- .text:00429FCB loc_429FCB:
- .text:00429FCB mov edx, [ebp+var_4]
- .text:00429FCE lea edx, [edx+edx*4]
- .text:00429FD1 mov ecx, [ebp+arg_0]
- .text:00429FD4 movsx eax, byte ptr [ecx]
- .text:00429FD7 add edx, eax
- .text:00429FD9 mov [ebp+var_4], edx
- .text:00429FDC inc [ebp+arg_0]
- .text:00429FDF loc_429FDF:
- .text:00429FDF mov edx, [ebp+arg_0]
- .text:00429FE2 cmp byte ptr [edx], 0
- .text:00429FE5 jnz short loc_429FCB
- .text:00429FE7 mov eax, [ebp+var_4]
- .text:00429FEA pop ecx
- .text:00429FEB pop ebp
- .text:00429FEC retn
Code: Убрать нумерацию
- int __cdecl sub_429FC0(int a1)
- {
- int v2; // [sp+0h] [bp-4h]@1
- v2 = 0;
- while ( *(_BYTE *)a1 )
- v2 = *(_BYTE *)a1++ + 5 * v2;
- return v2;
- }
Code (Assembler) : Убрать нумерацию
- .text:00429350 sub_429350 proc near
- .text:00429350 push ebp
- .text:00429351 mov ebp, esp
- .text:00429353 add esp, 0FFFFFFF8h
- .text:00429356 lea eax, [ebp+var_8]
- .text:00429359 push eax
- .text:0042935A push [ebp+arg_8]
- .text:0042935D push [ebp+arg_4]
- .text:00429360 push [ebp+arg_0]
- .text:00429363 call sub_429370
- .text:00429368 add esp, 10h
- .text:0042936B pop ecx
- .text:0042936C pop ecx
- .text:0042936D pop ebp
- .text:0042936E retn
- .text:0042936E sub_429350 endp
- ;-------------------------------------------------------
- .text:00429370 sub_429370 proc near
- .text:00429370 push ebp
- .text:00429371 mov ebp, esp
- .text:00429373 push ecx
- .text:00429374 mov eax, [ebp+arg_4]
- .text:00429377 sub eax, [ebp+arg_0]
- .text:0042937A test eax, eax
- .text:0042937C jns short loc_429381
- .text:0042937E add eax, 3
- .text:00429381 loc_429381:
- .text:00429381 sar eax, 2
- .text:00429384 sar eax, 2
- .text:00429387 mov [ebp+var_4], eax
- .text:0042938A cmp [ebp+var_4], 0
- .text:0042938E jle short loc_4293F1
- .text:00429390 loc_429390:
- .text:00429390 mov edx, [ebp+arg_0]
- .text:00429393 mov ecx, [edx]
- .text:00429395 mov eax, [ebp+arg_8]
- .text:00429398 cmp ecx, [eax]
- .text:0042939A jnz short loc_4293A2
- .text:0042939C mov eax, [ebp+arg_0]
- .text:0042939F pop ecx
- .text:004293A0 pop ebp
- .text:004293A1 retn
- .text:004293A2 ; ------------------------------------------
- .text:004293A2 loc_4293A2:
- .text:004293A2 add [ebp+arg_0], 4
- .text:004293A6 mov edx, [ebp+arg_0]
- .text:004293A9 mov ecx, [edx]
- .text:004293AB mov eax, [ebp+arg_8]
- .text:004293AE cmp ecx, [eax]
- .text:004293B0 jnz short loc_4293B8
- .text:004293B2 mov eax, [ebp+arg_0]
- .text:004293B5 pop ecx
- .text:004293B6 pop ebp
- .text:004293B7 retn
- .text:004293B8 ; ----------------------------------------------
- .text:004293B8 loc_4293B8:
- .text:004293B8 add [ebp+arg_0], 4
- .text:004293BC mov edx, [ebp+arg_0]
- .text:004293BF mov ecx, [edx]
- .text:004293C1 mov eax, [ebp+arg_8]
- .text:004293C4 cmp ecx, [eax]
- .text:004293C6 jnz short loc_4293CE
- .text:004293C8 mov eax, [ebp+arg_0]
- .text:004293CB pop ecx
- .text:004293CC pop ebp
- .text:004293CD retn
- ...
Code (Assembler) : Убрать нумерацию
- .data:006D71F8 dword_6D71F8 dd 0C6DDDh
- .data:006D71FC dd 1267C1h
- .data:006D7200 dd 14EC36h
- .data:006D7204 dd 15BFAFh
- .data:006D7208 dd 1F2B5Bh
- .data:006D720C dd 259E5Ch
- .data:006D7210 dd 3F92A6h
- .data:006D7214 dd 47A33Eh
- ...
Программа успешно зарегистрирована
Защиты такого типа, где серийный номер сравнивается с заранее подготовленным списком, встречаются не очень часто, но все-таки авторы упорно продолжают их использовать. И хорошо, если для хеширования используется что-то типа MD5 или более серьезные алгоритмы, а что если при слабом алгоритме хеширования ключ из списка будет подобран брутфорсом или реверсом алгоритма из исходного значения? Автор, по идее, должен забанить такие ключи сразу после релиза. Что же в этом случае делать легальным пользователям? Вопрос остается без ответа.
Просмотров: 7646 | Комментариев: 16
Метки: исследование защиты, графика
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(24.09.2016 в 08:32):
Три года прошло, не удивительно.
brute
(24.09.2016 в 07:43):
Хотел разминки ради заломать "самостоятельно", но в новых версиях (3.4 - с сервера/4.3 - с сайта) всё поменялось - и интерфейс и защита. Похоже, накрыто армой_4.х. То есть, статья не актуальна..
Alex
(09.01.2016 в 21:21):
ты супер .....
ManHunter
(19.07.2013 в 19:39):
This is a "HiEW" -> hiew.ru or google for warez.
vhexr
(19.07.2013 в 19:24):
I wonder what is the name you use the software ?
this pic
http://www.manhunter.ru/upload...28828fa5.gif
this pic
http://www.manhunter.ru/upload...28828fa5.gif
sim31
(18.07.2013 в 13:07):
Спасибо за упоминание о программе, давно что-то подобное искал (в Irfan View тоже можно делать и даже автоматизировать хоть 10 000 файлов одним кликом), но тут нагляднее, и за картинку 7fb45f10190c1bac07ad20058b93f6f7.gif :)
ManHunter
(15.07.2013 в 23:09):
vhexr, I never do that and will not do.
vhexr
(15.07.2013 в 23:07):
Hi ManHunter please this release video tutorial
Noobie
(15.07.2013 в 13:47):
>патчится один из хешей
Само собой, так и было сделано, дел на 5 минут по часам :-) Но всегда хочется чего-то большого и чистого.
Само собой, так и было сделано, дел на 5 минут по часам :-) Но всегда хочется чего-то большого и чистого.
Vladimir
(15.07.2013 в 11:36):
Fix CRC v1.01 от PEiD прекрасно помог, после патча программа запускается и работает. Пытался патчить проверку CRC, но не разобрался с этим madExcept. <offtop>Сам люблю в программах портативность, потому серийные номера не так интересны.</offtop>
ManHunter
(15.07.2013 в 10:55):
Ну или же как вариант можно сделать лоадер и патчить программу в памяти. Но это если уж совсем скучно и нечем заняться.
irokkezz
(15.07.2013 в 09:14):
Спасибо большое!
ManHunter
(15.07.2013 в 09:12):
Хех :) Я специально не рассматривал тут вариант с патчем :)
А копать надо в направлении CRC в PE-хидере, защита основана на ней. Достаточно пофиксить заголовок после модификации файла и все заработает.
А копать надо в направлении CRC в PE-хидере, защита основана на ней. Достаточно пофиксить заголовок после модификации файла и все заработает.
irokkezz
(15.07.2013 в 09:09):
Доброе утро!
Попробовал пропатчить процедуру 0042920C:
mov eax,11h
ret
Под отладчиком программа запускается без триальных ограничений, а в обычном режиме выводится сообщение о том, что файл поврежден. Попытался определить условие вывода этого сообщения и совсем запутался.
Не подскажете, в каком направлении копать?
Попробовал пропатчить процедуру 0042920C:
mov eax,11h
ret
Под отладчиком программа запускается без триальных ограничений, а в обычном режиме выводится сообщение о том, что файл поврежден. Попытался определить условие вывода этого сообщения и совсем запутался.
Не подскажете, в каком направлении копать?
ManHunter
(15.07.2013 в 08:15):
В таких случаях генерируется какой-нибудь свой серийник и патчится один из хешей под него. MD5 при 25 цифрах брутить очень гиморно.
Noobie
(15.07.2013 в 06:48):
Спасибо за статью, как всегда наглядно и доходчиво. Вопрос - встретилась программа с аналогичным методом защиты, серийник 25 цифр, первые 5 известны, считается MD5 и сравнивается с несколькими десятками зашитых значений. Насколько реально брутфорснуть, путем тупого перебора значений MD5 и их сравнения с валидными?
Добавить комментарий
Заполните форму для добавления комментария