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


Скриншот программы Noiseware Professional

Noiseware Professional от компании Imagenomic - одна из лучших программ для удаления артефактов и цифрового шума с фотографий. Все действия выполняются буквально в несколько кликов, есть пакетный режим работы и множество ручных настроек для профессионалов. Но, как обычно бывает в таких случаях, весь кайф портит запредельная стоимость программы.

Скачиваем дистрибутив, устанавливаем, запускаем. Сразу появляется окно с предложением заплатить. Ну или с предупреждением, что триальный период закончился. Это кому как повезет.


Триальное окно

Самой приметной строчкой в этом окне является "is not registered", поищем ее в файле. Он, кстати, ничем не упакован. Все лежит как на блюдечке. Там же и другие строчки, так или иначе связанные с незарегистрированным статусом программы:


Нехорошая строка найдена

Дальше все по классической схеме. В дизассемблере смотрим на участок кода, который ссылается на эту строку, а также все, что относится к переходам на этот участок. Вот что находится:
.text:00401977                 add     eax, 10h
.text:0040197A                 mov     [esp+1Ch+lpString], eax
; Указатель на участок памяти
.text:0040197E                 mov     ecx, dword_4B5A68
; Загрузить в EAX значение из указателя
.text:00401984                 mov     eax, [ecx-0Ch]
; Если EAX=0, то программа не зарегистрирована
.text:00401987                 test    eax, eax
.text:00401989                 mov     [esp+1Ch+var_4], 0
.text:00401991                 jz      short loc_401A03
; Иначе добавить в окно информацию о ID программы и регистрационном имени
.text:00401993                 mov     edx, dword_4B5A6C
.text:00401999                 push    edx
.text:0040199A                 lea     eax, [esp+20h+lpString]
.text:0040199E                 push    offset aS_0     ; " %s"
.text:004019A3                 push    eax
.text:004019A4                 call    sub_4018E0
.text:004019A9                 mov     ecx, ArgList
.text:004019AF                 push    ecx             ; ArgList
.text:004019B0                 lea     edx, [esp+2Ch+lpString]
.text:004019B4                 push    offset aS       ; "\r\n %s"
.text:004019B9                 push    edx             ; int
.text:004019BA                 call    sub_401900
.text:004019BF                 mov     eax, dword_4B5A68
.text:004019C4                 push    eax             ; ArgList
.text:004019C5                 lea     ecx, [esp+38h+lpString]
.text:004019C9                 push    offset aProductIdS
; "\r\n\r\n Product ID: %s"
.text:004019CE                 push    ecx             ; int
.text:004019CF                 call    sub_401900
.text:004019D4                 add     esp, 24h
.text:004019D7                 push    0               ; nCmdShow
.text:004019D9                 push    3F4h            ; nIDDlgItem
.text:004019DE                 mov     ecx, esi
.text:004019E0                 call    ?GetDlgItem@CWnd@@QBEPAV1@H@Z
; CWnd::GetDlgItem(int)
.text:004019E5                 mov     ecx, eax
.text:004019E7                 call    ?ShowWindow@CWnd@@QAEHH@Z
; CWnd::ShowWindow(int)
.text:004019EC                 push    0               ; nCmdShow
.text:004019EE                 push    3F5h            ; nIDDlgItem
.text:004019F3                 mov     ecx, esi
.text:004019F5                 call    ?GetDlgItem@CWnd@@QBEPAV1@H@Z
; CWnd::GetDlgItem(int)
.text:004019FA                 mov     ecx, eax
.text:004019FC                 call    ?ShowWindow@CWnd@@QAEHH@Z
; CWnd::ShowWindow(int)
.text:00401A01                 jmp     short loc_401A4E
.text:00401A03 ; ----------------------------------------------------
.text:00401A03 loc_401A03:
; Триальная ветка алгоритма
.text:00401A03                 test    edi, edi
.text:00401A05                 jle     short loc_401A20
; Сообщение, если триальный срок еще не закончился
.text:00401A07                 push    edi
.text:00401A08                 lea     edx, [esp+20h+lpString]
.text:00401A0C                 push    offset aTheEvaluationP
; "The evaluation period will expire in %d"...
.text:00401A11                 push    edx
.text:00401A12                 call    sub_4018E0
.text:00401A17                 add     esp, 0Ch
.text:00401A1A                 mov     byte ptr [esi+74h], 0
.text:00401A1E                 jmp     short loc_401A36
.text:00401A20 ; -----------------------------------------------
.text:00401A20 loc_401A20:
; Сообщение, если триальный срок уже закончился
.text:00401A20                 lea     eax, [esp+1Ch+lpString]
.text:00401A24                 push    offset aTheEvaluatio_0
; "The evaluation period has been expired."...
.text:00401A29                 push    eax
.text:00401A2A                 call    sub_4018E0
.text:00401A2F                 add     esp, 8
.text:00401A32                 mov     byte ptr [esi+74h], 1
.text:00401A36 loc_401A36:
.text:00401A36                 push    offset aThisSoftwareIs
; "This software is not registered."
.text:00401A3B                 push    4C3h            ; nIDDlgItem
.text:00401A40                 mov     ecx, esi
.text:00401A42                 call    ?GetDlgItem@CWnd@@QBEPAV1@H@Z
; CWnd::GetDlgItem(int)
.text:00401A47                 mov     ecx, eax
.text:00401A49                 call    ?SetWindowTextA@CWnd@@QAEXPBD@Z
; CWnd::SetWindowTextA(char const *)
.text:00401A4E loc_401A4E:
.text:00401A4E                 mov     edi, [esp+1Ch+lpString]
.text:00401A52                 push    edi             ; lpString
.text:00401A53                 push    4C4h            ; nIDDlgItem
.text:00401A58                 mov     ecx, esi
.text:00401A5A                 call    ?GetDlgItem@CWnd@@QBEPAV1@H@Z
; CWnd::GetDlgItem(int)
.text:00401A5F                 mov     ecx, eax
.text:00401A61                 call    ?SetWindowTextA@CWnd@@QAEXPBD@Z
; CWnd::SetWindowTextA(char const *)

Все должно быть понятно. Берется указатель по адресу 004B5A68, затем относительно него считывается двойное слово. Если оно равно нулю, то программа незарегистрирована, иначе все в порядке. Точка отсчета найдена, теперь посмотрим перекрестные ссылки, которые относятся к этому указателю.


Перекрестные ссылки на указатель

Не так много. Посмотрим их все по очереди:
.text:00401570                 mov     eax, dword_4B5A68
.text:00401575                 cmp     dword ptr [eax-0Ch], 0
.text:00401579                 push    esi
.text:0040157A                 mov     esi, ecx
.text:0040157C                 jz      short loc_401582

Практически такая же проверка, забиваем условный переход по адресу 0040157C NOPами. Вторая перекрестная ссылка относится к вышеуказанному коду, там по адресу 00401991 тоже патчим условный переход. Третья находится чуть ниже по коду, там, по всей видимости обрабатывается "Product ID", это нам не интересно, пропускаем.
.text:004143A8                 mov     eax, dword_4B5A68
.text:004143AD                 cmp     dword ptr [eax-0Ch], 0
.text:004143B1                 jz      short loc_41442A
Тут также забиваем условный переход NOPами.
Code (Assembler) : Убрать нумерацию
.text:0041A060                 mov     eax, dword_4B5A68
.text:0041A065                 cmp     dword ptr [eax-0Ch], 0
.text:0041A069                 jnz     short loc_41A084

А вот тут условный переход надо заменить на безусловный, так как условие проверки обратное. Теперь можно сохранить изменения и попробовать запустить программу. Триальное окно при запуске пропало, в окне "О программе" сказано, что программа зарегистрирована (надпись на скриншоте уже я немного подрихтовал). Других ограничений в программе нет.


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

Вот и все, программа работает как зарегистрированная, все ограничения по времени работы сняты. Можно больше не отвлекаться от разбора новогодних фотографий, а на сэкономленные деньги лучше купите что-нибудь вкусное на праздничный стол.
Добавлено: 14 Сентября 2013 09:32:41 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...