http://www.winimage.com - Webpage.
Date: 06/05/99
SoftICE v3.xx
W32Dasm
A brain.
Any programming language (I choose Pascal).
OK, lets begin, this tutor will teach you about keygens. Firstly a few words about this program, it uses multiple registraion codes, 5 to be exact.. however you only need to enter any one of them to register the program. Also this program gets a constant and adds it to the calculations from your name. It also converts your name serial into Hexadecimal, sort of, it will actually switch the 'B' and '8' around. Interesting.
Lets go!, fire UP SoftICE and set a breakpoint on 'hmemcpy', enter your fake name and serial and press enter. After some tracing we will get to this point:
:004346E8 CALL USER32.CharUpperA, Ord:002Fh <-- Capitalizes all letters in our name.
:004346EE PUSH [ESP+04]
:004346F2 CALL 0041F989
:004346F7 POP ECX
:004346F8 RET
Simple enough, this just capitalizes the user name, nothing big here.
:00434721 CALL KERNEL32.lstrlenA, Ord:0308h <-- Gets length of user name. :0043474B PUSH 00000027 <-- Set EDI = 27h, important in the function below. :0043474D POP EDI
Sure enough after some more tracing we come to this... the utilisation of the name.
:0043474E MOVZX EDX, BYTE PTR [ESI+ECX+03] <-- Get character.
:00434753 LEA EDX, DWORD PTR [ECX+03] <-- EAX = position of name+3 meaning the current position in the string. :00434756 IMUL EDX, EDI <-- EDX = ASCII of current character multiplied by value of EDI. :00434759 ADD DWORD PTR [EBP-04], EDX <-- Add EDX to "constant", I will show you how to get the constant later. :0043475C PUSH 0000000E :0043475E CDQ :0043475F POP EBX :00434760 IDIV EBX :00434762 TEST EDX, EDX <-- Do stupid maths. :00434764 JZ 0043476B :00434766 LEA EDI, DWORD PTR [EDI+2*EDI] <-- EDI = EDI*3 :00434769 JMP 0043476E <-- Just follow this. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00434764(C) :0043476B IMUL EDI, 00000007 <-- Ignore this. * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00434769(U) | :0043476E INC ECX <-- Increase position. :0043476F CMP ECX, DWORD PTR [EBP+08] <-- Check if end of name. :00434772 JL 0043473F <-- If not... repeat.
Now.. simple.. EDI does NOT get reset to 27h each pass of the loop.. instead, it triples on each consecutive loop.... Now how to get the constant? well if we use a 3 or 4 letter name, and write down what it adds each time then we get the total of the new value and subtract everything that was added to it we get the constant.. pretty simple.. it just repeats the above until it gets to the end of your name!
How to do this? simple.. when you get to the below line.. just type "? edx" and write this value down.
:00434759 ADD DWORD PTR [EBP-04], EDX
For those of you too lazy.. the constant is: 47694Ch
Now, this number generated is your first serial (not the constant, but the result of all the maths), with one exception.. It does its crazy switch with the 'B' and "8" now.
:00434806 LEA EAX, DWORD PTR [EBP+FFFFFF00] <-- String hex value before conversion. :0043480C PUSH EAX :0043480D LEA EAX, DWORD PTR [EBP+FFFFFE00] :00434813 PUSH EDI :00434814 PUSH EAX :00434815 CALL 0043477C <-- Call 'crazy' converter. :0043481A POP ECX :0043481B POP ECX :0043481C PUSH EAX * Reference To: CRTDLL.strcmp, Ord:01CFh <-- Compare strings, like your fake serial and the REAL one.
OK, simple... all it does is take the value of the result of the additions to the string and puts them into a HEX value. Next it uses the 'crazy' call and switches the B and the 8 in hex, see examples:
12345B would become 123458
17A988 would become 17A9BB
I will explain the crazy function in a bit.
Now i will explain the way to get the other serials. Follow below.. It is important to know that EDI starts off as the value of the result of the maths with our name.
:0043482C LEA EAX, DWORD PTR [EBP+FFFFFF00] :00434832 PUSH EAX :00434833 LEA EAX, DWORD PTR [EDI+14051948] <-- Add this constant to EDI. :00434839 PUSH EAX :0043483A LEA EAX, DWORD PTR [EBP+FFFFFE00] :00434840 PUSH EAX :00434841 CALL 0043477C <-- Call the crazy funtion again. :00434846 POP ECX :00434847 POP ECX :00434848 PUSH EAX * Reference To: CRTDLL.strcmp, Ord:01CFh <-- Another string compare.
| OK all it does is add a constant to the result of the maths on our name..it then changes the B and 8 like above by calling the crazy function again. This process repeats for all 5 possible serials.. I wont comment the rest because they are all similar, but I did highlight them for easy access :).
:0043485B LEA EAX, DWORD PTR [EDI+17061954] :00434869 CALL 0043477C * Reference To: CRTDLL.strcmp, Ord:01CFh :00434871 CALL CRTDLL.strcmp :00434883 LEA EAX, DWORD PTR [EDI+10051981] :00434891 CALL 0043477C * Reference To: CRTDLL.strcmp, Ord:01CFh :00434899 CALL CRTDLL.strcmp :004348AB LEA EAX, DWORD PTR [EDI+04011995] :004348B9 CALL 0043477C * Reference To: CRTDLL.strcmp, Ord:01CFh :004348C1 CALL CRTDLL.strcmp
Pretty simple eh?, now the below code is my so called 'Crazy function'. Basically, this function moves the HEX value into a string and compares the characters one by one to B or 8, and if either is found it switches them.
:00434798 MOV AL, BYTE PTR [EBP-10] <-- Load first character into AL. :004347A7 CMP AL, 38 <-- Compare AL to '8'. :004347A9 JNZ 004347AF <-- If not 8 continue. :004347AB ADD AL, 0A <-- If it is 8 convert it to B and follow next jump. :004347AD JMP 004347B5 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004347A9(C) | :004347AF CMP AL, 42 <-- Compare to B. :004347B1 JNZ 004347B5 <-- If it isn't B continue. :004347B3 ADD AL, F6 <-- If it is B convert to 8 by adding F6h. * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:004347AD(U), :004347B1(C) | :004347B5 MOV BYTE PTR [ESI], AL <-- Move modified character over old character in string. :004347B7 MOV AL, BYTE PTR [ECX+ESI+01] <-- Get next character. :004347BB INC ESI <-- Increase position marker. :004347BC TEST AL, AL <-- Test for end of string. :004347BE JNZ 004347A7 <-- If more characters, loop.
OK, I hope you can put this all together.. I will also include my source code for my keygen below. I'm a terrible programmer.. but it works! btw, I only generated 3 of the five serials.. can you do the other two?.
I hope to see you again in Flu[X] tutor #9. As always if you like a program buy it! This essay is for educational purposes ONLY! Software authors deserve your support!
Flu[X]/TNO99
http://tuts99.cjb.net - Webpage.