
Скриншот программы eXeScope
eXeScope - одна из моих любимых программ для работы с ресурсами исполняемых файлов. Последняя версия 6.50, давно не обновлялась, но на работоспособность это никак не влияет. eXeScope предоставляет широкий выбор инструментов как для начинающего исследователя, так и для профессиональных реверсеров: вывод информации о заголовке, функциях импорта, просмотр различных ресурсов с возможностью их редактирования, импорта и экспорта. А также eXeScope сам может оказаться неплохим объектом для исследования, потому что программа шароварная с двухнедельным испытательным периодом.
Качаем дистрибутив (офсайт на японском языке, без переводчиков там все равно делать нечего), распаковываем, запускаем. Попытаемся зарегистрировать программу с любыми левыми данными, получаем сообщение "Invalid ID or Name". Файл ничем не упакован, строка легко находится.

Нехорошая строка найдена
Посмотрим в дизассемблере код, который на нее ссылается.
...
CODE:004C2AB0 mov edx, ds:off_4CFE4C
CODE:004C2AB6 mov edx, [edx]
CODE:004C2AB8 mov eax, ds:off_4CFC54
CODE:004C2ABD mov eax, [eax]
; Вызвать процедуру проверки регистрационных данных
CODE:004C2ABF call sub_4CBF7C
CODE:004C2AC4 test al, al
; Если она вернула AL=0, то регистрация неправильная
CODE:004C2AC6 jz loc_4C2B59
CODE:004C2ACC mov eax, ds:off_4CFEE8
CODE:004C2AD1 mov eax, [eax]
CODE:004C2AD3 call sub_404C50
CODE:004C2AD8 test eax, eax
CODE:004C2ADA jle short loc_4C2B59
; Сохранить регистрационные данные
CODE:004C2ADC lea edx, [ebp+var_10]
CODE:004C2ADF mov eax, ds:off_4CFEFC
CODE:004C2AE4 mov eax, [eax]
CODE:004C2AE6 call sub_4926FC
CODE:004C2AEB mov eax, [ebp+var_10]
CODE:004C2AEE lea ecx, [ebp+var_C]
CODE:004C2AF1 mov edx, offset dword_4C2BB8
CODE:004C2AF6 call sub_409B20
CODE:004C2AFB mov ecx, [ebp+var_C]
CODE:004C2AFE mov dl, 1
CODE:004C2B00 mov eax, off_43BE2C
CODE:004C2B05 call sub_43BEDC
CODE:004C2B0A mov esi, eax
CODE:004C2B0C mov eax, ds:off_4CFEE8
CODE:004C2B11 mov eax, [eax]
CODE:004C2B13 push eax
CODE:004C2B14 mov ecx, offset aName_1 ; "Name"
CODE:004C2B19 mov edx, offset dword_4C2BD8
CODE:004C2B1E mov eax, esi
CODE:004C2B20 mov edi, [eax]
CODE:004C2B22 call dword ptr [edi+4]
CODE:004C2B25 mov eax, ds:off_4CFE4C
CODE:004C2B2A mov eax, [eax]
CODE:004C2B2C push eax
CODE:004C2B2D mov edx, offset dword_4C2BD8
CODE:004C2B32 mov ecx, offset dword_4C2BE4
CODE:004C2B37 mov eax, esi
CODE:004C2B39 mov edi, [eax]
CODE:004C2B3B call dword ptr [edi+4]
CODE:004C2B3E mov eax, esi
CODE:004C2B40 call sub_403BE0
CODE:004C2B45 mov eax, ds:off_4CFC5C
CODE:004C2B4A mov byte ptr [eax], 1
CODE:004C2B4D mov dword ptr [ebx+24Ch], 1
CODE:004C2B57 jmp short loc_4C2B79
CODE:004C2B59 ; ----------------------------------------------
CODE:004C2B59 loc_4C2B59:
; Сообщение о неправильной регистрации
CODE:004C2B59 push 0
CODE:004C2B5B lea edx, [ebp+var_14]
CODE:004C2B5E mov eax, offset aInvalidIdOrNam
; "Invalid ID or Name"...
CODE:004C2B63 call sub_4C38D0
CODE:004C2B68 mov eax, [ebp+var_14]
CODE:004C2B6B mov cx, word_4C2C20
CODE:004C2B72 mov dl, 1
CODE:004C2B74 call sub_4376A8
...
Теперь пройдем функцию проверки регистрации под отладчиком:
...
CODE:004CBF9A xor ebx, ebx
CODE:004CBF9C mov eax, [ebp+var_4]
; Первая проверка - длина строки должна быть 10 символов
CODE:004CBF9F call sub_404C50
CODE:004CBFA4 cmp eax, 0Ah
CODE:004CBFA7 jnz short loc_4CC005
После первой проверки мы знаем длину серийного номера - 10 символов.
; Вторая проверка - серийный код должен начинаться с "A1910" или "A1423"
CODE:004CBFA9 mov edx, [ebp+var_4]
CODE:004CBFAC mov eax, offset aA1910 ; "A1910"
CODE:004CBFB1 call sub_404F94
CODE:004CBFB6 dec eax
CODE:004CBFB7 jz short loc_4CBFC9
CODE:004CBFB9 mov edx, [ebp+var_4]
CODE:004CBFBC mov eax, offset aA1423 ; "A1423"
CODE:004CBFC1 call sub_404F94
CODE:004CBFC6 dec eax
CODE:004CBFC7 jnz short loc_4CC005
Следующая проверка - в программе захардкодены две строки, с которых может начинаться правильный серийный номер.
; Следующая проверка - символы серийного номера, начиная со второго,
; должны быть цифрами
CODE:004CBFC9 mov eax, 2
CODE:004CBFCE loc_4CBFCE:
CODE:004CBFCE mov edx, [ebp+var_4]
CODE:004CBFD1 mov dl, [edx+eax-1]
CODE:004CBFD5 cmp dl, 30h
CODE:004CBFD8 jb short loc_4CC005
CODE:004CBFDA cmp dl, 39h
CODE:004CBFDD ja short loc_4CC005
CODE:004CBFDF inc eax
CODE:004CBFE0 cmp eax, 0Bh
CODE:004CBFE3 jnz short loc_4CBFCE
На следующем этапе проверяется, чтобы все символы серийника, начиная со второго, были цифрами. Это не совсем логично, ведь после предыдущей проверки как минимум 4 символа уже гарантированно цифры.
CODE:004CBFE5 mov eax, [ebp+var_4]
; Взять предпоследний символ серийника
CODE:004CBFE8 movzx eax, byte ptr [eax+8]
CODE:004CBFEC mov edx, [ebp+var_4]
; Взять последний символ серийника
CODE:004CBFEF movzx edx, byte ptr [edx+9]
; Сумма ASCII-кодов символов
CODE:004CBFF3 add eax, edx
; Поделить на 10
CODE:004CBFF5 mov ecx, 0Ah
CODE:004CBFFA xor edx, edx
CODE:004CBFFC div ecx
; Остаток от деления должен быть = 4
CODE:004CBFFE cmp edx, 4
CODE:004CC001 jnz short loc_4CC005
...
И в заключительной проверке сумма ASCII-кодов последнего и предпоследнего символов делится на 10, остаток должен быть равен 4. Остальные символы серийника нигде не проверяются и могут быть любыми цифрами, регистрационное имя также нигде не учитывается и не проверяется. Под эту схему, например, подходит серийный номер "A191000044". Попробуем его ввести в окно регистрации, никаких сообщений об ошибке не появляется. В дальнейшем в окне регистрации поле ввода блокируется и сообщается, что программа уже зарегистрирована.

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