697 lines
20 KiB
Plaintext
697 lines
20 KiB
Plaintext
== ASM KEYGEN TUTORIAL - WRITTEN BY TERAPHY [PC97]
|
|
===================================================
|
|
|
|
This is the tools i use in this tutorial:
|
|
Soft-Ice 3.01
|
|
W32Dasm 8.9 *Regged*
|
|
Tasm/Tlink
|
|
|
|
|
|
Getting Started:
|
|
What we should do is to get the registration code,
|
|
find where the code is being calculated and rip it out.
|
|
I will use two easy programs as examples,
|
|
Command Line 97 1.0, and Flywheel V1.02b.
|
|
|
|
|
|
Command Line 97 1.0:
|
|
(http://www.odyssey.net/subscribers/js01/index.html)
|
|
This program has a real simple code calculation.
|
|
I will guide you step by step how to get the serial,
|
|
how to rip it and how to make a working keygen.
|
|
|
|
1. Start the Program
|
|
|
|
2. Select Register
|
|
|
|
3. Go into Soft-Ice by pressing Ctrl-D, and set a breakpoint on
|
|
GetDlgItemTextA. Type 'bpx getdlgitemtexta'. Now Press Ctrl-D
|
|
again to get out from Soft-Ice.
|
|
|
|
4. Enter your name and a serial... I used 'TERAPHY' and '12345'
|
|
|
|
5. Press OK Button.. Soft-Ice will now show up inside the call
|
|
to GetDlgItemTextA. Press F11 to get out of that call.
|
|
|
|
Scroll up a bit and u will see this
|
|
|
|
:0040254B 6A1E push 0000001E
|
|
:0040254D 68300B4100 push 00410B30
|
|
:00402552 68F0030000 push 000003F0
|
|
:00402557 56 push esi
|
|
:00402558 FF1550234100 Call [USER32!GetDlgItemTextA]
|
|
|
|
The memory location being pushed at 40254D is where your name is
|
|
stored. Type 'd 410B30', and you should see your name.
|
|
|
|
Below this you'll see
|
|
|
|
:0040255E 6A00 push 00000000
|
|
:00402560 BF300B4100 mov edi, 00410B30
|
|
:00402565 6A00 push 00000000
|
|
:00402567 68FC030000 push 000003FC
|
|
:0040256C 56 push esi
|
|
:0040256D FF1518234100 Call [USER32!GetDlgItemInt]
|
|
|
|
Step until you reach 40256D. The call to Getdlgitemint returns
|
|
what you typed in as serial in eax. Type '? eax' and you will
|
|
see this '00003039 0000012345 "09"'. 3039 is 12345 in hex.
|
|
Also notice :00402560. This command moves the offset of your name
|
|
into edi.
|
|
|
|
Below this, you will see
|
|
|
|
:00402573 B9FFFFFFFF mov ecx, FFFFFFFF
|
|
:00402578 A354A54000 mov dword ptr [0040A554], eax
|
|
:0040257D 2BC0 sub eax, eax
|
|
:0040257F F2 repnz
|
|
:00402580 AE scasb
|
|
:00402581 F7D1 not ecx
|
|
:00402583 49 dec ecx
|
|
|
|
:00402578 saves your code for later use.
|
|
The rest of the code is used to calculate the string length of
|
|
your name... After this has been executed ecx contains the length
|
|
of your name. In my case '7'.
|
|
|
|
Below this, you'll see
|
|
|
|
:00402584 0FBE05300B4100 movsx eax, byte ptr [00410B30]
|
|
:0040258B 0FAFC8 imul ecx, eax
|
|
:0040258E C1E10A shl ecx, 0A
|
|
:00402591 81C1CCF80200 add ecx, 0002F8CC
|
|
:00402597 890D50A54000 mov dword ptr [0040A550], ecx
|
|
:0040259D 390D54A54000 cmp dword ptr [0040A554], ecx
|
|
|
|
:00402584 moves the byte of the first letter to eax.
|
|
In my case 54('T'). The next line multiplys eax (54),
|
|
with ecx (7). shl ecx, 0A means multiply ecx with 2^10.
|
|
And finnaly we add 02F8CC to ecx.
|
|
At :0040259D the registration code is compared with what
|
|
we typed in, remember it moved our code to [0040A554].
|
|
Type '? ecx' and you can see your real code.
|
|
But we don't just want the code, do we?
|
|
Leave SoftIce and exit Command Line 97.
|
|
|
|
6. Start W32Dasm, and dissasemble cline97.exe
|
|
Save dissasembly to file and exit.
|
|
|
|
7. Now we are going to build the keygen itself.
|
|
Start your favorite texteditor and enter this code.
|
|
|
|
|
|
Code Segment Byte Public
|
|
Assume Ds:Code,Cs:Code
|
|
Org 100h
|
|
P386 ; this enables 386 instructions
|
|
and 32bit registers
|
|
|
|
Start:
|
|
|
|
mov ah,09
|
|
mov dx,offset Intro
|
|
int 21h ; Show intro msg
|
|
|
|
mov ah,0Ah
|
|
mov dx,offset Namesto
|
|
int 21h ; Get name
|
|
|
|
|
|
Now load the dissasembly (cline97.alf) into your texteditor.
|
|
Goto :00402573. Copy all code from here down to :00402591,
|
|
and paste it into your asm source.
|
|
|
|
It will look like this
|
|
:00402573 B9FFFFFFFF mov ecx, FFFFFFFF
|
|
:00402578 A354A54000 mov dword ptr [0040A554], eax
|
|
:0040257D 2BC0 sub eax, eax
|
|
:0040257F F2 repnz
|
|
:00402580 AE scasb
|
|
:00402581 F7D1 not ecx
|
|
:00402583 49 dec ecx
|
|
:00402584 0FBE05300B4100 movsx eax, byte ptr [00410B30]
|
|
:0040258B 0FAFC8 imul ecx, eax
|
|
:0040258E C1E10A shl ecx, 0A
|
|
:00402591 81C1CCF80200 add ecx, 0002F8CC
|
|
|
|
Now you can start ripping. You should remove everything except the command
|
|
itself. The line :00402578 is obviously not needed, because it saves the
|
|
inputed regcode for later use, and our keygen does not prompt for regcode,
|
|
it calculates =)
|
|
|
|
The source in your program should look like this.
|
|
|
|
mov ecx, FFFFFFFF
|
|
sub eax, eax
|
|
repnz
|
|
scasb
|
|
not ecx
|
|
dec ecx
|
|
movsx eax, byte ptr [00410B30]
|
|
imul ecx, eax
|
|
shl ecx, 0A
|
|
add ecx, 0002F8CC
|
|
|
|
If you remember, it moved the offset of Name into edi earlier.
|
|
So we need to add this before mov ecx, FFFFFFFF
|
|
xor edi,edi
|
|
mov di, offset Namesto+2 ; this must be +2, becaue that's there
|
|
; the actuall name begins.
|
|
|
|
The command mov ecx, FFFFFFFF can't be compiled this way, so we
|
|
have to change it to mov ecx, 0FFFFFFFFh.
|
|
|
|
movsx eax, byte ptr [00410B30] is not valid either, because
|
|
our name is'nt on [00410B30]. This could be changed to
|
|
xor edi,edi
|
|
mov di, offset Namesto+2
|
|
movsx eax, byte ptr [edi]
|
|
|
|
Both 'shl ecx, 0A' and 'add ecx, 0002F8CC' needs to be changed to
|
|
valid hex format: 'shl ecx, 0Ah' and 'add ecx 2F8CCh'
|
|
|
|
We now have a source that should look like this
|
|
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
mov ecx, 0FFFFFFFFh
|
|
sub eax, eax
|
|
repnz
|
|
scasb
|
|
not ecx
|
|
dec ecx
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
movsx eax, byte ptr [edi]
|
|
imul ecx, eax
|
|
shl ecx, 0Ah
|
|
add ecx, 2F8CCh
|
|
|
|
after the dec ecx, we need to add another dec ecx,
|
|
because when we enter our name, the last char will not be,
|
|
in my case, 'y', it will be 0Dh, the enter key.
|
|
This function, as it is, will return, in my case, ecx=8,
|
|
not ecx=7 as it should be.
|
|
|
|
movsx eax, byte ptr [edi] moves the ascii code of the first
|
|
letter to eax. But, what if the user enters a name with a
|
|
small letter? The input box in Command Line 97 automaticly
|
|
makes it capital letters. This could be fixed by adding this
|
|
code below movsx eax, byte ptr [edi].
|
|
|
|
cmp eax, 061h ; compare eax with 61h (a)
|
|
jb capital ; jump if below
|
|
cmp eax, 07Ah ; compare eax with 7Ah (z)
|
|
ja capital ; jump if above
|
|
sub eax,20h ; convert char to capital
|
|
capital:
|
|
|
|
Our code now looks like
|
|
|
|
Code Segment Byte Public
|
|
Assume Ds:Code,Cs:Code
|
|
Org 100h
|
|
P386 ; this enables 386 instructions
|
|
and 32bit registers
|
|
|
|
Start:
|
|
|
|
mov ah,09
|
|
mov dx,offset Intro
|
|
int 21h ; Show intro msg
|
|
|
|
mov ah,0Ah
|
|
mov dx,offset Namesto
|
|
int 21h ; Get name
|
|
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
mov ecx, 0FFFFFFFFh
|
|
sub eax, eax
|
|
repnz
|
|
scasb
|
|
not ecx
|
|
dec ecx
|
|
dec ecx
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
movsx eax, byte ptr [edi]
|
|
cmp eax, 061h
|
|
jb capital
|
|
cmp eax, 07Ah
|
|
ja capital
|
|
sub eax,20h
|
|
capital:
|
|
imul ecx, eax
|
|
shl ecx, 0Ah
|
|
add ecx, 2F8CCh
|
|
|
|
What we need now is a routine to show the serial.
|
|
We know that the serial is the decimal value of ecx.
|
|
|
|
xor esi,esi
|
|
mov si,offset Serial+9 ; esi is the offset there the
|
|
; regnumber will be stored
|
|
|
|
mov eax,ecx ; eax should be reg number
|
|
mov ecx,0Ah
|
|
KeepGoing:
|
|
xor edx,edx
|
|
div ecx
|
|
add dl,30h
|
|
cmp dl,3Ah
|
|
jl printnow
|
|
add dl,7
|
|
printnow:
|
|
dec esi
|
|
mov [esi],dl
|
|
or eax,eax
|
|
jnz keepgoing
|
|
|
|
After this serial contains the registration code.
|
|
You don't really need to understand this code. It can be used
|
|
by any keygen there the code is the decimal value of a register.
|
|
|
|
The only thing left to do is to add the command that's writes
|
|
this to screen.
|
|
|
|
mov ah, 9
|
|
mov dx, offset RegPrompt
|
|
int 21h
|
|
|
|
And finnaly quit.
|
|
int 20h
|
|
|
|
The full source should look like this
|
|
|
|
; COMMAND LINE 97 *KEYGEN*
|
|
; CODED BY TERAPHY [PC97]
|
|
|
|
Code Segment Byte Public
|
|
Assume Ds:Code,Cs:Code
|
|
Org 100h
|
|
P386 ; this enables 386 instructions
|
|
; and 32bit registers
|
|
|
|
Start:
|
|
|
|
mov ah,09
|
|
mov dx,offset Intro
|
|
int 21h ; Show intro msg
|
|
|
|
mov ah,0Ah
|
|
mov dx,offset Namesto
|
|
int 21h ; Get name
|
|
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
mov ecx, 0FFFFFFFFh
|
|
sub eax, eax
|
|
repnz
|
|
scasb
|
|
not ecx
|
|
dec ecx
|
|
xor edi,edi
|
|
mov di,offset Namesto+2
|
|
movsx eax, byte ptr [edi]
|
|
cmp eax, 061h
|
|
jb capital
|
|
cmp eax, 07Ah
|
|
ja capital
|
|
sub eax,20h
|
|
capital:
|
|
imul ecx, eax
|
|
shl ecx, 0Ah
|
|
add ecx, 2F8CCh
|
|
|
|
xor esi,esi
|
|
mov si,offset Serial+9
|
|
mov eax,ecx
|
|
mov ecx,0Ah
|
|
KeepGoing:
|
|
xor edx,edx
|
|
div ecx
|
|
add dl,30h
|
|
cmp dl,3Ah
|
|
jl printnow
|
|
add dl,7
|
|
printnow:
|
|
dec esi
|
|
mov [esi],dl
|
|
or eax,eax
|
|
jnz keepgoing
|
|
|
|
mov ah, 9
|
|
mov dx, offset RegPrompt
|
|
int 21h
|
|
|
|
int 20h
|
|
|
|
Intro db 13,10,'COMMAND LINE 97 *KEYGEN*'
|
|
db 13,10,'CODED BY TERAPHY [PC97]',13,10
|
|
db 13,10,'Enter your name: $'
|
|
|
|
RegPrompt db 13,10,'Your registration key is: '
|
|
Serial db 0,0,0,0,0,0,0,0,0,0,13,10,24h
|
|
|
|
Namesto db 18h,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
|
|
Code Ends
|
|
End Start
|
|
|
|
8. Compile the code with tasm.
|
|
tasm keygen.asm
|
|
tlink /t keygen.asm
|
|
You must link with the /t option for the keygen to run,
|
|
it makes it a com file.
|
|
|
|
9. Congratulations! You have just made your first(?) keygen!
|
|
|
|
|
|
Flywheel V1.02b
|
|
(http://www.plannetarium.com)
|
|
|
|
1. Start the Program
|
|
|
|
2. Select Register
|
|
|
|
3. Go into Soft-Ice by pressing Ctrl-D, and set a breakpoint on
|
|
GetDlgItemTextA. Type 'bpx getdlgitemtexta'. Now Press Ctrl-D
|
|
again to get out from Soft-Ice.
|
|
|
|
4. Enter your name ('TERAPHY') and any serial ('12345').
|
|
Press OK button, and Soft-Ice will show up.
|
|
|
|
Scroll up a little bit and you'll see this
|
|
|
|
:00402ACD 8D4C242C lea ecx, [esp+2C]
|
|
:00402AD1 66AB stosw
|
|
:00402AD3 6800010000 push 00000100
|
|
:00402AD8 51 push ecx
|
|
:00402AD9 6A65 push 00000065
|
|
:00402ADB 56 push esi
|
|
:00402ADC AA stosb
|
|
:00402ADD FF151C154100 Call [USER32!GetDlgItemTextA]
|
|
|
|
The important adress is there your name is being pushed, and
|
|
that is push ecx. ecx got is value from 'lea ecx,[esp+2C]'.
|
|
Type 'd esp+2c', and you should see your name.
|
|
|
|
Below is a call to GetDlgItemInt, and as you remember it returns
|
|
the inputed value to eax. Type '? eax' to see the serial you wrote.
|
|
|
|
Below this, you'll see this
|
|
|
|
:00402AF3 8D54242C lea edx, [esp+2C]
|
|
:00402AF7 50 push eax
|
|
:00402AF8 52 push edx
|
|
:00402AF9 E8D2F9FFFF call 004024D0
|
|
:00402AFE 83C408 add esp, 00000008
|
|
:00402B01 85C0 test eax, eax
|
|
|
|
'lea edx,[esp+2C]' moves the offset of your name into edx,
|
|
and then it pushes to stack. And eax contains our serial.
|
|
And after the call it tests if eax is true or false.
|
|
This call is there the registration code is being calculated.
|
|
|
|
We trace into it. Step past the first instructions until you reach
|
|
|
|
:004024EF B81F85EB51 mov eax, 51EB851F
|
|
:004024F4 F7E7 mul edi
|
|
:004024F6 C1EA05 shr edx, 05
|
|
:004024F9 52 push edx
|
|
:004024FA 56 push esi
|
|
:004024FB E8B0000000 call 004025B0
|
|
|
|
004024EF - 004024F6 makes edx all digits except the two last
|
|
of what we typed in as serial. If you wrote '12345' edx will
|
|
be '123', and if you wrote '072597' edx will be '0725'.
|
|
|
|
Then it pushes edx and esi. esi is the offset to your name.
|
|
Trace into the call. Step past a few instructions until you reach
|
|
|
|
:004025B8 8A06 mov al, byte ptr [esi]
|
|
esi contains the offset to your name, so this instrucion moves
|
|
the ascii code of the first letter to al, in my case '54'
|
|
|
|
:004025BA 84C0 test al, al
|
|
:004025BC 7426 je 004025E4
|
|
This instrucions checks if we have inputed any name, if not it jumps.
|
|
|
|
:004025BE 0FBEC0 movsx eax, al
|
|
This instrucion moves al, to eax. If eax = FFFFFF54,
|
|
after this eax would have been 00000054
|
|
|
|
:004025C1 50 push eax
|
|
:004025C2 E889140000 call 00403A50
|
|
At a first look this call only moves the eax value to ecx.
|
|
But it does also check for a space (20h) in eax. It returns
|
|
false if not a space.
|
|
|
|
:004025C7 83C404 add esp, 00000004
|
|
This code changes the stack and should be ignored
|
|
|
|
:004025CA 85C0 test eax, eax
|
|
:004025CC 750E jne 004025DC
|
|
Test if a space was found. Jump if found.
|
|
|
|
:004025CE 0FBE0E movsx ecx, byte ptr [esi]
|
|
This moves the letter into ecx (there it should already be).
|
|
|
|
:004025D1 51 push ecx
|
|
:004025D2 E8E9120000 call 004038C0
|
|
If you, as in my case, wrote your name with a capital letter,
|
|
this call will return eax = ascii code for your letter + 20h.
|
|
This means it has been converted to a small letter.
|
|
|
|
:004025D7 83C404 add esp, 00000004
|
|
Ignore this
|
|
|
|
:004025DA 03F8 add edi, eax
|
|
Add edi, eax. Eax is the value of our char as small letter.
|
|
|
|
:004025DC 8A4601 mov al, byte ptr [esi+01]
|
|
:004025DF 46 inc esi
|
|
Moves the value of the next char into al
|
|
|
|
:004025E0 84C0 test al, al
|
|
:004025E2 75DA jne 004025BE
|
|
Test if al is 0. This means the end of our name has been reached.
|
|
Jump if al is not 0.
|
|
|
|
What this code has done, as you probably already figured out, is
|
|
add the ascii value of all chars into edi. Except spaces (20h).
|
|
It has also converted all capital chars into small letters.
|
|
|
|
:004025E4 8B4C2410 mov ecx, [esp+10]
|
|
This moves what we typed in (except the last two digits) into ecx
|
|
|
|
:004025E8 8D14BF lea edx, [edi+4*edi]
|
|
:004025EB 2BCF sub ecx, edi
|
|
:004025ED 8D1457 lea edx, [edi+2*edx]
|
|
:004025F0 85D2 test edx, edx
|
|
:004025F2 740F je 00402603
|
|
:004025F4 B8ABAAAAAA mov eax, AAAAAAAB
|
|
:004025F9 F7E2 mul edx
|
|
:004025FB D1EA shr edx, 1
|
|
:004025FD 81C204060200 add edx, 00020604
|
|
:00402603 33C0 xor eax, eax
|
|
:00402605 3BCA cmp ecx, edx
|
|
|
|
This code checks if you typed in the right number.
|
|
At 402605 the compare is made. But ecx is no longer
|
|
what we wrote as serial, because of the 'sub ecx,edi'
|
|
command. We could make a simple equation of this.
|
|
|
|
Assume X is our registration code (except the two digits).
|
|
'X - EDI = EDX'
|
|
|
|
Now type '? edx+edi' and, in my case, I'll get '136182'
|
|
as decimal value. This is my regcode, except the two last
|
|
digits. These digits could be anything.
|
|
Now then we know my registration code is '13618200',
|
|
we can start on the keygen.
|
|
|
|
5. Run W32Dasm and dissasemble flywheel.exe (the file is located
|
|
in 'C:\Program Files\Plannet Crafters\Flywheel')
|
|
Save the dissasembly to disk and quit.
|
|
|
|
6. Now it's time to start on the code. We can use the same start
|
|
as in the last keygen. We go directly to the ripping part.
|
|
|
|
You can start by copy all code from 4025B8 to 402605 into your program.
|
|
That will look like this.
|
|
|
|
:004025B8 8A06 mov al, byte ptr [esi]
|
|
:004025BA 84C0 test al, al
|
|
:004025BC 7426 je 004025E4
|
|
:004025BE 0FBEC0 movsx eax, al
|
|
:004025C1 50 push eax
|
|
:004025C2 E889140000 call 00403A50
|
|
:004025C7 83C404 add esp, 00000004
|
|
:004025CA 85C0 test eax, eax
|
|
:004025CC 750E jne 004025DC
|
|
:004025CE 0FBE0E movsx ecx, byte ptr [esi]
|
|
:004025D1 51 push ecx
|
|
:004025D2 E8E9120000 call 004038C0
|
|
:004025D7 83C404 add esp, 00000004
|
|
:004025DA 03F8 add edi, eax
|
|
:004025DC 8A4601 mov al, byte ptr [esi+01]
|
|
:004025DF 46 inc esi
|
|
:004025E0 84C0 test al, al
|
|
:004025E2 75DA jne 004025BE
|
|
:004025E4 8B4C2410 mov ecx, dword ptr [esp+10]
|
|
:004025E8 8D14BF lea edx, dword ptr [edi+4*edi]
|
|
:004025EB 2BCF sub ecx, edi
|
|
:004025ED 8D1457 lea edx, dword ptr [edi+2*edx]
|
|
:004025F0 85D2 test edx, edx
|
|
:004025F2 740F je 00402603
|
|
:004025F4 B8ABAAAAAA mov eax, AAAAAAAB
|
|
:004025F9 F7E2 mul edx
|
|
:004025FB D1EA shr edx, 1
|
|
:004025FD 81C204060200 add edx, 00020604
|
|
:00402603 33C0 xor eax, eax
|
|
:00402605 3BCA cmp ecx, edx
|
|
|
|
Here is how I would have ripped this into the program,
|
|
with comments.
|
|
|
|
; THIS REPLACES 4025BE - 4025E2
|
|
|
|
xor ecx,ecx
|
|
xor edi,edi
|
|
mov di, offset NameSto+2 ; Mov the offset of your name
|
|
; into edi
|
|
anotherchar:
|
|
movsx eax, byte ptr [di] ; Get char from [di]
|
|
|
|
cmp eax, 20h ; Compare your letter with 20h
|
|
je space ; Jump if equal
|
|
|
|
cmp eax, 041h ; Compare your letter to see
|
|
jb capital ; if it's already is a
|
|
cmp eax, 05Ah ; small lettter
|
|
ja capital
|
|
add eax,20h ; If capital char, add 20h to make
|
|
; it a small letter.
|
|
capital:
|
|
add ecx, eax ; add eax to ecx, if not space
|
|
space:
|
|
|
|
inc di ; inc di to make it point to the
|
|
; next char.
|
|
|
|
cmp byte ptr [di], 0dh ; Compare next char with 0Dh (return)
|
|
; Remember then we get our name, it
|
|
; ends with a 0Dh
|
|
|
|
jne anotherchar ; Jump if not 0Dh
|
|
mov edi, ecx
|
|
|
|
; CODE BELOW REPLACES 4025E2 - 402603
|
|
; All commands with ecx (our inputed code) is not needed
|
|
; because we do not input any code.
|
|
|
|
xor edx,edx
|
|
lea edx, [edi + 4*edi]
|
|
lea edx, [edi + 2*edx]
|
|
mov eax, 0AAAAAAABh
|
|
mul edx
|
|
shr edx, 1
|
|
add edx, 20604h
|
|
|
|
xor ecx, ecx ; Here we do our equation
|
|
add ecx, edx ;
|
|
add ecx, edi ; ecx = edx + edi
|
|
|
|
After this, ecx contains the regcode.
|
|
The complete source could look like this.
|
|
|
|
Code Segment Byte Public
|
|
Assume Ds:Code,Cs:Code
|
|
Org 100h
|
|
P386
|
|
|
|
Start:
|
|
|
|
mov ah,09
|
|
mov dx,offset Intro
|
|
int 21h ; Show intro msg
|
|
|
|
mov ah,0Ah
|
|
mov dx,offset Namesto
|
|
int 21h ; Get name
|
|
|
|
xor ecx,ecx
|
|
xor edi,edi
|
|
mov di, offset NameSto+2
|
|
anotherchar:
|
|
movsx eax, byte ptr [di]
|
|
cmp eax, 20h
|
|
je space
|
|
cmp eax, 041h
|
|
jb capital
|
|
cmp eax, 05Ah
|
|
ja capital
|
|
add eax,20h
|
|
capital:
|
|
add ecx, eax
|
|
space:
|
|
inc di
|
|
cmp byte ptr [di], 0dh
|
|
jne anotherchar
|
|
mov edi, ecx
|
|
xor edx,edx
|
|
lea edx, [edi + 4*edi]
|
|
lea edx, [edi + 2*edx]
|
|
mov eax, 0AAAAAAABh
|
|
mul edx
|
|
shr edx, 1
|
|
add edx, 20604h
|
|
xor ecx, ecx
|
|
add ecx, edx
|
|
add ecx, edi
|
|
|
|
xor esi,esi
|
|
mov si,offset Serial+9
|
|
mov eax,ecx
|
|
mov ecx,0Ah
|
|
KeepGoing:
|
|
xor edx,edx
|
|
div ecx
|
|
add dl,30h
|
|
cmp dl,3Ah
|
|
jl printnow
|
|
add dl,7
|
|
printnow:
|
|
dec esi
|
|
mov [esi],dl
|
|
or eax,eax
|
|
jnz keepgoing
|
|
|
|
mov ah, 9
|
|
mov dx, offset RegPrompt
|
|
int 21h
|
|
|
|
int 20h
|
|
|
|
Intro db 13,10,'FLYWHEEL 1.2 *KEYGEN*'
|
|
db 13,10,'CODED BY TERAPHY [PC97]',13,10
|
|
db 13,10,'Enter your name: $'
|
|
|
|
RegPrompt db 13,10,'Your registration key is: '
|
|
Serial db 0,0,0,0,0,0,0,0,0,'0','0',13,10,24h
|
|
|
|
Namesto db 18h,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
|
|
Code Ends
|
|
End Start
|
|
|
|
|
|
Now compile, run and enjoy! :)
|
|
|
|
|
|
==================
|
|
= TERAPHY [PC97] =
|
|
= 07/25/1997 =
|
|
================== |