Исследование защиты программы Moo0 ImageViewer SP
Скриншот программы Moo0 ImageViewer SP
Moo0 ImageViewer - шустрый просмотрщик, конвертер и редактор изображений популярных форматов. Приятная программа, за исключением того, что бесплатно работает только 30 дней, а потом просит денег. Давайте исправим этот досадный недостаток.
Забираем с офсайта свеженький дистрибутив, устанавливаем его, запускаем. В окне программы сразу же красуется поле для ввода серийника. На попытку ввести туда какие-то левые данные, программа реагирует следующим сообщением:
Сообщение о неправильной регистрации
Главный файл ничем не защищен и не упакован, отправляем его на разборку в дизассемблер. Поскольку программа состоит из единственного файла и никаких дополнительных пакетов локализации нет, значит надо искать строку в нем. Встроенный просмотрщик Total Commander легко обнаруживает вот такой блок:
Строка сообщения в файле
Выше и ниже находятся похожие блоки с другими строками на разных языках. Логично предположить, что обращение к ним выполняется по идентификатору, в нашем случае это число 401060 или 61EA4h, если считать в шестнадцатеричной системе. Поиск в листинге этого значения приводит нас на следующий код:
Code (Assembler) : Убрать нумерацию
- .text:0042631B mov ecx, [ebx+6E4h]
- .text:00426321 test ecx, ecx
- .text:00426323 jz short loc_426361
- ; Вызывать функцию проверки
- .text:00426325 call sub_427A60
- .text:0042632A test al, al
- .text:0042632C jnz short loc_426361
- ; Вывести сообщение о неправильной регистрации
- .text:0042632E mov dl, [ebx+6E0h]
- .text:00426334 mov ecx, [ebx+6DCh]
- .text:0042633A mov dword ptr [ebx+6E4h], 0
- .text:00426344 call sub_42A0E0
- .text:00426349 test eax, eax
- .text:0042634B jns short loc_426361
- .text:0042634D mov ecx, [ebx+1Ch]
- .text:00426350 push 61EA4h
- .text:00426355 call sub_42F3B0
- .text:0042635A mov ecx, eax
- .text:0042635C call sub_44AE60
Code (Assembler) : Убрать нумерацию
- .text:00427A60 sub_427A60
- .text:00427A60 imul eax, ecx, 1001h
- .text:00427A66 add eax, 7ED55D16h
- .text:00427A6B mov ecx, eax
- .text:00427A6D shr ecx, 13h
- .text:00427A70 xor ecx, eax
- .text:00427A72 xor ecx, 0C761C23Ch
- .text:00427A78 mov eax, ecx
- .text:00427A7A add ecx, 165667B1h
- .text:00427A80 shl eax, 5
- .text:00427A83 add eax, ecx
- .text:00427A85 lea ecx, [eax-2C5D9B94h]
- .text:00427A8B shl eax, 9
- .text:00427A8E xor ecx, eax
- .text:00427A90 lea ecx, [ecx+ecx*8]
- .text:00427A93 add ecx, 0FD7046C5h
- .text:00427A99 mov eax, ecx
- .text:00427A9B shr eax, 10h
- .text:00427A9E xor al, cl
- .text:00427AA0 shr al, 7
- .text:00427AA3 not al
- .text:00427AA5 and al, 1
- .text:00427AA7 retn
- .text:00427AA7 sub_427A60 endp
Code (Assembler) : Убрать нумерацию
- .text:0041A7EA mov [ebx+6E4h], eax
- .text:0041A7F0 cmp eax, 3B9ACA00h
- .text:0041A7F5 jb short loc_41A833
- ...
- ...
- ...
- .text:0041A833 loc_41A833:
- ; Вывести сообщение о неправильном серийном номере
- .text:0041A833 push 61EA4h
- .text:0041A838 call sub_42F3B0
- .text:0041A83D mov ecx, eax
- .text:0041A83F call sub_44AE60
- .text:0041A844 mov ecx, [ebx+6ECh]
- .text:0041A84A push 0
Программа успешно зарегистрирована
Внешне программа выглядит зарегистрированной, однако при попытке открыть любой графический файл, регистрация мгновенно слетает. В этих ваших интернетах уже появлялись релизы генераторов ключей и отдельных серийников от разных крякерских команд, но все они не работают, регистрация стабильно слетает. Каким образом отловить код, который сбрасывает регистрацию? Давайте посмотрим на окно "О программе". Сразу после запуска программы и фейковой псевдо-регистрации в нем красуется надпись "(Зарегистрировано)". Строчки мы искать уже умеем, по аналогии находим строку с индексом 401040, оно же 61E90h. Находим в листинге место, где этот индекс используется:
Code (Assembler) : Убрать нумерацию
- ; Проверить флаг зарегистрированности
- .text:00455BC5 cmp byte ptr [ebx+3Ch], 0
- .text:00455BC9 jz short loc_455C12
- .text:00455BCB mov eax, [esi]
- .text:00455BCD mov ecx, esi
- .text:00455BCF push 0
- .text:00455BD1 push 0AAh
- .text:00455BD6 push 0
- .text:00455BD8 call dword ptr [eax+130h]
- .text:00455BDE mov eax, [esi]
- .text:00455BE0 mov ecx, esi
- .text:00455BE2 push 1
- .text:00455BE4 call dword ptr [eax+14Ch]
- .text:00455BEA mov ecx, [ebx+10h]
- .text:00455BED mov eax, [ecx]
- .text:00455BEF call dword ptr [eax+24h]
- ; Загрузить строчку
- .text:00455BF2 push 61E90h
- .text:00455BF7 mov ecx, eax
- .text:00455BF9 mov edx, [eax]
Code (Assembler) : Убрать нумерацию
- ; Проверить серийный номер
- .text:004272BD cmp dword ptr [ebx+6E4h], 3B9ACA00h
- .text:004272C7 mov eax, [ebx+1C8h]
- ; Если значение меньше 3B9ACA00h, то программа не зарегистрирована
- .text:004272CD jb short loc_4272D5
- ; Установить флаг регистрации
- .text:004272CF mov byte ptr [eax+3Ch], 1
- .text:004272D3 jmp short loc_4272D9
- .text:004272D5 ; ---------------------------------------
- .text:004272D5 loc_4272D5:
- ; Сбросить флаг регистрации
- .text:004272D5 mov byte ptr [eax+3Ch], 0
- .text:004272D9 loc_4272D9:
- .text:004272D9 push dword ptr [ebx+18Ch]
- .text:004272DF mov ecx, [ebx+1C8h]
- .text:004272E5 call sub_454520
- .text:004272EA pop edi
Адрес ячейки памяти
Таким образом мы узнаем адрес ячейки памяти, в которой пока еще хранится серийник. Переходим на этот адрес в дампе и ставим Memory breakpoint на любую запись в этот адрес.
Ставим точку останова
Отпускаем программу на выполнение и выполняем любое действие, которое приводит к слету регистрации, в нашем случае это попытка открыть любой графический файл для просмотра. Точка останова сработает в момент записи нуля в ячейку памяти, то есть выполняется сброс регистрации.
Code (Assembler) : Убрать нумерацию
- .text:00419D7A cmp dword ptr [ebx+6E4h], 0
- .text:00419D81 jz short loc_419DAC
- .text:00419D83 mov ecx, [esp+40h+var_10]
- ; Вызвать проверку
- .text:00419D87 call sub_429FE0
- .text:00419D8C test al, al
- ; Регистрацию не обнулять, проверка пройдена успешно
- .text:00419D8E jnz short loc_419DAC
- .text:00419D90 mov dl, byte ptr [esp+40h+var_18+3]
- .text:00419D94 mov ecx, esi
- .text:00419D96 call sub_42A0E0
- .text:00419D9B test eax, eax
- .text:00419D9D jns short loc_419DA4
- .text:00419D9F call sub_429F80
- .text:00419DA4 loc_419DA4:
- ; Обнулить регистрацию
- .text:00419DA4 xor eax, eax
- .text:00419DA6 mov [esp+40h+var_10], eax
- .text:00419DAA jmp short loc_419DB0
- .text:00419DAC ; ---------------------------------------
- .text:00419DAC loc_419DAC:
- .text:00419DAC mov eax, [esp+40h+var_10]
- .text:00419DB0 loc_419DB0:
- ; Записать новые данные регистрации
- .text:00419DB0 mov [ebx+6E4h], eax
- .text:00419DB6 mov [ebx+6DCh], esi
- .text:00419DBC test eax, eax
- .text:00419DBE jnz short loc_419DD3
Code (Assembler) : Убрать нумерацию
- .text:00429FE0 sub_429FE0 proc near
- .text:00429FE0 imul eax, ecx, 1001h
- .text:00429FE6 add eax, 7ED55D16h
- .text:00429FEB mov ecx, eax
- .text:00429FED shr ecx, 13h
- .text:00429FF0 xor ecx, eax
- .text:00429FF2 xor ecx, 0C761C23Ch
- .text:00429FF8 mov eax, ecx
- .text:00429FFA add ecx, 165667B1h
- .text:0042A000 shl eax, 5
- .text:0042A003 add eax, ecx
- .text:0042A005 lea ecx, [eax-2C5D9B94h]
- .text:0042A00B shl eax, 9
- .text:0042A00E xor ecx, eax
- .text:0042A010 lea ecx, [ecx+ecx*8]
- .text:0042A013 add ecx, 0FD7046C5h
- .text:0042A019 mov eax, ecx
- .text:0042A01B shr eax, 10h
- .text:0042A01E xor al, cl
- .text:0042A020 shr al, 6
- .text:0042A023 and al, 1
- .text:0042A025 retn
- .text:0042A025 sub_429FE0 endp
Code (Assembler) : Убрать нумерацию
- .text:004242AB mov eax, [ebx+6E4h]
- ...
- .text:004242BB mov ecx, eax
- .text:004242BD not eax
- .text:004242BF shl ecx, 0Fh
- .text:004242C2 add ecx, eax
- .text:004242C4 mov eax, ecx
- .text:004242C6 shr eax, 0Ch
- .text:004242C9 xor eax, ecx
- .text:004242CB lea edx, [eax+eax*4]
- .text:004242CE mov eax, edx
- .text:004242D0 shr eax, 4
- .text:004242D3 xor eax, edx
- .text:004242D5 imul eax, 809h
- .text:004242DB cmp eax, 80000000h
- ; Сбросить регистрацию
- ...
- ...
- ...
- .text:00424327 mov eax, [ebx+6E4h]
- .text:0042432D test eax, eax
- .text:0042432F jz short loc_4243A3
- .text:00424331 mov ecx, eax
- .text:00424333 not eax
- .text:00424335 shl ecx, 0Fh
- .text:00424338 add ecx, eax
- .text:0042433A mov eax, ecx
- .text:0042433C shr eax, 0Ch
- .text:0042433F xor eax, ecx
- .text:00424341 lea ecx, [eax+eax*4]
- .text:00424344 mov eax, ecx
- .text:00424346 shr eax, 4
- .text:00424349 xor eax, ecx
- .text:0042434B imul eax, 809h
- .text:00424351 test eax, 10000000h
- .text:00424356 jnz short loc_4243A3
- ; Сбросить регистрацию
- ...
- ...
- ...
- .text:004243A3 mov eax, [ebx+6E4h]
- .text:004243A9 test eax, eax
- .text:004243AB jz loc_42443B
- .text:004243B1 imul eax, 1001h
- .text:004243B7 add eax, 7ED55D16h
- .text:004243BC mov ecx, eax
- .text:004243BE shr ecx, 13h
- .text:004243C1 xor ecx, eax
- .text:004243C3 xor ecx, 0C761C23Ch
- .text:004243C9 mov eax, ecx
- .text:004243CB shl eax, 5
- .text:004243CE add eax, ecx
- .text:004243D0 lea ecx, [eax+165667B1h]
- .text:004243D6 add eax, 1658CC1Dh
- .text:004243DB shl ecx, 9
- .text:004243DE xor ecx, eax
- .text:004243E0 add ecx, 7DDh
- .text:004243E6 lea eax, [ecx+ecx*8]
- .text:004243E9 test eax, 40000h
- .text:004243EE jz short loc_42443B
- ; Сбросить регистрацию
- ...
- ...
- ...
- .text:0042443B mov eax, [ebx+6E4h]
- ...
- .text:0042445A imul eax, 1001h
- .text:00424460 add eax, 7ED55D16h
- .text:00424465 mov ecx, eax
- .text:00424467 shr ecx, 13h
- .text:0042446A xor ecx, eax
- .text:0042446C xor ecx, 0C761C23Ch
- .text:00424472 mov eax, ecx
- .text:00424474 shl eax, 5
- .text:00424477 add eax, ecx
- .text:00424479 lea ecx, [eax+165667B1h]
- .text:0042447F add eax, 0E9F8CC1Dh
- .text:00424484 shl ecx, 9
- .text:00424487 xor ecx, eax
- .text:00424489 lea ecx, [ecx+ecx*8]
- .text:0042448C add ecx, 0FD7046C5h
- .text:00424492 mov eax, ecx
- .text:00424494 shr eax, 10h
- .text:00424497 xor eax, ecx
- .text:00424499 test eax, 2000h
- .text:0042449E jnz short loc_4244D8
- ; Сбросить регистрацию
Code (Assembler) : Убрать нумерацию
- .text:004267B6 imul eax, [ebp+var_18], 1001h
- .text:004267BD add eax, 7ED55D16h
- .text:004267C2 mov ecx, eax
- .text:004267C4 shr ecx, 13h
- .text:004267C7 xor ecx, eax
- .text:004267C9 xor ecx, 0C761C23Ch
- .text:004267CF mov eax, ecx
- .text:004267D1 shl eax, 5
- .text:004267D4 add eax, 165667B1h
- .text:004267D9 add eax, ecx
- .text:004267DB lea esi, [eax-2C5D9B94h]
- .text:004267E1 shl eax, 9
- .text:004267E4 xor esi, eax
- .text:004267E6 lea esi, [esi+esi*8]
- .text:004267E9 add esi, 0FD7046C5h
- .text:004267EF mov eax, esi
- .text:004267F1 shr eax, 10h
- .text:004267F4 xor eax, esi
- .text:004267F6 test al, al
- .text:004267F8 jns short loc_42680E
Если собрать все проверки серийника и заменить в них условные переходы на противоположное значение, то можно сделать полноценный генератор-брутфорсер. У меня он получился вот такой. Код получения случайного числа я тут не привожу, все необходимое для этого есть на сайте в разделе "Ассемблер".
Code (Assembler) : Убрать нумерацию
- gen:
- ;--------------------------
- ; Получаем случайное число и записываем его в регистр ESI
- ; ESI = случайное число
- ;--------------------------
- mov eax,esi
- cmp eax,1000000000
- jb gen
- ;--------------------------
- mov eax,esi
- imul eax, 1001h
- add eax, 7ED55D16h
- mov ecx, eax
- shr ecx, 13h
- xor ecx, eax
- xor ecx, 0C761C23Ch
- mov eax, ecx
- add ecx, 165667B1h
- shl eax, 5
- add eax, ecx
- lea ecx, [eax-2C5D9B94h]
- shl eax, 9
- xor ecx, eax
- lea ecx, [ecx+ecx*8]
- add ecx, 0FD7046C5h
- mov eax, ecx
- shr eax, 10h
- xor al, cl
- shr al, 6
- and al, 1
- or al,al
- jz gen
- ;--------------------------
- mov eax,esi
- mov ecx, eax
- not eax
- shl ecx, 0Fh
- add ecx, eax
- mov eax, ecx
- shr eax, 0Ch
- xor eax, ecx
- lea edx, [eax+eax*4]
- mov eax, edx
- shr eax, 4
- xor eax, edx
- imul eax, 809h
- cmp eax, 80000000h
- jae gen
- ;--------------------------
- mov eax,esi
- mov ecx, eax
- not eax
- shl ecx, 0Fh
- add ecx, eax
- mov eax, ecx
- shr eax, 0Ch
- xor eax, ecx
- lea ecx, [eax+eax*4]
- mov eax, ecx
- shr eax, 4
- xor eax, ecx
- imul eax, 809h
- test eax, 10000000h
- jz gen
- ;--------------------------
- mov eax,esi
- imul eax, 1001h
- add eax, 7ED55D16h
- mov ecx, eax
- shr ecx, 13h
- xor ecx, eax
- xor ecx, 0C761C23Ch
- mov eax, ecx
- shl eax, 5
- add eax, ecx
- lea ecx, [eax+165667B1h]
- add eax, 1658CC1Dh
- shl ecx, 9
- xor ecx, eax
- add ecx, 7DDh
- lea eax, [ecx+ecx*8]
- test eax, 40000h
- jnz gen
- ;--------------------------
- mov eax,esi
- imul eax, 1001h
- add eax, 7ED55D16h
- mov ecx, eax
- shr ecx, 13h
- xor ecx, eax
- xor ecx, 0C761C23Ch
- mov eax, ecx
- shl eax, 5
- add eax, ecx
- lea ecx, [eax+165667B1h]
- add eax, 0E9F8CC1Dh
- shl ecx, 9
- xor ecx, eax
- lea ecx, [ecx+ecx*8]
- add ecx, 0FD7046C5h
- mov eax, ecx
- shr eax, 10h
- xor eax, ecx
- test eax, 2000h
- jz gen
- ;--------------------------
- mov eax,esi
- imul eax, 1001h
- add eax, 7ED55D16h
- mov ecx, eax
- shr ecx, 13h
- xor ecx, eax
- xor ecx, 0C761C23Ch
- mov eax, ecx
- shl eax, 5
- add eax, 165667B1h
- add eax, ecx
- lea ecx, [eax-2C5D9B94h]
- shl eax, 9
- xor ecx, eax
- lea ecx, [ecx+ecx*8]
- add ecx, 0FD7046C5h
- mov eax, ecx
- shr eax, 10h
- xor eax, ecx
- test al, al
- js gen
- ;--------------------------
- mov eax,esi
- imul eax, 1001h
- add eax, 7ED55D16h
- mov ecx, eax
- shr ecx, 13h
- xor ecx, eax
- xor ecx, 0C761C23Ch
- mov eax, ecx
- add ecx, 165667B1h
- shl eax, 5
- add eax, ecx
- lea ecx, [eax-2C5D9B94h]
- shl eax, 9
- xor ecx, eax
- lea ecx, [ecx+ecx*8]
- add ecx, 0FD7046C5h
- mov eax, ecx
- shr eax, 10h
- xor al, cl
- shr al, 7
- not al
- and al, 1
- cmp al,1
- jne gen
- ;--------------------------
- ; ESI = валидный серийник
- ;--------------------------
Программа успешно зарегистрирована
Но даже если что-то я проглядел, то слет регистрации можно отловить, как я написал выше. Спасибо автору и за хорошую программу, и за отличную разминку для ума.
Просмотров: 1962 | Комментариев: 3
Метки: исследование защиты, мультимедиа
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
voffka
(20.07.2019 в 03:07):
ИМХО. А не оптимальней все jx gen кроме первого направлять на inc или dec esi?
ufo
(16.07.2019 в 00:17):
Попробовал программу в деле. Не понравилась. Неудобная, мало форматов открывает, да еще платная с таким функционалом проверок :). Мне кажется она больше подходит не для работы, а для исследований проверок регистрации и поиска "сюрпризов". Бесплатная PhotoScape привычнее.
xussr
(22.06.2019 в 11:21):
Это что прикол такой взял прогу по ссылки ввел шесть пятерок просто по приколу от балды она мне написала что прога успешна зарегина ну ты прикололся ...)))))
Интересная защита
Интересная защита
Добавить комментарий
Заполните форму для добавления комментария