Навигация по сайту:
Статья "Взлом Melody v1.52 тремя способами и написание Кейгена в Delphi":
<< Все статьи по взлому Версия для печати
Только для образовательных целей!
Автор:Bokiv [AHTeam]
Уровень:Для начинающих
Программа:Melody v1.52 - http://www.lighttek.com
Инструменты:OllyDebug v1.10, Delphi 6

[Начало]

Данная статья предназначнна для неопытного взломщика программ, и конечно-же - чисто в образовательных целях. Итак, приступим. Несколько слов о нашей жертве: Melody 1.52 - аудио плэйер. Поддерживает WAV, MIDI, MPEG, MOD форматы.

Читаем её Help:
Программа распространяется как Shareware. Это означает, что Вы можете свободно использовать ее в течение 30 дней. После этого срока, Вы должны либо зарегистрировать свою копию, либо удалить программу с компьютера. Стоимость регистрации через американские Shareware службы – 10$. Стоимость регистрации почтовым или банковским переводом по России 50 рублей. Так как после 30 дней программа перестала работать, было принято решение устранить это недоразумение!

Рассмотрим три способа, которые заставят работать эту программу всегда.

1) Патч (Patch)
2) Просмотр кода
3) Кейген


1. Патч (Patch)

Дословный перевод слова Patch – это Корректор. Будем корректировать! Для комфортной работы нам потребуется отладчик, я выбрал OllyDebug v1.10. Запускаем OllyDebug v1.10 (далее Оля), жмём F3, открываем файл melody.exe. После того как Оля сделает анализ кода, жмём: F10--->Search for--->All Referenced text strings. В появившемся окне с текстовыми строками, жмём PgUp (или просто прокрутим мышкой вверх). Моё внимание привлекли следующие строки:

0044CB05	MOV EDX,melody.0044CCAC	ASCII "usercode"
0044CB19 MOV EDX,melody.0044CCAC ASCII "usercode"
0044CB30 MOV EDX,melody.0044CCC0 ASCII "username"
0044CB8E MOV EDX,melody.0044CCD4 ASCII "Registered for "

Ставим курсор на строку №1 и жмём F2, строка должна выделиться красным. Т.е. отладчик остановит программу по адресу 044CB05. Теперь F9 (запуск программы), далее Shift+F9 пока не остановимся на нашей точке прерывания. Перед нами следующий код:

(Листинг 1)
0044CB05	BA ACCC4400	MOV EDX,melody.0044CCAC ASCII"usercode"	<-Мы тут
0044CB0A 8BC3 MOV EAX,EBX
0044CB0C E8 A39EFFFF CALL melody.004469B4
0044CB11 84C0 TEST AL,AL
0044CB13 0F84 92000000 JE melody.0044CBAB <-Если нет летим как демо

Схема команды: jz или je метка
Назначение: переход если флаг нуля установлен в единицу или условие равно

• jz (Jump if Zero) – переход если флаг нуля установлен.
• je (Jump if Equal) – переход, если равно.

Команды jz и je одинаковы. Например, дисассемблер может показывать je, а отладчик jz.

Схема команды: jnz или jne метка
Назначение: переход если флаг нуля не установлен в единицу или условие не равно

• jnz (Jump if not Zero) – переход если флаг нуля не установлен.
• jne (Jump if not Equal) – переход, если не равно.

И опять же команды jnz и jne одинаковы.

Программа проверяет, есть ли в реестре код с регистрацией, и если нет, то включает тридцатидневный счётчик, а если есть, то проверяет правильный ли он. Смотрим ниже строк так на 35-40:

(Листинг 2)
0044CB71	3B75 F4		CMP ESI,DWORD PTR SS:[EBP-C]		<-Сравниваем пароли
0044CB74 75 35 JNZ SHORT melody.0044CBAB <-Если код не правильный улетаем в демо.
0044CB76 A1 B8074500 MOV EAX,DWORD PTR DS:[4507B8] <-А отсюда идут те, кто купил программу.
0044CB7B 8B80 A4020000 MOV EAX,DWORD PTR DS:[EAX+2A4]
0044CB81 33D2 XOR EDX,EDX
0044CB83 E8 DC15FDFF CALL melody.0041E164
0044CB88 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
0044CB8B 8B4D F8 MOV ECX,DWORD PTR SS:[EBP-8]
0044CB8E BA D4CC4400 MOV EDX,melody.0044CCD4 ASCII "Registered for "

Так что тут получается, мы перепрыгиваем строку "Registered for " в двух случаях:

• Если нет пароля в реестре.
• Или если он неправильный.

Самый простой вариант (листинг 1) по адресу 0044CB13 исправить JE на JMP;
JE - Это условный переход,
JMP – безусловный.

Прыгать будем на третью строку (листинг 2), т.е. не проверяем ничего. Ставим курсор на строку 0044CB13 в Оле, жмём пробел и вместо JE 0044CBAB пишем JMP 0044CB76

0044CB13	0F84 92000000	JE melody.0044CBAB		<-Это оригинальный код.
0044CB13 EB 61 JMP SHORT melody.0044CB76 <-Это исправленный код.

Программа взломана, F9 и наслаждаемся проделанной работой. Для того чтобы сохранить сделанные нами изменения жмём:

F10--->Copy to executable--->All Modifications.

Появится окно с названием «Copy selection to executable file» нажимаем Copy All, появиться новое окно с кодом, в нём F10--->Save File. Сохраним как melody_.exe, чтобы не портить оригинал, он нам ещё пригодиться.

Если у вас всё получилось, и в About программы написано Registered For - то примите мои поздравления,программа ваша!


2. Просмотр кода

Приступим к подглядыванию кода, этот метод мне нравиться более всего, т.к. не надо создавать Patch, или писать KeyGen. Записал своё имя и код в текстовый файл и дело сделано.

Запускаем Олю, открываем нашу программу в ней, нажимаем F9 (запуск программы), далее Shift+F9 пока наша программа полностью не запуститься. Идём в окно о программе жмём «Register you copy now!». Пытаемся зарегистрироваться, я ввёл такие данные:

Name:	Bokiv
s/n: 111222333

Кнопка Ok, и вылетает сообщение: «Invalide registration name or code. Try again.» Типа неправильный пароль попробуйте снова, ну что ж попробуем!

Жмём F10--->Search for--->All Referenced text strings, крутим мышку вверх, пока не найдём текст «Invalide registration name or code. Try again». Ага, вот:

0044739D	MOV EDX,melody.004474A0	ASCII "\software\Lighttek\Melody"
004473BA MOV EDX,melody.004474C4 ASCII "username"
004473E9 MOV EDX,melody.004474D8 ASCII "usercode"
00447417 MOV EDX,melody.004474EC ASCII "Registered for "
00447456 MOV EAX,melody.00447504 ASCII "Invalide registration name or code. Try again."

Ставим бряк по F2 на адресе 00447456. Всё программа попалась, далее чуть-чуть терпения и пароль наш! Возвращаемся к нашей программе и регистрируемся снова. Жмём Ok и встаём тут:

00447454	JMP SHORT melody.00447460
00447456 MOV EAX,melody.00447504 "Invalide registration name or code. Try again."

Посмотрим что у нас выше, строк так на 35-40:

0044735D	BA 01000000	MOV EDX,1
00447362 8B4D F8 /MOV ECX,DWORD PTR SS:[EBP-8] <-Цикл создания кода по имени
00447365 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1]
0044736A 03F1 |ADD ESI,ECX
0044736C 42 |INC EDX
0044736D 48 |DEC EAX
0044736E 75 F2 \JNZ SHORT melody.00447362
00447370 8975 EC MOV DWORD PTR SS:[EBP-14],ESI
00447373 DB45 EC FILD DWORD PTR SS:[EBP-14]
00447376 E8 4DB6FBFF CALL melody.004029C8
0044737B 8BD0 MOV EDX,EAX
0044737D C1E0 07 SHL EAX,7
00447380 03C2 ADD EAX,EDX
00447382 8BF0 MOV ESI,EAX <-В EAX заветный пароль
00447384 3B75 FC CMP ESI,DWORD PTR SS:[EBP-4] <-Тут он сравнивается с нашим!
00447387 0F85 C9000000 JNZ melody.00447456 <-Переход на демо
0044738D B2 01 MOV DL,1

*** Обрезано… Здесь происходит запись вашего имени и пароля в реестр, если пароль правильный ***

00447454 EB 0A JMP SHORT melody.00447460
00447456 B8 04754400 MOV EAX,melody.00447504 : "Invalide registration name or code. Try again."

Ставим бряк по F2 на 00447382. Жмём F9 снова регистрируемся, прерываемся на 00447382 идём в правое окошко Registers(FPU) и дублекликаем по EAX:

Вылетает маленькое окошко с таким содержимым:

Modify EAX

Hexadecimal 0000FF7B
Signed 65403 <-Такой пароль генерируется на имя Bokiv
Unsigned 65403 <-

Теперь можно регистрироваться:

Name:	Bokiv
s/n: 65403

Спасибо за покупку программы!


3. Пишем Кейген

Кейген будем писать в Delphi, но на языке Ассемблер. Вернёмся к нашему циклу создания пароля, как туда добраться описанно в главе №2. В EAX уже храниться количество символов нашего имени (т.е. 5), это необходимо для цикла.

0044735D	BA 01000000	MOV EDX,1				<- Помещаем 1 в EDX
00447362 8B4D F8 /MOV ECX,DWORD PTR SS:[EBP-8] <- Помещаем наше имя из переменной в ECX
00447365 0FB64C11 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1] <- Помещаем в ECX hex значение буквы имени
0044736A 03F1 |ADD ESI,ECX <- Помещаем в ESI получившуюся цифру,
происходит сложение
0044736C 42 |INC EDX
0044736D 48 |DEC EAX <- Уменьшаем EAX на единицу
0044736E 75 F2 \JNZ SHORT melody.00447362 <- переход если флаг нуля не установлен
00447370 8975 EC MOV DWORD PTR SS:[EBP-14],ESI <- Результат копируем в переменную
00447373 DB45 EC FILD DWORD PTR SS:[EBP-14]
00447376 E8 4DB6FBFF CALL melody.004029C8
0044737B 8BD0 MOV EDX,EAX
0044737D C1E0 07 SHL EAX,7 <- преобразуем полученную сумму
00447380 03C2 ADD EAX,EDX <- складываем EAX и EDX и получаем
наш пароль!

Алгоритм создания пароля по имени:
B + o + k + i + v
66+111+107+105+118=507
SHL 507,7=64896
507+64896=65403

Код для написания Кейгена на Delphi:
Кидаем на форму два "Edit" и "Button".

function Generate(UserName:String; Len: Integer):String;
begin
asm
XOR ESI,ESI
MOV EDX,1
MOV EAX,[Len]

@@1:
MOV ECX,[UserName]
MOVZX ECX,[ECX+EDX-1]
ADD ESI,ECX
INC EDX
DEC EAX
JNZ @@1

MOV DWORD PTR SS:[Len],ESI
FILD DWORD PTR SS:[Len]
//---CALL melody.004029C8
PUSH EAX
FISTP DWORD PTR SS:[ESP]
WAIT
POP EAX
//-------------
MOV EDX,EAX
SHL EAX,7
ADD EAX,EDX

MOV [Len],EAX
XOR EAX,EAX
XOR ESI,ESI
end;
Result:=IntToStr(Len);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a: String;
l: Integer;
begin
a:=Edit1.Text;
if a<>''
then begin
l:=LenGth(a);
Edit2.Text:=(Generate(a,l));
end
else
MessageBox(Handle,'Enter name','Warning',$00001030)
end;

Далее для желающих создать полноценный Кейген размером менее 20 kb, привожу код написания на чистом WinApi, без ресурсов и библиотек!

Создаём текстовый файл, копируем всё туда, сохраняем и переименовываем его в «KeyGen.dpr». И открываем в Delphi и компилируем.

program KeyGen;

uses
windows, messages, commctrl; //Используемые модули

var
WinClass : TWndClass; //переменная класса TWndClass для создания главного окна
hInst, //хандлер приложения
Handle, //локальный хандлер
Com1, //TEdit
Com2, //TEdit
Com3, //TMemo
Com4, //TStaticText
Com5, //TStaticText
Com6, //TEdit
Com7, //TEdit
Com8, //TStaticText
Com9, //TButton
hFont, //хандлер шрифта
hFont1, //хандлер шрифта
hFontTahoma : HWND; //хандлер шрифта
Msg : TMSG; //сообщение
Edit1Text,
Edit2Text,
Memo1Text,
Edit3Text,
Edit4Text: String;

const
Edit1 = 1; //TEdit
Edit2 = 2; //TEdit
Memo1 = 3; //TMemo
Label1 = 4; //TStaticText
Label2 = 5; //TStaticText
Edit3 = 6; //TEdit
Edit4 = 7; //TEdit
Label3 = 8; //TStaticText
Button1 = 9; //TButton

function IntInStr(Value : Integer): String;
asm
XOR ECX, ECX
PUSH ECX
ADD ESP, -0Ch

PUSH EBX
LEA EBX, [ESP + 15 + 4]
PUSH EDX
CMP EAX, ECX
PUSHFD
JGE @@1
NEG EAX
@@1:
MOV CL, 10

@@2:
DEC EBX
CDQ
IDIV ECX
ADD DL, 30h
MOV [EBX], DL
TEST EAX, EAX
JNZ @@2

POPFD
JGE @@3

DEC EBX
MOV byte ptr [EBX], '-'
@@3:
POP EAX
MOV EDX, EBX
CALL System.@LStrFromPChar

POP EBX
ADD ESP, 10h
end;

procedure AppInitialize;
begin
Edit1Text := 'Melody v1.52';
Edit2Text := 'Bokiv';
Memo1Text := 'Mail: Bokiv@yandex.ru' +#13#10+
'http://bokiv.narod.ru' +#13#10+
'Пишите письма!' +#13#10+
'г. Саяногорск!';
Edit3Text := 'Bokiv';
Edit4Text := '';
end;

procedure Form1Create;
begin
//
end;

procedure Edit3Change;
begin
//
end;

function GetEdit3Text: String; //Edit3.Text
var
OldInfo : array[0..65534] of Char;
begin
GetDlgItemText(Handle, Edit3, PChar(@OldInfo), 1000);
Result:=OldInfo;
end;

procedure AddEdit4(Text: String); //Edit4.Text:=
begin
SetDlgItemText(Handle, Edit4, PChar(Text));
end;

function Generate(UserName:String; Len: Integer):String;
begin
asm
XOR ESI,ESI
MOV EDX,1
MOV EAX,[Len]

@@1:
MOV ECX,[UserName]
MOVZX ECX,[ECX+EDX-1]
ADD ESI,ECX
INC EDX
DEC EAX
JNZ @@1

MOV DWORD PTR SS:[Len],ESI
FILD DWORD PTR SS:[Len]
//---CALL melody.004029C8
PUSH EAX
FISTP DWORD PTR SS:[ESP]
WAIT
POP EAX
//-------------
MOV EDX,EAX
SHL EAX,7
ADD EAX,EDX

MOV [Len],EAX
XOR EAX,EAX
XOR ESI,ESI
end;
Result:=IntInStr(Len);
end;

procedure Button1Click;
var
a: String;
l: Integer;
begin
a:=GetEdit3Text;
if a<>'' //Если А неравно пустоте
then begin
l:=LenGth(a);
AddEdit4(Generate(a,l));
end
else
MessageBox(Handle,'Ведите ваше имя','Warning',$00001030)
end;

procedure Form1Destroy;
begin
DeleteObject(hFont); //удаление шрифта
DeleteObject(hFont1); //удаление шрифта
DeleteObject(hFontTahoma); //удаление шрифта
UnRegisterClass('Sample Class', hInst); //удаление окна
ExitProcess(hInst); //закрытие программы
end;

function WindowProc(hwnd, msg, wparam, lparam: longint): longint; stdcall; //обработчик сообщений
begin
Result := DefWindowProc(hwnd, msg, wparam, lparam);
case Msg of
WM_COMMAND:
case LoWord(wParam) of
Button1 :
if HiWord(wParam) = bn_Clicked then Button1Click;
Edit3 :
if HiWord(wParam) = EN_CHANGE then Edit3Change;
end;
WM_CREATE: Form1Create;
WM_DESTROY: Form1Destroy;
end;
end;

begin
AppInitialize;
hInst := GetModuleHandle(nil);
with WinClass do
begin
Style := CS_PARENTDC; //стиль класса главного окна
hIcon := LoadIcon(hInstance, IDI_APPLICATION); //иконка программы
lpfnWndProc := @WindowProc; //назначение обработчика сообщений
hInstance := hInst;
hbrBackground := COLOR_BTNFACE + 1; //цвет окна
lpszClassName := 'Sample Class'; //класс окна
hCursor := LoadCursor(0, IDC_ARROW); //активный курсор
end;
InitCommonControls;
RegisterClass(WinClass); //регистрация класса в системе

{Создание главного окна программы}
Handle := CreateWindowEx(0, 'Sample Class', 'KeyGen',
WS_OVERLAPPED or WS_SYSMENU or
WS_VISIBLE,
230,//слева
130,//сверху
322,//Ширина формы
266,//Высота формы
0, 0,
hInst, nil);

{Создание шрифта}
hFont := CreateFont(
-12, 0, 0, 0, 0, 0, 0, 0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH or FF_DONTCARE, 'MS Sans Serif');

hFont1 := CreateFont(14, 0, 0, 0, 900, 0, 0, 0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH, 'MS Sans Serif');
hFontTahoma := CreateFont(13, 0, 0, 0, 0, 0, 0, 0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH, 'Tahoma');

Com1:=CreateWindowEx(
WS_EX_CLIENTEDGE,
'Edit',
PChar(Edit1Text),
WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE or ES_READONLY,
60,7,250,21,Handle, Edit1, hInst,nil);
SendMessage(Com1,WM_SETFONT,hFont,0);

Com2:=CreateWindowEx(
WS_EX_CLIENTEDGE,
'Edit',
PChar(Edit2Text),
WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE or ES_READONLY,
60,32,250,21,Handle, Edit2, hInst,nil);
SendMessage(Com2,WM_SETFONT,hFont1,0);

Com3:=CreateWindowEx(
WS_EX_CLIENTEDGE,
'Edit',
PChar(Memo1Text),
WS_CHILD or ES_MULTILINE or ES_WANTRETURN or ES_AUTOVSCROLL or WS_VSCROLL
or WS_VISIBLE or ES_READONLY, 5,57,305,71,Handle, Memo1, hInst,nil);
SendMessage(Com3,WM_SETFONT,hFontTahoma,0);

Com4:=CreateWindow(
'Static',
'Program:' ,
WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE,
5,9,46,17,Handle, Label1, hInst,nil);
SendMessage(Com4,WM_SETFONT,hFont,0);

Com5:=CreateWindow(
'Static',
'Author:' ,
WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE,
5,34,38,17,Handle, Label2, hInst,nil);
SendMessage(Com5,WM_SETFONT,hFont,0);

Com6:=CreateWindowEx(
WS_EX_CLIENTEDGE,
'Edit',
PChar(Edit3Text),
WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE,
5,151,305,21,Handle, Edit3, hInst,nil);
SendMessage(Com6,WM_SETFONT,hFont,0);

Com7:=CreateWindowEx(
WS_EX_CLIENTEDGE,
'Edit',
PChar(Edit4Text),
WS_CHILD or ES_AUTOHSCROLL or WS_VISIBLE or ES_READONLY,
5,176,305,21,Handle, Edit4, hInst,nil);
SendMessage(Com7,WM_SETFONT,hFont,0);

Com8:=CreateWindow(
'Static',
'Enter name:' ,
WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE,
5,133,90,17,Handle, Label3, hInst,nil);
SendMessage(Com8,WM_SETFONT,hFont1,0);

Com9 := CreateWindow(
'Button',
'Generate',
WS_CHILD or BS_TEXT or WS_VISIBLE,
5, 203, 305, 24,Handle, Button1, hInst, nil);
SendMessage(Com9,WM_SETFONT,hFont,0);

//Цикл сбора сообщений
while(GetMessage(Msg, Handle, 0, 0)) do
begin
TranslateMessage(Msg); //прием сообщений
DispatchMessage(Msg); //удаление сообщений из очереди
end;

end.

Послесловие.

Спасибо, всем кто прочитал этот мануал. Критика пожелания и замечания будут учитываться при написании последующих статей.

Автор: Bokiv [AHTeam]
<< Все статьи по взлому Версия для печати
Комментарии читателей к статье "Взлом Melody v1.52 тремя способами и написание Кейгена в Delphi":

11.02.2014 13:01
Нашел для себя новое по освоению ОЛЛИДБГ. Благодарю.

17.03.2013 14:50
спасибо за статью :)

07.01.2009 01:01
очень хорошая статья - спасибо !)

18.12.2008 12:17
Спасибо! Но один вопрос как взламывать проги которые сами генерируют номер, а по нему нужно ввести другой код. И еще у меня есть одна прога которая при запуске сразу просит ввести код, как я описал выше. Как быть здесь?

03.03.2008 12:07
2 марьё
Дело гришь - мужик,были бы статьи,яб афтора наверно вообще разцеловал ))))))

25.09.2007 00:49
кул) статья просто супер!)
я ломал похожие программы, но все же мне очень помогла статья:)

08.08.2007 17:39
Спасибо, но не очень понятен ход мысли при определении например строчки с паролем:
"MOV ESI,EAX <-В EAX заветный пароль". И в других местах тоже. Статья ведь предназначена для совсем неопытных. Но спасибо большое за статью- в целом очень полезную.

05.11.2006 17:57
Конечно огромное спасибо автору !!! Ведь благодаря этой статье я смог не только увидеть, но попробовать собственными руками "зарегистрировать" чью-то программу !! Приятно конечно сознавать что получилось, но хотелось бы лучше понять то что делаешь, да и программы по-интересней !! На-пример: как "зарегистрировать" Alcohol_120% и наконец-то поставить на место эту долбанную StarForce ?!!
Добавить свой комментарий:
Ваше имя: Текст сообщения:
Ваш E-Mail:
Введите код:   

ALIEN Hack Team - © 2003-2017
Лицензионное соглашение