|
KeyGen для Enchansed NotePad
OllyDbg
v1.10 [1087 KB-ZIP] http://biocyborg.narod.ru/soft/OllyDbg110.zip OllyPlugins [420
KB-ZIP] http://biocyborg.narod.ru/soft/ollyplugins.zip W32Dasm v9.0b
[315 KB-ZIP] http://biocyborg.narod.ru/W32dsm9b.zip
Enchansed NotePad [30 KB-ZIP] http://biocyborg.narod.ru/soft/enotepad.zip Мозги
[43 KB-ZIP] http://biocyborg.narod.ru/rev/mozgi.zip
Enchansed NotePad чем-то напоминает виндовый Блокнот, только менее функциональная и не бесплатная. Для регистрации требуется ввести имя пользователя и регистрационный код. При неверном рег. номере показывает сообщение: “Check serial number or user name”.
На GetDlgItemTextA и GetWindowTextA программа не ловится, зато hmemcpy срабатывает безупречно и Вы без проблем доберётесь до места генерации правильного серийного номера и его сравнения с кодом, введённым пользователем.
Но мы поступим иначе. Дизассемблируем программу в Win32dasm и найдем сообщение “Check serial number or user
name”:
* Reference To: KERNEL32.lstrcmpiA, Ord:026Ch
|
:00403449 FF154CE34000 Call dword ptr [0040E34C]
:0040344F 85C0 test eax, eax
:00403451 741C je 0040346F
:00403453 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Invalid data"
|
:00403455 6834B54000 push 0040B534
* Possible StringData Ref from Data Obj ->"Check serial number or user name"
|
:0040345A 6810B54000 push 0040B510
:0040345F FF7604 push [esi+04]
Здесь всё должно быть ясно: в зависимости от значения eax появится сообщение о неправильном серийнике, или регистрационные данные будут сохранены в реестре для проверки при следующем запуске программы.
Поэтому мы должны найти место, где программа устанавливает значение регистра eax.
В Win32Dasm прокрутим листинг вверх примерно на один экран и увидим вызов подозрительной процедуры:
* Reference To: USER32.SendMessageA, Ord:01C6h
|
:00403405 FF1554E44000 Call dword ptr [0040E454]
:0040340B 8D4DF8 lea ecx, dword ptr [ebp-08]
:0040340E 8D55A8 lea edx, dword ptr [ebp-58]
:00403411 51 push ecx
:00403412 52 push edx
:00403413 E854040000 call 0040386C
:00403418 83C408 add esp, 00000008
:0040341B 8D55D4 lea edx, dword ptr [ebp-2C]
:0040341E FF75F8 push [ebp-08]
Если перейти по адресу 40386С то можно увидеть, что процедура вызывается два раза и производит интересные действия, поэтому стоит изучить её в отладчике.
Поставим брейкпоинт на вызов процедуры по адресу 40386С и попробуем зарегистрироваться. (Запускаем NOTEPAD.EXE, жмём кнопку “Register…” и вводим регистрационную инфрмацию. В отладчике устанавливаем breakpoint командой bp 40386С (я использовал OllyDbg с плагином
CommandBar). В окне регистрации жмём “OK”) . Бряк сработал
:):
0040386C 53 PUSH EBX
0040386D 56 PUSH ESI
0040386E 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+C];помещает в ESI имя
00403872 57 PUSH EDI
00403873 BF 889CDF03 MOV EDI,3DF9C88 ;помещает в EDI константу 3DF9C88h
00403878 803E 00 CMP BYTE PTR DS:[ESI],0
0040387B 74 21 JE SHORT NOTEPAD.0040389E
0040387D 8A06 MOV AL,BYTE PTR DS:[ESI] ;берём символ из UserName
0040387F 3C 20 CMP AL,20 ;если это пробел
00403881 74 15 JE SHORT NOTEPAD.00403898 ;его не обрабатываем и берём следующий
00403883 0FBEC0 MOVSX EAX,AL
00403886 8BDF MOV EBX,EDI ;в EBX значение EDI(сначала EDI=3DF9C88h)
00403888 50 PUSH EAX
00403889 C1EB 18 SHR EBX,18 ;логический сдвиг вправо на 24 бинарных разряда,
;т.е. 3 байта (1816=2410)
0040388C FF15 A4E44000 CALL DWORD PTR DS:[<&USER32.CharUpperA>] ;CharUpperA
00403892 0FAFC7 IMUL EAX,EDI ;умножаем EAX на EDI, результат в EAX
00403895 8D3C03 LEA EDI,DWORD PTR DS:[EBX+EAX];суммируем EBX и EAX, результат помещаем в EDI
00403898 46 INC ESI ;отбрасываем из имени обработанный символ
00403899 803E 00 CMP BYTE PTR DS:[ESI],0 ;все символы имени обработаны?
0040389C 75 DF JNZ SHORT NOTEPAD.0040387D ;если нет, повторяем цикл
0040389E 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]
004038A2 8938 MOV DWORD PTR DS:[EAX],EDI
004038A4 5F POP EDI
004038A5 5E POP ESI
004038A6 5B POP EBX
004038A7 C3 RETN ;выход из процедуры генерации кода
Алгоритм генерации ключа состоит в следующем: берём число X (в начале это константа 3DF9C88h), получаем из него логическим сдвигом вправо на
3 байта число Y, которое складываем с произведением X на ASCII-код символа имени (если символ - строчная буква, он преобразуется в прописную функцией CharUpperA). Результат сложения присваиваем иксу, берём
следующий символ из UserName и повторяем всё заново
(кстати, имя пользователя не должно
превышать 30 символов). Пробелы не обрабатываются. В конечном итоге регистрационный код окажется в X.
Регистрационная информация
сохраняется в реестре: HKEY_LOCAL_MACHINE\Software\Chistyacov Software\EnhancedNotepad\1.0
Теперь, когда нам известен алгоритм генерации ключа, мы можем написать KeyGen. Писать будем на Delphi с использованием
KOL&MCK ( http://bonanzas.rinet.ru
), так как эта библиотека позволяет значительно уменьшить размер exe-шника (у меня размер генератора ключей получился 16,5 кб).
procedure TForm1.Button1Click(Sender: PObj);
var
i,m,n,t,y: integer;
serial:string;
b:char;
begin
if Length(Editbox1.Text)>30 then
editbox2.Text:='Имя пользователя должно быть менее 30 символов'
else
begin
m:=$3df9c88; // значок "$" показывает, что число в шестнадцатеричном формате
For I:=1 To Length(Editbox1.Text) Do
begin
b:=editbox1.text[i]; //считываем очередной символ
b:=upcase(b); //преобразуем строчные буквы в прописные
n:=ord(b); //ord возвращает ascii-код символа
if n<>32 then //пробелы пропускаем (32-это ASCII-код пробела)
begin
y:=m shr $18;
t:=m*n;
m:=t+y;
end;
end;
serial:=int2hex(m,0); //преобразуем результат в шестнадцатеричный формат
editbox2.Text:=serial; //выводим полученный рег. номер
end;
end;
При написании кейгенов на
Делфи можно использовать встроенный
ассемблер.
procedure TForm1.Button1Click(Sender: PObj);
var
j,n: dword;
i: integer;
serial: string;
b: char;
begin
if Length(Editbox1.Text)>30 then
editbox2.Text:='Имя пользователя должно быть менее 30 символов'
else
begin
j:=$3df9c88; // значок "$" показывает, что число в шестнадцатеричном формате
For I:=1 To Length(Editbox1.Text) Do
begin
b:=editbox1.text[i]; //считываем очередной символ
b:=upcase(b); //преобразуем строчные буквы в прописные
n:=ord(b); //ord возвращает ascii-код символа
if n<>32 then //пробелы пропускаем (32-это ASCII-код пробела)
begin
asm
pushad
mov eax, n
mov ebx, j
shr ebx, 18h
imul eax, j
add eax, ebx
mov j, eax
popad
end;
end;
end;
serial:=int2hex(j,0);
editbox2.Text:=serial;
end;
end;
Исходники можно скачать
здесь http://biocyborg.narod.ru/rev/epkg.zip
Информация приведена
исключительно для ознакомления.
Применение данной информации в
незаконных целях категорически
запрещается.
© BioCyborG, 2003
|