Кейген для 3dflyind v2.28

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: Fess

imsho-imho-imo-ho-ho-ho-hey-yo-hey-ho-hip-hop-hooray…

Target: 3dflyind v2.28

Tools:

Some brains

Soft-Ice

Win32Dasm 8.93

RegMon 4.13

Delphi 3 или выше

Все, кроме мозгов и Delphi, можно найти на www.exetools.com

Вступление

Как это начиналось:

Я тут вспомнил, что уже месяц не пишу тьюториалов. И решил тряхнуть стариной и вот он… Накачал я софта с Инета среди прочего мусора была и эта прога. К глубокому моему глубокому сожалению, аддоны в незарегеной версии использовать было нельзя, а я накачал и их тоже. В таких случаях для простых смертных есть два пути: Заплатить или Забыть(Забить). Но мы не принадлежим к ним, у нас есть свой особенный путь — Исследовать эту программу и зарегиться нахаляву. Кстати, в проге предусмотрено несколько видов регистрации: Deluxe, Basic, Test. За самую лучшую, просят всего ничаво 29.90 американских вафель. У меня таких денег отродясь не бывало. На мою степендию эту прогу можно купить, покопив денюшки месяцков с 13.

Что за прога:

Какой-то хитрый скринсавер, типа эмуляция полета самолета. Им можно даже порулить, но полчается фигово. Вообщем, за такие деньги можно было сделать и получше, но у них там за бугром свои правила. В архиве занимает ~ 1700 Kb. Я тут поглядел на системные требования и матерь божья: Display Card: Direct3D compatible 3D accelerated card with 16M display memory CPU: Pentium II 400 or higher with 64M system memory Короче обнаглели в конец. Пользоваться или не юзать решать вам, а мы приступаем…

Начало

Сегодня я поставил перед собой цель не только вместе с вами написать кейген, но и научить вам крэкерскому мышлению и методу действий. Если у меня это получиться, значит я старался не зря.

Посмотрев, в таблицу секций я прикинул, что это скорее всего сбацано на С . Как это я определил? У С стандартно первый раздел называется .text. Я видел, только одну прогу на Делфи, у которой первый раздел назывался бы так же. Если не верите можете проверить, я проверил это оказался Visual C 6.0. А я что говорил? делаем вывод, что нам повезло — у С обычно очень хороший и чистый код.

Для начала кинем ее в Win32Dasm и посмотрим на результат. Все прошло нормально, значит нам повезло в двойне — прога ничем не запакована. Лезем в секцию строк и ищем, что-нибудь интересненькое. Первое на что натыкается взгляд это…

«%s Basic»

«%s Deluxe»

«%s Normal»

«%s Once»

«%s -This product is licensed to «

«%s -This product is unregistered»

«%s Unregistered»

Жмем два раза на Deluxe и попадаем сюда.

:00473152 A1E0FC4E00 mov eax, dword ptr [004EFCE0]

:00473157 83C408 add esp, 00000008

:0047315A 8B805C010000 mov eax, dword ptr [eax 0000015C]

:00473160 3D89BC3A74 cmp eax, 743ABC89

:00473165 7513 jne 0047317A

* Possible StringData Ref from Data Obj ->»3dflyingsaver v2.28″

|

:00473167 8B0DDC764C00 mov ecx, dword ptr [004C76DC]

:0047316D 8D542400 lea edx, dword ptr [esp]

:00473171 51 push ecx

* Possible StringData Ref from Data Obj ->»%s Normal»

|

:00473172 687C7B4C00 push 004C7B7C

:00473177 52 push edx

:00473178 EB58 jmp 004731D2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00473165(C)

|

:0047317A 3DAA457782 cmp eax, 827745AA

:0047317F 750D jne 0047318E

* Possible StringData Ref from Data Obj ->»3dflyingsaver v2.28″

|

:00473181 A1DC764C00 mov eax, dword ptr [004C76DC]

:00473186 50 push eax

* Possible StringData Ref from Data Obj ->»%s Deluxe»

|

:00473187 68707B4C00 push 004C7B70

:0047318C EB3F jmp 004731CD

(и так далее)

Как видно, что если в нужной ячейке памяти будет число 827745AAh, то программа выполнит любой ваш приказ, который сможет. И не будет посылать вас ко всем разработчикам. Две строки определяющие адрес памяти выделены красным. На этом месте я вошел в ступор. И решил попробовать ввести код. Полез в настройки савера, но там никаких кнопок регистрации не было. На самом деле она есть, но об этом после.

Потом я решил проверить реестр, многие проги кидают туда регистрационную инфу. Я запустил RegMon и опять зашел в настройки скринсавера.

??? QueryValueEx HKCU\Software\Longgame\3dflyingsaver\regserial NOTFOUND

??? QueryValueEx HKCU\Software\Longgame\3dflyingsaver\regname NOTFOUND

??? QueryValueEx HKCU\Software\Longgame\3dflyingsaver\regtype NOTFOUND

Это сподвигло меня на мысль, и я отбалды создал эти параметры. Зайдя очередной раз в настройки я увидел, что прога зарегена на меня, но сверху почему-то все еще торчит Unregistred. Тогда меня осенило, в параметре regtype(двоичный) я написал буквально следующее 827745AA. Но опяти ничаво не произошло. Но в голову лезли всякие мысли и я вспомнил, что в памяти числовая информация храниться в обратном порядке и я написал AA457782. Каково же было мое удивление, когда вместо привычной строки Unregistred, я увидал Deluxe. Теперь стал возможен выбор всего барахла. Вроде бы все в порядке, но дабы насладиться плодами своего труда я решил запустить савер и что… после нескольких секунд всплыла надпись, утверждающая, что я не зареген и предлогалось нажать F2, чтобы сделать эту процедуру. Что делать, нажал. Всплыло тоже окно, что и в настройках, но с хорошей кнопочкой Registrer. Нажав ее, вам откроется обычное окошко с двумя полями для ввода. Тут-то и начинается основная сказка….

Для выявления места, я воспользовался старым, как мир способом: написал любой пароль, выдалась строка «invalid code». Затем в Win32Dasm’e я ее нашел и отправился, к нужной точке.

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004729ED(C), :004729F1(C)

|

* Possible StringData Ref from Data Obj ->»invalid code»

|

:00472A54 6894784C00 push 004C7894

:00472A59 6A00 push 00000000

:00472A5B 6A0C push 0000000C

Как обычно поднимаемся выше по ссылкам.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00472839(C)

|

:00472996 8D942428010000 lea edx, dword ptr [esp 00000128]

* Possible StringData Ref from Data Obj ->»have a try»

|

:0047299D 68F8784C00 push 004C78F8

:004729A2 52 push edx

(куча пропущено)

:004729CA E8E1560200 call 004980B0

:004729CF 8D542440 lea edx, dword ptr [esp 40]

:004729D3 8BF0 mov esi, eax

* Possible StringData Ref from Data Obj ->»test»

|

:004729D5 68CC784C00 push 004C78CC <- Сравнение с тестовой версией

:004729DA 52 push edx

:004729DB 0FAFF7 imul esi, edi

:004729DE E8CD560200 call 004980B0

:004729E3 0FAF442430 imul eax, dword ptr [esp 30]

:004729E8 83C420 add esp, 00000020

:004729EB 85F6 test esi, esi

:004729ED 7565 jne 00472A54 <- Вот переходы к предыдущему блоку

:004729EF 85C0 test eax, eax

:004729F1 7561 jne 00472A54 <-

:004729F3 A1E0FC4E00 mov eax, dword ptr [004EFCE0]

:004729F8 56 push esi

Опять ничего определенного, только сравнение на тестовую версию. Теперь идем к 472839.

:00472818 8D442428 lea eax, dword ptr [esp 28] <- Берем имя

:0047281C 8D8C2428010000 lea ecx, dword ptr [esp 00000128] <- Берем пароль

(!!! Я могу ошибаться с именем и паролем, я не проверял)

:00472823 50 push eax <- Заносим

:00472824 51 push ecx <- Их в стек

* Possible Reference to String Resource ID=00001: «3dflyingsaver 2.28»

|

:00472825 6A01 push 00000001

:00472827 E8C4FDFFFF call 004725F0 <- Процедура проверки

:0047282C 83C40C add esp, 0000000C

:0047282F 89442414 mov dword ptr [esp 14], eax <- Записываем результат проверки

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00472812(C), :00472816(C)

|

:00472833 8B442414 mov eax, dword ptr [esp 14] <- Берем результат в eax

:00472837 85C0 test eax, eax <- Проверяем, если результат не 0, то все отлично

:00472839 0F8457010000 je 00472996 <- Вот отсюда делался скачок на предыдущий блок

(Дальше идет запись в реестр правильных данных)

Теперь, как вы понимаете идем к процедуре проверки имени и пароля, и будем с ней разбираться.

:004725F0 81EC14010000 sub esp, 00000114

….

(Выброшены строки, где имя копируется на новое место)

….

:0047262B 8D4C2410 lea ecx, dword ptr [esp 10] <- Имя

:0047262F BF89BC3A74 mov edi, 743ABC89 <- Указание на нормальную регистрацию

(поскольку нормальная ругистрация нам не нужна пропускаем эту процедуру)

:00472634 51 push ecx

:00472635 55 push ebp

:00472636 53 push ebx

:00472637 E884FBFFFF call 004721C0

:0047263C 8BB4243C010000 mov esi, dword ptr [esp 0000013C]

:00472643 8D54241C lea edx, dword ptr [esp 1C] <- По адресу в edx лежит правильный код

для нормальной регистрации (можно просто посмотреть)

:00472647 83C40C add esp, 0000000C

:0047264A 33C0 xor eax, eax

:0047264C 2BF2 sub esi, edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0047265F(C)

|

:0047264E 8D4C0410 lea ecx, dword ptr [esp eax 10]

:00472652 8A140E mov dl, byte ptr [esi ecx] < Сравнение правильного кода с введенным

:00472655 3A11 cmp dl, byte ptr [ecx] < вами

:00472657 7402 je 0047265B

:00472659 33FF xor edi, edi

(всякий мусор)

:00472676 BFAA457782 mov edi, 827745AA <- А вот это уже Deluxe

:0047267B 50 push eax

:0047267C 55 push ebp

:0047267D 6A03 push 00000003 <- Запомните это число

:0047267F E83CFBFFFF call 004721C0

:00472684 83C40C add esp, 0000000C

:00472687 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0047269E(C)

|

:00472689 8A5C0C10 mov bl, byte ptr [esp ecx 10]

:0047268D 8D440C10 lea eax, dword ptr [esp ecx 10] < Тут идет проверка и можно

:00472691 8A1406 mov dl, byte ptr [esi eax] < подсмотреть настоящий s/n

:00472694 3AD3 cmp dl, bl < и на этом закончить.

:00472696 7402 je 0047269A

Теперь заходим в основную процедуру генерации, обитающую по адресу 4721C0.

(выкинут лишний код)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0047221E(U)

|

:00472214 803820 cmp byte ptr [eax], 20 <- Если у имени имеется пробел, он заменяется на байт с кодом 0

:00472217 7507 jne 00472220

:00472219 C60000 mov byte ptr [eax], 00

:0047221C 4D dec ebp

:0047221D 48 dec eax

:0047221E EBF4 jmp 00472214

(куча лишнего кода, общий смысл которого сводился к подстановке числа

посланного в процедуру в конец имени. Помните я вам говорил запомнить )

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00472228(C)

|

:00472289 8B84242C020000 mov eax, dword ptr [esp 0000022C]

:00472290 83F802 cmp eax, 00000002 < Сравнение с Basic-регистрацией

:00472293 0F8587010000 jne 00472420 <- Переходим

(Весь код связанный с Basic-регистрациейбыл вырезан, если Вам интересно, то исследуйте

код сами)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00472293(C)

|

:00472420 83F803 cmp eax, 00000003 <- Сравнение с Deluxe-регистрацией

:00472423 742A je 0047244F < Если не она, то улететь

(Здесь вырез код, общий смысл которого. Если регистрация Делюкс, то последний символ

(который вставили раньше) удаляется, т.е. какое имя было, такое и осталось)

(Далее идет основная процедура генерации кода)

(Перед входом в процедуру значение регистров равны EBP = 0A77C5523h, EDI = 45FA4323h, EDX = 0)

(В адресе [esp 14] в начале храниться значение 0A77C5523h, а [esp 18] в начале равно 35DCA890h)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004724FA(C)

|

:004724A6 0FBE9C1428010000 movsx ebx, byte ptr [esp edx 00000128] <- Берем edx-ный символ имени

:004724AE 0FBE44141C movsx eax, byte ptr [esp edx 1C] <- Берем тот же edx-ный символ имени

:004724B3 8BF3 mov esi, ebx <- esi=ebx

:004724B5 8BC8 mov ecx, eax <- ecx=eax

:004724B7 0FAFF3 imul esi, ebx <- esi = esi*ebx;

:004724BA 0FAFCD imul ecx, ebp <- ecx = ecx*ebp;

:004724BD 0FAFF2 imul esi, edx <- esi = esi*edx;

:004724C0 03CE add ecx, esi <- ecx = ecx esi

:004724C2 0FAFCA imul ecx, edx <- ecx = ecx*edx

:004724C5 8D2C39 lea ebp, dword ptr [ecx edi] <- ebp = ecx edi

:004724C8 0FAFEB imul ebp, ebx <- ebp = ebp*ebx

:004724CB 03FD add edi, ebp <- edi = edi ebp

:004724CD 8B6C2414 mov ebp, dword ptr [esp 14] <- ebp = значение из адреса памяти [esp 14]

:004724D1 03CF add ecx, edi <- ecx = ecx edi

:004724D3 0FAFCB imul ecx, ebx <- ecx = ecx*ebx

:004724D6 03E9 add ebp, ecx <- ebp = ebp ecx

:004724D8 0FAFC5 imul eax, ebp <- eax = eax*ebp

:004724DB 03C6 add eax, esi <- eax = eax esi

:004724DD 896C2414 mov dword ptr [esp 14], ebp <- Записываем в адрес [esp 14] значение ebp

:004724E1 0FAFC2 imul eax, edx <- eax = eax*edx

:004724E4 03C7 add eax, edi <- eax = eax edi

:004724E6 0FAFC3 imul eax, ebx <- eax = eax*ebx

:004724E9 8B5C2418 mov ebx, dword ptr [esp 18] <- Берем в ebx значение из [esp 18]

:004724ED 03D8 add ebx, eax <- ebx = ebx eax

:004724EF 8B442410 mov eax, dword ptr [esp 10] <- Берем общую длинну имени

:004724F3 42 inc edx <- Увеличивам счетчик на единицу

:004724F4 895C2418 mov dword ptr [esp 18], ebx <- Записываем из ebx значение в [esp 18]

:004724F8 3BD0 cmp edx, eax <- Если еще не все буквы прошли

:004724FA 72AA jb 004724A6 <- то повторяем

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004724A4(C)

|

:004724FC 8BC7 mov eax, edi <- eax = edi

:004724FE 33D2 xor edx, edx <- edx = 0

:00472500 B923000000 mov ecx, 00000023 <- ecx = 23h

:00472505 8BB42434020000 mov esi, dword ptr [esp 00000234] <- В esi адрес буфера правильного кода

:0047250C F7F1 div ecx <- eax = eax div ecx, edx = eax mod ecx

(Прим: После операции деления, в eax остается целая часть, а в edx остаток. В Паскале

такой остаток можно вычислить с помощью команды mod и поэтому, я ее здесь применил)

:0047250E B8D5411DD4 mov eax, D41D41D5 <- eax = 0D41D41D5h

:00472513 80C230 add dl, 30 <- dl = dl 30h

:00472516 8816 mov byte ptr [esi], dl <- Записываем первый символ кода

:00472518 F7E7 mul edi <-

(После такой операции умножения, значеник распределиться в два регистра edx:eax. В Паскале

аналогов этому нет, и поэтому в кейгене, я применил вставку на ассемблере)

:0047251A 8BC7 mov eax, edi <- eax = edi

:0047251C BF23000000 mov edi, 00000023 <- edi = 23h

:00472521 2BC2 sub eax, edx <- eax = eax-edx

:00472523 D1E8 shr eax, 1 <- eax = eax div 2

(Прим: shr — логический сдвиг вправо, здесь сдвигается регистр eax на 1 бит. )

Аналогичен целочисленному делению на 2. )

Т.к. в Паскале div это операция целочисленного деления, я ее здесь применил )

:00472525 03C2 add eax, edx <- eax = eax edx

:00472527 33D2 xor edx, edx <- edx = 0

:00472529 C1E805 shr eax, 05 < eax = eax div 32

(Прим: shr — логический сдвиг вправо, здесь сдвигается регистр eax на 5 бит. )

Это аналогично делению на 2 пять раз. Т.е. надо делить на 32 )

Далее идет код аналогичный рассмотренному ранее, поэтому попробуйте проанализировать его

сами. ИМХО, ничего трудного в этом нет. А если вы не будете знать элементраных команд

ассемблера наизусть, то какой из Вас крэкер?

:0047252C F7F1 div ecx

:0047252E B8D5411DD4 mov eax, D41D41D5

:00472533 8BCD mov ecx, ebp

:00472535 80C230 add dl, 30

:00472538 885601 mov byte ptr [esi 01], dl

:0047253B F7E5 mul ebp

:0047253D 2BCA sub ecx, edx

:0047253F 8BC5 mov eax, ebp

:00472541 D1E9 shr ecx, 1

:00472543 03CA add ecx, edx

:00472545 33D2 xor edx, edx

:00472547 F7F7 div edi

:00472549 C1E905 shr ecx, 05

:0047254C 8BC1 mov eax, ecx

:0047254E 80C230 add dl, 30

:00472551 885602 mov byte ptr [esi 02], dl

:00472554 33D2 xor edx, edx

:00472556 F7F7 div edi

:00472558 B8D5411DD4 mov eax, D41D41D5

:0047255D 80C230 add dl, 30

:00472560 885603 mov byte ptr [esi 03], dl

:00472563 F7E1 mul ecx

:00472565 8BC1 mov eax, ecx

:00472567 8BCF mov ecx, edi

:00472569 2BC2 sub eax, edx

:0047256B D1E8 shr eax, 1

:0047256D 03C2 add eax, edx

:0047256F 33D2 xor edx, edx

:00472571 C1E805 shr eax, 05

:00472574 F7F1 div ecx

:00472576 B8D5411DD4 mov eax, D41D41D5

:0047257B 8BCB mov ecx, ebx

:0047257D 80C230 add dl, 30

:00472580 885604 mov byte ptr [esi 04], dl

:00472583 F7E3 mul ebx

:00472585 2BCA sub ecx, edx

:00472587 8BC3 mov eax, ebx

:00472589 D1E9 shr ecx, 1

:0047258B 03CA add ecx, edx

:0047258D 33D2 xor edx, edx

:0047258F F7F7 div edi

:00472591 C1E905 shr ecx, 05

:00472594 8BC1 mov eax, ecx

:00472596 80C230 add dl, 30

:00472599 885605 mov byte ptr [esi 05], dl

:0047259C 33D2 xor edx, edx

:0047259E F7F7 div edi

:004725A0 B8D5411DD4 mov eax, D41D41D5

:004725A5 80C230 add dl, 30

:004725A8 885606 mov byte ptr [esi 06], dl

:004725AB F7E1 mul ecx

:004725AD 8BC1 mov eax, ecx

:004725AF 8BCF mov ecx, edi

:004725B1 2BC2 sub eax, edx

:004725B3 D1E8 shr eax, 1

:004725B5 03C2 add eax, edx

:004725B7 33D2 xor edx, edx

:004725B9 C1E805 shr eax, 05

:004725BC F7F1 div ecx

:004725BE 80C230 add dl, 30

:004725C1 33C9 xor ecx, ecx <- ecx =0

:004725C3 885607 mov byte ptr [esi 07], dl <- Записываем последний 8 символ

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004725D6(C)

|

:004725C6 8A0431 mov al, byte ptr [ecx esi] <- Берем ecx-ный символ имени

:004725C9 3C39 cmp al, 39 <- Сравниваем его с кодом 39h (символ '9')

:004725CB 7E05 jle 004725D2 <- Если меньше или равно, то переход

:004725CD 0407 add al, 07 <- Иначе добавляем к его коду 7

:004725CF 880431 mov byte ptr [ecx esi], al <- И записываем обратно

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004725CB(C)

|

:004725D2 41 inc ecx <- Увеличиваем счетчик на единицу

:004725D3 83F908 cmp ecx, 00000008 <- Сравниваем счетчик с 8

:004725D6 72EE jb 004725C6 <- Если меньше, то повторяем

:004725D8 C6460800 mov [esi 08], 00 <- Записываем в конец сгенерированного кода символ 0

тем самым получая настоющую null-строку

…(Выполняем стандартные процедуры)

:004725E6 C3 ret <- Выходим из процедуры

Вся процедура генерации рассмотрена и проверена, теперь осталось простое занятие — написать кейген. Сегодня я напишу кейген на Делфи, который будет занимать < 20Kb. Тем самым давая понять, что на Дельфях тоже можно делать такое. За предоставленный образец огромнейшее спасибо Dr. Golova без его разъяснений ничего бы не получилось.

Как этим воспользоваться? Сохраняем весь этот кусок, как проэктный файл, т.е файл с расширением «.dpr». Затем открываем Делфой и запускаем.

program KG;

uses Windows, Messages;

const WindowTitle : PChar = ‘3Dflyingsaver v2.28 KeyGen by Fess [PTDS]’;

AboutStr : PChar = ‘3Dflyingsaver v2.28’

‘ KeyGen by Fess [PTDS]’ #13#10

‘ Прога: http://www.longgame.net’ #13#10

‘ Мыль мне lomovskih@yandex.ru’ #13#10

‘ Наша урла: vallkor.chat.ru’ #13#10

‘ Специальное спасибо Dr.Golova ‘ #0;

var WinClass: TWndClassA;

Inst, Handle, Button1, Button2, Label1, Label2, Edit1, Edit2: Integer;

Msg: TMsg;

hFont: Integer;

////////////////////////////////////////////////////////////////////////////////

{ Собственно расчет ключиков. Без комментариев. }

function KeyGen(Name: string): string;

var

s,s1: String;

B: Byte;

M1,M2,M3,M4,M5,M6,M7,M8: Char;

dx_ : Word;

ebx_,eax_, edi_, edx_, esp14, esp18, esi_, ecx_, ebp_:Dword;

begin

s:=Name;

esp14:=$A77C5523;

esp18:=$35DCA890;

edi_ :=$45FA432B;

For B:=1 To Length(S) Do

Begin

ebx_ := Ord(S[B]);

edx_ := B-1;

eax_ := Ord(S[B]);

esi_ := ebx_;

ecx_ := eax_;

esi_ := esi_*ebx_;

ecx_ := ecx_*ebp_;

esi_ := esi_*edx_;

ecx_ := ecx_ esi_;

ecx_ := ecx_*edx_;

ebp_ := ecx_;

ebp_ := ebp_ edi_;

ebp_ := ebp_*ebx_;

edi_ := edi_ ebp_;

ebp_ := esp14;

ecx_ := ecx_ edi_;

ecx_ := ecx_*ebx_;

ebp_ := ebp_ ecx_;

eax_ := eax_*ebp_;

eax_ := eax_ esi_;

esp14 := ebp_;

eax_ := eax_*edx_;

eax_ := eax_ edi_;

eax_ := eax_*ebx_;

ebx_ := esp18;

ebx_ := ebx_ eax_;

esp18 := ebx_;

end;

eax_ := edi_;

edx_ := 0;

ecx_ := $00000023;

dx_:= eax_ mod ecx_;

eax_ := $D41D41D5;

M1 := Chr(Lo(dx_) $30);

asm

mov eax, eax_

mov ecx, edi_

mul ecx

mov edx_,edx

end;

eax_ := edi_;

edi_ := $00000023;

eax_ := eax_-edx_;

eax_ := eax_ div 2;

eax_ := eax_ edx_;

edx_:=0;

eax_ := eax_ div 32; //shr eax, 5

dx_ := eax_ mod ecx_;

eax_ := $D41D41D5;

ecx_ := ebp_;

M2 := Chr(Lo(dx_) $30);

asm

mov eax, eax_

mov ecx, ebp_

mul ecx

mov edx_,edx

end;

ecx_ := ecx_-edx_;

eax_ := ebp_;

ecx_ := ecx_ div 2;

ecx_ := ecx_ edx_;

edx_ :=0;

dx_ := eax_ mod edi_;

ecx_ := ecx_ div 32; //shr ecx,5

eax_ := ecx_;

M3 := Chr(Lo(dx_) $30);

edx_ :=0;

dx_:= eax_ mod edi_;

eax_ := $D41D41D5;

M4 := Chr(Lo(dx_) $30);

asm

mov eax, eax_

mov ecx, ecx_

mul ecx

mov edx_,edx

end;

eax_ := ecx_;

ecx_ := edi_;

eax_ := eax_-edx_;

eax_ := eax_ div 2;

eax_ := eax_ edx_;

edx_:=0;

eax_ := eax_ div 32;

dx_ := eax_ mod ecx_;

eax_ := $D41D41D5;

ecx_ := ebx_;

M5 := Chr(Lo(dx_) $30);

asm

mov eax, eax_

mov ecx, ebx_

mul ecx

mov edx_,edx

end;

ecx_ := ecx_-edx_;

eax_ := ebx_;

ecx_ := ecx_ div 2;

ecx_ := ecx_ edx_;

edx_ :=0;

dx_ := eax_ mod edi_;

ecx_ := ecx_ div 32;

eax_ := ecx_;

M6 := Chr(Lo(dx_) $30);

edx_ := 0;

dx_ := eax_ mod edi_;

eax_ := $D41D41D5;

M7 := Chr(Lo(dx_) $30);

asm

mov eax, eax_

mov ecx, ecx_

mul ecx

mov edx_,edx

end;

eax_ := ecx_;

ecx_ := edi_;

eax_ := eax_-edx_;

eax_ := eax_ div 2;

eax_ := eax_ edx_;

edx_:=0;

eax_ := eax_ div 32;

dx_ := eax_ mod ecx_;

M8 := Chr(Lo(dx_) $30);

ecx_:=0;

S1:=M1 M2 M3 M4 M5 M6 M7 M8;

For B:=1 To 8 Do

if Ord(S1[B])>$39 then S1[B]:=Chr( Ord(S1[B]) 7 );

Result:=S1;

end;

{ Процедура генерации рег.номера, вызывается при нажатии Button1. }

{ Сама обрабатывает непредвиденные ситуации и пишет результвт в Edit2 }

procedure Generate;

var Name : PChar;

begin

{ Выделяем память для текстового буффера, и получаем рег.имя из Edit1}

GetMem(Name, 1024);

GetWindowText(Edit1, Name, 1024);

{ Если длина имени не подходит — уведомим об этом пользователя }

if length(Name) < 4 then begin

SetWindowText(Edit2, PChar(‘Введите имя подлинней !!!’));

FreeMem(Name);

Exit;

end;

{ Выводим посчитанный рег.номер в Edit2, и освобождаем текстовый буффер }

SetWindowText(Edit2, PChar(KeyGen(String(Name))));

FreeMem(Name);

end;

{ Личная оконная функция 🙂 Обрабатывает события в нашем окне }

{ Эта функция вызывается операционной системой, потому и stdcall }

function WindowProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;

begin

Result := DefWindowProc(hWnd, uMsg, wParam, lParam);

if uMsg = WM_COMMAND then begin

if lParam = Button1 then MessageBox(hWnd, AboutStr, ‘О кейгене…’, 0);

if lParam = Button2 then Halt;

if (HIWORD(wParam) = EN_CHANGE) and (lParam = Edit1) then Generate;

end else

if uMsg = WM_DESTROY then Halt;

end;

////////////////////////////////////////////////////////////////////////////////

begin

{$R *.res}

{ Зарегистрируем свой собственный класс окна }

Inst := hInstance;

with WinClass do

begin

style := CS_CLASSDC or CS_PARENTDC; // Стиль окна

lpfnWndProc := @WindowProc; // Адрес оконной функции

hInstance := Inst;

hbrBackground := color_btnface 1;

lpszClassname := ‘KG_WINDOW’; // Имя нового класса

hCursor := LoadCursor(0, IDC_ARROW); // Стандартный курсор

hIcon := LoadIcon(Inst, ‘MAINICON’); // Моя иконка

end;

RegisterClass(WinClass);

{ Создаем главное окно программы }

Handle := CreateWindowEx(WS_EX_WINDOWEDGE, ‘KG_WINDOW’, WindowTitle,

WS_VISIBLE or WS_CAPTION or WS_SYSMENU,

(GetSystemMetrics(SM_CXSCREEN) — 305) div 2,

(GetSystemMetrics(SM_CYSCREEN) — 083) div 2,

305, 83, 0, 0, Inst, nil);

{ На этом окне делаем все прочие элементы — кнопку, текста, окна редактирования }

Button1 := CreateWindow(‘Button’, ‘Об этом.’, WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,

227, 9, 65, 19, Handle, 0, Inst, nil);

Button2 := CreateWindow(‘Button’, ‘Закрыть.’, WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,

227, 31, 65, 19, Handle, 0, Inst, nil);

Label1 := CreateWindow(‘Static’, », WS_VISIBLE or WS_CHILD or SS_LEFT,

8, 12, 176, 13, Handle, 0, Inst, nil);

Label2 := CreateWindow(‘Static’, », WS_VISIBLE or WS_CHILD or SS_LEFT,

8, 34, 176, 13, Handle, 0, Inst, nil);

Edit1 := CreateWindowEx(WS_EX_CLIENTEDGE, ‘Edit’, », WS_CHILD or WS_VISIBLE or

WS_BORDER or ES_AUTOHSCROLL, 80, 8, 140, 21, Handle, 0, Inst, nil);

Edit2 := CreateWindowEx(WS_EX_CLIENTEDGE, ‘Edit’, », WS_CHILD or WS_VISIBLE or

WS_BORDER or ES_READONLY or ES_AUTOHSCROLL, 80, 30, 140, 21, Handle, 0, Inst, nil);

{ Создаем приемлимый для нас шрифт для всех элементов. }

hFont := CreateFont(-11, 0, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET,

OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,

DEFAULT_PITCH or FF_DONTCARE, ‘MS Sans Serif’);

{ Устанавливаем созданный шрифт для всех элементов }

if hFont 0 then

begin

SendMessage(Button1, WM_SETFONT, hFont, 0);

SendMessage(Button2, WM_SETFONT, hFont, 0);

SendMessage(Label1, WM_SETFONT, hFont, 0);

SendMessage(Label2, WM_SETFONT, hFont, 0);

SendMessage(Edit1, WM_SETFONT, hFont, 0);

SendMessage(Edit2, WM_SETFONT, hFont, 0);

end;

{ Прописываем текст на метках (Label) }

SetWindowText(Label1, ‘Ваше имя:’);

SetWindowText(Label2, ‘Рег.номер:’);

{ Пусть поле ввода имени будет активизировано по умолчанию }

SetFocus(Edit1);

{ Показать окно, и перерисовать содержимое }

ShowWindow(Handle, 1);

UpdateWindow(Handle);

{ Типа цикл обработки сообщений, он и будет все время крутиться }

while(GetMessage(Msg, Handle, 0, 0)) do

begin

TranslateMessage(msg);

DispatchMessage(msg);

end;

end.

Процедура генерации опробована и проверена!! Так что ошибок нет. Сделана на Delphi 4.

Для имени Fess код должен быть N08L6PWR.

Спасибо за интерес к моему творчеству!

Удачи в Reversing Engeneering!

Послесловие

Спасибо автору за предоставленный для исследования продукт. Было очень интересно. Спасибо фирме Borland за превосходный Паскаль, без которого я жить не могу. 🙂

Господа Авторы: Защита стандартна. Перед тем, как делать защиту можно было и почитать мануалы, написанные в этом направлении. Извините меня, но $30 для России это не дела. Крэкеров в Росии много. Россия рулез!

Братья Крэкеры: Не стоит сильно ругать авторов, они там за бугром не ведают, что творят.

P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!

P.P.S. Возможно имеют место опечатки, заранее извините!

With best wishes Fess Member of the group PTDS

И да пребудет с вами великий дух bad-сектора.

{/codecitation}

Добавить комментарий