
Скриншот программы 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
А вот тут условный переход надо заменить на безусловный, так как условие проверки обратное. Теперь можно сохранить изменения и попробовать запустить программу. Триальное окно при запуске пропало, в окне "О программе" сказано, что программа зарегистрирована (надпись на скриншоте уже я немного подрихтовал). Других ограничений в программе нет.

Программа успешно "зарегистрирована"
Вот и все, программа работает как зарегистрированная, все ограничения по времени работы сняты. Можно больше не отвлекаться от разбора новогодних фотографий, а на сэкономленные деньги лучше купите что-нибудь вкусное на праздничный стол.