скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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


Автор: 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-сектора.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook