
Скриншот программы Sonne Flash Decompiler
Sonne Flash Decompiler - предназначена для извлечения объектов и других элементов, используемых во flash-файлах. Она также позволяет извлекать файлы SWF из EXE-контейнеров и редактировать ролики в формате SWF - изменять текст, шрифты, картинки, звуки, формы, скрипты и другие элементы, находящиеся во flash-файле. Естественно, за все это аффтары хотят денег.
Качаем
дистрибутив, распаковываем, устанавливаем. Сразу после запуска нам предлагают ввести регистрационные данные, а точнее имя, адрес электронной почты и серийный номер.

Окно регистрации программы
На ввод всякого левака программа реагирует сообщением "Invalid registration key!". Исполняемый файл ничем не упакован, искомая строчка лежит в открытом виде:

Нехорошая строка найдена
Традиционно переходим к дизассемблированию с целью выяснить условия появления этой строки. Код достаточно понятный, но я постараюсь его максимально прокомментировать:
CODE:00644014 lea edx, [ebp+var_28]
CODE:00644017 mov eax, [ebx+300h]
; Прочитать введенный текст из поля ввода
CODE:0064401D call @Controls@TControl@GetText$qqrv
CODE:00644022 cmp [ebp+var_28], 0
; Если его длина не нулевая, то продолжить
CODE:00644026 jnz short loc_64406F
; Сообщение "Invalid registration key!"
CODE:00644028 push 30h ; uType
CODE:0064402A lea edx, [ebp+var_2C]
; Указатель на указатель на строку "Invalid registration key!"
CODE:0064402D mov eax, ds:off_662AFC
CODE:00644032 mov eax, [eax]
CODE:00644034 call @Forms@TApplication@GetTitle$qqrv
CODE:00644039 mov eax, [ebp+var_2C]
CODE:0064403C call @System@@LStrToPChar$qqrx...
CODE:00644041 push eax ; lpCaption
CODE:00644042 mov eax, ds:off_66262C
CODE:00644047 mov eax, [eax]
CODE:00644049 call @System@@LStrToPChar$qqrx...
CODE:0064404E push eax ; lpText
CODE:0064404F mov eax, ebx
CODE:00644051 call @Controls@TWinControl@GetHandle$qqrv
CODE:00644056 push eax ; hWnd
CODE:00644057 call MessageBoxA_0
CODE:0064405C mov eax, [ebx+300h]
CODE:00644062 mov edx, [eax]
CODE:00644064 call dword ptr [edx+0C4h]
CODE:0064406A jmp loc_644122
CODE:0064406F ; -------------------------------------------
; Подготовка всех трех строк (имя, email и серийник) к проверке
CODE:0064406F loc_64406F:
CODE:0064406F lea eax, [ebp+var_30]
CODE:00644072 mov edx, [ebp+var_8]
CODE:00644075 call @System@@LStrFromWStr$qqrr...
CODE:0064407A mov eax, [ebp+var_30]
CODE:0064407D push eax
CODE:0064407E push 0
CODE:00644080 lea eax, [ebp+var_34]
CODE:00644083 mov edx, [ebp+var_4]
CODE:00644086 call @System@@LStrFromWStr$qqrr...
CODE:0064408B mov eax, [ebp+var_34]
CODE:0064408E push eax
CODE:0064408F lea eax, [ebp+var_38]
CODE:00644092 mov edx, [ebp+var_C]
CODE:00644095 call @System@@LStrFromWStr$qqrr...
CODE:0064409A mov edx, [ebp+var_38]
CODE:0064409D mov eax, ds:off_662550
CODE:006440A2 mov eax, [eax]
CODE:006440A4 pop ecx
; Вызвать процедуру проверки серийного номера
CODE:006440A5 call @Sqledit@EditSQL$qqrp16Classes...
; Если она вернула AL!=0, то регистрационные данные верные
CODE:006440AA test al, al
CODE:006440AC jz short loc_6440CB
; Регистрация прошла успешно
CODE:006440AE mov eax, ds:off_662550
CODE:006440B3 mov eax, [eax]
CODE:006440B5 call sub_626308
; Установить флажок "Зарегистрировано"
CODE:006440BA mov eax, ds:off_66284C
CODE:006440BF mov byte ptr [eax], 1
CODE:006440C2 mov eax, ebx
; Вывести сообщение об удачной регистрации
CODE:006440C4 call sub_643E88
CODE:006440C9 jmp short loc_644122
CODE:006440CB ; ------------------------------------------------
CODE:006440CB loc_6440CB:
; Вывести сообщение "Invalid registration key!"
CODE:006440CB mov eax, ds:off_66284C
CODE:006440D0 mov byte ptr [eax], 0
CODE:006440D3 push 10h ; uType
CODE:006440D5 lea edx, [ebp+var_3C]
CODE:006440D8 mov eax, ds:off_662AFC
CODE:006440DD mov eax, [eax]
CODE:006440DF call @Forms@TApplication@GetTitle$qqrv
CODE:006440E4 mov eax, [ebp+var_3C]
CODE:006440E7 call @System@@LStrToPChar$qqrx17System@AnsiString
CODE:006440EC push eax ; lpCaption
; Указатель на указатель на строку "Invalid registration key!"
CODE:006440ED mov eax, ds:off_66262C
CODE:006440F2 mov eax, [eax]
CODE:006440F4 call @System@@LStrToPChar$qqrx17System@AnsiString
CODE:006440F9 push eax ; lpText
CODE:006440FA mov eax, ebx
CODE:006440FC call @Controls@TWinControl@GetHandle$qqrv
CODE:00644101 push eax ; hWnd
CODE:00644102 call MessageBoxA_0
...
Итого, что мы имеем. По адресу ds:off_66284C хранится флаг регистрации. Если байт по этому адресу равен 1, то программа считается зарегистрированной, иначе нет. Ссылок на него слишком много, чтобы патчить их все, поэтому попробуем пройти под отладчиком процедуру проверки регистрационных данных.
CODE:006260DC push ebp
CODE:006260DD mov ebp, esp
CODE:006260DF add esp, 0FFFFFFF4h
CODE:006260E2 push ebx
CODE:006260E3 push esi
CODE:006260E4 xor ebx, ebx
CODE:006260E6 mov [ebp+var_C], ebx
CODE:006260E9 mov [ebp+var_8], ecx
CODE:006260EC mov [ebp+var_4], edx
CODE:006260EF mov esi, eax
CODE:006260F1 mov eax, [ebp+var_4]
CODE:006260F4 call @System@@LStrAddRef$qqrpv
CODE:006260F9 mov eax, [ebp+var_8]
CODE:006260FC call @System@@LStrAddRef$qqrpv
CODE:00626101 mov eax, [ebp+arg_4]
CODE:00626104 call @System@@LStrAddRef$qqrpv
CODE:00626109 mov eax, [ebp+arg_0]
CODE:0062610C call @System@@LStrAddRef$qqrpv
CODE:00626111 xor eax, eax
CODE:00626113 push ebp
CODE:00626114 push offset loc_62619C
CODE:00626119 push dword ptr fs:[eax]
CODE:0062611C mov fs:[eax], esp
CODE:0062611F cmp byte ptr [esi+34h], 0
CODE:00626123 jnz short loc_626129
CODE:00626125 xor ebx, ebx
CODE:00626127 jmp short loc_626174
CODE:00626129 ; ------------------------------------
CODE:00626129 loc_626129:
CODE:00626129 lea edx, [ebp+var_C]
CODE:0062612C mov eax, esi
CODE:0062612E call sub_626708
; Функция сравнения двух текстовых строк
CODE:00626133 mov edx, [ebp+var_C]
CODE:00626136 mov eax, [ebp+var_4]
CODE:00626139 call @System@@LStrCmp$qqrv
CODE:0062613E jnz short loc_626172
CODE:00626140 mov bl, 1
CODE:00626142 mov dl, 2
CODE:00626144 mov eax, esi
CODE:00626146 call sub_6271E4
CODE:0062614B mov edx, [ebp+var_8]
CODE:0062614E mov eax, esi
CODE:00626150 call sub_62683C
...
Под отладчиком в пошаговом режиме видны всякие этапы подготовки строк, какие-то действия с ними, и кульминация - вызов функции сравнения двух строк по адресу 00626139.

Серийный номер в отладчике
В окне регистров видно, что сравнивается наш левый серийник с какой-то красивой строкой "SFD2568741". Попробуем повторить регистрацию, но теперь вместо серийного номера используем строку из отладчика "SFD2568741". На этот раз никакой ругани нет, наоборот, программа радостно приняла серийник и поблагодарила:

Сообщение об успешной регистрации
В окне "About" также появились наши регистрационные данные, стартовое окно с предложением купить также исчезло:

Программа успешно зарегистрирована
Здравый смысл в очередной раз победил неуемную жадность разработчиков. Надеюсь, что и сама программа также будет использоваться в борьбе со всякими защищенными ресурсами.