
Скриншот программы Teleport Pro
Teleport Pro - один из лучших оффлайновых браузеров, позволяющих целиком выкачивать сайты с сохранением всех внутренних ссылок и структуры. Также может сохранять отдельные типы файлов, например, только картинки нужного размера. Кроме версии Pro есть еще и другие версии программы, но разница между ними только в цене, в максимальном количестве одиночных страниц в проекте, и расширенные версии доступны для скачивания только после их покупки. Но обычно хватает версии Pro, которую можно свободно скачать с офсайта. Недостаток у всех версий один - они все хотят денег.
Запускаем программу, открываем окно регистрации, вводим любые левые данные, получаем отлуп: "We're sorry! The registration number you entered appears to be invalid". Нехорошая строка находится дизассемблером:
.data:0049112C aWeReSorryTheRe db 'We',27h,'re sorry! The registration number'
.data:0049112C db ' you entered appears to b...'
.data:0049112C ; DATA XREF: .data:off_48C310
На нее идет ссылка с адреса 48C310:
Code (Assembler) : Убрать нумерацию
.data:0048C310 ; LPCSTR off_48C310
; DATA XREF: sub_42EC7A:loc_42ED05
.data:0048C310 off_48C310 dd offset aWeReSorryTheRe
.data:0048C310 ; "We're sorry! The registration number y"...
А на этот указатель ссылка идет уже из секции кода:
...
.text:0042ECB3 cmp esi, ebx
.text:0042ECB5 mov ebp, offset aUser ; "User"
.text:0042ECBA jz short loc_42ED15
.text:0042ECBC push dword ptr [edi+0D5h] ; Str
; Вызвать функцию генерации серийного номера на основании введенного имени
.text:0042ECC2 call sub_42F675
; Сгенерированный серийник совпадает с введенным?
.text:0042ECC7 cmp esi, eax
.text:0042ECC9 pop ecx
.text:0042ECCA jnz short loc_42ECDB
.text:0042ECCC push ebx ; int
.text:0042ECCD push ebx ; uType
; Сообщение об успешной регистрации
.text:0042ECCE push off_48C290 ; lpText
.text:0042ECD4 call sub_4542AB
.text:0042ECD9 jmp short loc_42ED50
.text:0042ECDB ; --------------------------------------------
.text:0042ECDB
.text:0042ECDB loc_42ECDB:
.text:0042ECDB mov edi, [edi+0D5h]
.text:0042ECE1 cmp [edi-8], ebx
.text:0042ECE4 jnz short loc_42ECF0
.text:0042ECE6 push ebx
.text:0042ECE7 push ebx
.text:0042ECE8 push off_48C308
.text:0042ECEE jmp short loc_42ED0B
.text:0042ECF0 ; ----------------------------------------
.text:0042ECF0
.text:0042ECF0 loc_42ECF0:
.text:0042ECF0 push edi ; Str
; Вызвать функцию проверки введенного серийного номера
.text:0042ECF1 call sub_42F675
.text:0042ECF6 pop ecx
; Если функция вернула 0, то введено слишком короткое имя, иначе
; введены неправильные регистрационные данные
.text:0042ECF7 test eax, eax
.text:0042ECF9 push ebx ; int
.text:0042ECFA push ebx ; uType
.text:0042ECFB jnz short loc_42ED05
; Сообщение о слишком коротком введенном имени
.text:0042ECFD push off_48C30C
.text:0042ED03 jmp short loc_42ED0B
.text:0042ED05 ; -----------------------------------------------------
.text:0042ED05
.text:0042ED05 loc_42ED05:
; Сообщение об ошибке
.text:0042ED05 push off_48C310 ; lpText
.text:0042ED0B
.text:0042ED0B loc_42ED0B:
.text:0042ED0B call sub_4542AB
.text:0042ED10 jmp loc_42EDED
...
Теперь посмотрим процедуру регистрации. Сразу скажу, что просто пропатчить ее не получится, потому что программа проверяет целостность исполняемого файла.
.text:0042F675 push edi
.text:0042F676 mov edi, [esp+4+Str]
.text:0042F67A test edi, edi
.text:0042F67C jz short loc_42F687
.text:0042F67E push edi ; Str
; Получить длину введенного имени
.text:0042F67F call _strlen
.text:0042F684 pop ecx
.text:0042F685 jmp short loc_42F689
.text:0042F687 ; -------------------------------------------------------
.text:0042F687
.text:0042F687 loc_42F687:
.text:0042F687 xor eax, eax
.text:0042F689
.text:0042F689 loc_42F689:
; Длина имени должна быть не менее 5 символов
.text:0042F689 cmp eax, 5
.text:0042F68C jnb short loc_42F692
.text:0042F68E xor eax, eax
.text:0042F690 pop edi
.text:0042F691 retn
.text:0042F692 ; -------------------------------------------------------
.text:0042F692
.text:0042F692 loc_42F692:
.text:0042F692 push ebx
.text:0042F693 push esi
; Начальная константа для генерации серийного номера
.text:0042F694 mov esi, 5DFEE4A4h
.text:0042F699 xor ebx, ebx
.text:0042F69B
.text:0042F69B loc_42F69B:
; Регистр EDI - указатель на текущее положение "кадра" в имени
.text:0042F69B test edi, edi
.text:0042F69D jz short loc_42F6A8
.text:0042F69F push edi ; Str
.text:0042F6A0 call _strlen
.text:0042F6A5 pop ecx
.text:0042F6A6 jmp short loc_42F6AA
.text:0042F6A8 ; -------------------------------------------------------
.text:0042F6A8
.text:0042F6A8 loc_42F6A8:
.text:0042F6A8 xor eax, eax
.text:0042F6AA
.text:0042F6AA loc_42F6AA:
.text:0042F6AA add eax, 0FFFFFFFCh
; "Кадр" за 4 символа до конца имени?
.text:0042F6AD cmp ebx, eax
.text:0042F6AF jnb short loc_42F6BD
; ПоXORить константу с 4 символами имени в "кадре"
.text:0042F6B1 xor esi, [ebx+edi]
.text:0042F6B4 test bl, 40h
.text:0042F6B7 jz short loc_42F6BA
.text:0042F6B9 inc ebx
.text:0042F6BA
.text:0042F6BA loc_42F6BA:
.text:0042F6BA inc ebx
.text:0042F6BB jmp short loc_42F69B
.text:0042F6BD ; -------------------------------------------------------
.text:0042F6BD
.text:0042F6BD loc_42F6BD:
; В регистре EAX правильный серийный номер для введенного имени
; Переведите его в десятичное число и можно повторить регистрацию уже с этим
; правильным серийником
.text:0042F6BD mov eax, esi
.text:0042F6BF pop esi
.text:0042F6C0 pop ebx
.text:0042F6C1 pop edi
.text:0042F6C2 retn
.text:0042F6C2 sub_42F675 endp
Для большей наглядности лучше пройти функцию генерации в отладчике. Теперь у нас есть алгоритм генерации серийного номера. Регистрационное имя должно быть не короче 5 символов, хотя в сообщении программы не менее 6 символов. Для генерации серийного номера сперва берется константа 5DFEE4A4h, а затем XORится поочередно с каждыми 4 байтами регистрационного имени, после каждой операции XOR 4-байтовый "кадр" в регистрационном имени сдвигается на один символ вправо, пока длина оставшегося "хвоста" не менее 4 символов. Итоговое число переводится в десятичный вид, это и есть правильный серийный номер. Если даже после разбора алгоритма затрудняетесь написать рабочий кейген, то можете ограничиться фишингом серийников из процедуры генерации серийного номера.
А теперь поковыряемся в реестре в ветке, где хранятся данные о регистрации. В программе полей ввода только два: имя и номер, а в реестр записывается еще один пустой ключ Company:
[HKEY_LOCAL_MACHINE\SOFTWARE\Tennyson Maxwell\Teleport Pro]
"Name"="ManHunter"
"Company"=""
"Registration"=dword:1fb7b8db
Попробуем его отредактировать и сохранить изменения. Получается вполне симпатичная картина:

Программа успешно зарегистрирована
Теперь для регистрации можно использовать следующий reg-файл:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Tennyson Maxwell\Teleport Pro]
"Name"="ManHunter"
"Company"="Perm Crack Laboratory"
"Registration"=dword:1fb7b8db
Все поля, естественно, могут быть с вашими регистрационными данными. Вот такая защита. Автор не меняет алгоритм регистрации уже много лет, поэтому есть вероятность, что и в следующих версиях также ничего не изменится.