About this tutorial:
Tutorial:An interesting self-checking serial protection: Auto-IP Publisher 2.32 Target:Auto-IP Publisher(http://www.lakefield.net/~smiller/autoip/) Tools:SoftICE 3.2x, W32Dasm 8.9x, HIEW 6.1x
Date:10th June 2000(Last updated on 12th June 2000)
Descriptions&Comments:There are not many tutorials on self-checking serial yet on the net and I am proud to introduce you(well, sort of, though there are already some very good essays on this subject) to this self-checking serial protection with a very good protection(in a program called Auto-IP Publisher) as an example. By the way, I found that this(not particular this, but this type of) protection is even more secure compared to some name/serial protection with *real* easy serial calculation algo(at least, for newbies, hehe)...
Protections:Self-checking serial
Disclaimer:This file is used for educational purposes
only. Any misuse of the information presented here is not my responsibility.
Copyright information:This tutorial is copyright ©
ManKind
Starting words:
|
The process:
First of all, just in case if there's anyone who doesn't understand even a single thing about self-checking serial protection, I will explain it here. A self-checking serial protection's serial(s) is/are calculated from the entered serial itself, meaning validity verification of either valid or invalid serial is made on the serial and the serial must comply to some rules to be valid. I have included the following source(with comment!) to show you an example of self-checking serial:
Program example ; {program's name} uses crt ; {crt is a unit, this is similar to the include directive in c/c++, for example - #include
var {variable declaration}
begin
If serial2 = serial3 then {if serial2 equal to serial3, display good_boy_message}
end. |
How to get a valid serial? Note that the ascii value of the second byte(character) of serial must be equal to the ascii of the first byte of serial + ascii of the third byte of the serial to be a valid serial. So, to calculate a valid second byte(character), it depends on the ascii of first and third byte of the serial and you must add up the ascii value of the first and the third byte of the serial. If for example, I choose 1 and 1(each with ascii value of 49) the second byte should be a b to be a valid serial because 49 + 49 = 98(ascii of b). The full valid serial would be 1b1. Note that there are more than one valid serial(because it not fixed, it depends on the first and third byte, so, as long as ascii_of_second_byte = ascii_of_first_byte + ascii_of_third_byte, it will be a valid serial. One last thing you have to pay attention to is the serial length check(heck, it is the very first rule that your serial have to comply to).
I would like to show you one example of such protection(of course, it is not as easy as what I demonstrated, hehe). Our target is Auto-IP Publisher 2.32. Start it, go to the registration screen and enter the following as the registration code(the usual fake number that I used for cracking):
23199981
Go into SoftICE, set a breakpoint on hmemcpy so that we would break immediately after our serial has been read like below:
bpx hmemcpy
Leave SoftICE, press OK button, you will break in SoftICE, press F11 once and F12 until you reach useful codes(something like xxxx:xxxxxxxx with no RET instruction nearby, in this case and almost all the times 11 times of F12 are required) like below:
:0049FC13 8B55FC mov edx, dword ptr [ebp-04] <-- get serial into edx :0049FC16 8D831C050000 lea eax, dword ptr [ebx+0000051C] :0049FC1C E8AF3FF6FF call 00403BD0 :0049FC21 8B931C050000 mov edx, dword ptr [ebx+0000051C] <-- get serial into edx :0049FC27 8BC3 mov eax, ebx :0049FC29 E8D2FCFFFF call 0049F900 <-- main serial verification routine :0049FC2E 84C0 test al, al <-- if al=0=bad_boy else ifHmm, obviously we have to step into the call instruction at address 0049FC29(call 0049F900) to defeat this protection(no, don't even think of patching the JE at address 0049FC30 to JNE, that's lame and it won't work). To step into the call, when your white line of indicator of SoftICE is on that particular line, press F8 and you will see something like this:
al=1=good_boy :0049FC30 7471 je 0049FCA3 <-- bad_boy_jump,
determined by the value returned by th above call :0049FC32 6A00 push 00000000* Possible StringData Ref from Code Obj ->"Registered!" | :0049FC34 B9ECFC4900 mov ecx, 0049FCEC * Possible StringData Ref from Code Obj ->"You are now registered. Please " ->"restart Auto-IP" | :0049FC39 BAF8FC4900 mov edx, 0049FCF8 :0049FC3E A1A84E4A00 mov eax, dword ptr [004A4EA8] :0049FC43 8B00 mov eax, dword ptr [eax] :0049FC45 E8A208FBFF call 004504EC
* Referenced by a CALL at Addresses: <-- take note of this |:0049AF69 , :0049FC29 <-- and this for use at the end of tutorial | :0049F900 55 push ebp :0049F901 8BEC mov ebp, esp :0049F903 B906000000 mov ecx, 00000006 --- snipped out to save space, its useless anyway --------- * Possible StringData Ref from Code Obj ->"110391481A28" | :0049F92F BA74FB4900 mov edx, 0049FB74 <-- get above number into edx :0049F934 E8D345F6FF call 00403F0C <-- check if serial = edx :0049F939 740F je 0049F94A <-- jump to bad_boy if yes :0049F93B 8B45FC mov eax, dword ptr [ebp-04] <-- move serial to eax * Possible StringData Ref from Code Obj ->"J00811611@06" | :0049F93E BA8CFB4900 mov edx, 0049FB8C <-- get above number into edx :0049F943 E8C445F6FF call 00403F0C <-- check if serial = edx :0049F948 7517 jne 0049F961 <-- jump to good_boy if notSo, it checks if our serial is equal to either 110391481A28 or J00811611@06 and we will immediately be thrown to bad_boy if the serial is equal to one of them. My wild guess is that these two set of numbers are pirated serial numbers that has been blacklisted by the author of this program(meaning the serial has been identified as pirate serial and you won't be able to register the program with this serial though the two set of numbers are actually valid ones, but that's in the past, hehe). At first, I myself was fooled into believing that one of those two set of numbers are actually valid serials because the check really looks like those lame single serial check protection which I had cracked in the past. Continue with the good_boy code over here(don't enter the two sets of numbers as serial and you'll reach here):
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0049F948(C) | :0049F961 837DFC00 cmp dword ptr [ebp-04], 00000000 <-- compareIf you are using the same serial I told you to, you won't be able to continue to the good_code, so, set a breakpoint on address 0049F976(disable all others), leave SoftICE and re-register with the below serial so that we can pass the length check:
whether serial is entered(or if its length is 0) :0049F965 0F84CB010000 je 0049FB36 <-- jump to
bad_boy if serial is not entered(or if its length is 0) :0049F96B 8B45FC mov eax, dword ptr [ebp-04] :0049F96E E88944F6FF call 00403DFC :0049F973 83F80C cmp eax, 0000000C <-- compare
whether length of serial equals to 12 decimal :0049F976 0F85BA010000 jne 0049FB36 <-- jump to bad_boy if not
231999812222
Press the OK button and you will be brought here after you jump from address 0049F976:
:0049F97F 33DB xor ebx, ebx :0049F981 8A18 mov bl, byte ptr [eax] <-- get theHmm, it wants to make sure that ascii of the first character of the serial is higher than 59 decimal but not more than 90 decimal(this actually means that capital A-Z is accepted). Leave SoftICE again(of course, set a breakpoint on address 0049F98E and disable all other breakpoints first), modify your serial into the following and re-register again:
ascii of the first byte(character) of serial :0049F983 83EB06 sub ebx, 00000006 <-- minus it by 6 decimal :0049F986 83FB3B cmp ebx, 0000003B <-- compare
whether it equals to 59 decimal :0049F989 7C05 jl 0049F990 <-- jump to bad_boy
if its lower than 59 decimal :0049F98B 83FB54 cmp ebx, 00000054 <-- compare
it with 84 decimal(ascii of 'T') :0049F98E 7E11 jle 0049F9A1 <-- jump if its
lower than or equal to 84 decimal
M23199981222(no special intention except for putting the first letter of my handle into the serial to create some sort of signature, useful for preventing lamers to steal your serial and for serial identification(as if its legal, hehe))
You will successfully jump here:
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0049F98E(C) | :0049F9A1 8D45F4 lea eax, dword ptr [ebp-0C] :0049F9A4 8B55FC mov edx, dword ptr [ebp-04] <-- get serial into edx :0049F9A7 8A5206 mov dl, byte ptr [edx+06] <-- get theI think my comments are good, aren't they? This piece of code retrieve the char of the 7th and 4th byte of the serial and make them into a string(9 & 1 = 91, some sort of string concatenation) and turn that string into integer value("91" into 91) and then compare the value of the ascii of the first byte - 6(M=77 decimal, 77 - 6 = 71 decimal) with the combined value of 7th and 4th byte of the serial. To pass this check, modify your serial into the following:
ascii of the 7th byte(character) of serial :0049F9AA 885001 mov byte ptr [eax+01], dl :0049F9AD C60001 mov byte ptr [eax], 01 :0049F9B0 8D55F4 lea edx, dword ptr [ebp-0C] :0049F9B3 8D45F0 lea eax, dword ptr [ebp-10] :0049F9B6 E85930F6FF call 00402A14 :0049F9BB 8D45EC lea eax, dword ptr [ebp-14] :0049F9BE 8B55FC mov edx, dword ptr [ebp-04] :0049F9C1 8A5203 mov dl, byte ptr [edx+03] <-- get the
ascii of the 4th byte(character) of serial :0049F9C4 885001 mov byte ptr [eax+01], dl :0049F9C7 C60001 mov byte ptr [eax], 01 :0049F9CA 8D55EC lea edx, dword ptr [ebp-14] :0049F9CD 8D45F0 lea eax, dword ptr [ebp-10] :0049F9D0 B102 mov cl, 02 :0049F9D2 E80D30F6FF call 004029E4 :0049F9D7 8D55F0 lea edx, dword ptr [ebp-10] :0049F9DA 8D45F8 lea eax, dword ptr [ebp-08] :0049F9DD E8BE43F6FF call 00403DA0 :0049F9E2 8B45F8 mov eax, dword ptr [ebp-08] :0049F9E5 E80A90F6FF call 004089F4 :0049F9EA 3BD8 cmp ebx, eax <-- compare ebx with eax,
ebx=ascii of first byte - 6, eax=integer form of char of the 7th and 4th
character(where 7th is 9 and 4th is 1 will make up a value of 91) of serial :0049F9EC 7407 je 0049F9F5 <-- jump to good_boy if equals :0049F9EE 33DB xor ebx, ebx :0049F9F0 E941010000 jmp 0049FB36 <-- jump to ret with a bad_boy value
M23199781222
After passing the check you will jump to the following code from 0049F9EC:
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0049F9EC(C) | :0049F9F5 8D45F4 lea eax, dword ptr [ebp-0C] :0049F9F8 8B55FC mov edx, dword ptr [ebp-04] :0049F9FB 8A5202 mov dl, byte ptr [edx+02] <-- get the 3rd byte of serial :0049F9FE 885001 mov byte ptr [eax+01], dl :0049FA01 C60001 mov byte ptr [eax], 01 :0049FA04 8D55F4 lea edx, dword ptr [ebp-0C] :0049FA07 8D45F0 lea eax, dword ptr [ebp-10] :0049FA0A E80530F6FF call 00402A14 :0049FA0F 8D45EC lea eax, dword ptr [ebp-14] :0049FA12 8B55FC mov edx, dword ptr [ebp-04] :0049FA15 8A5201 mov dl, byte ptr [edx+01] <-- get the 2nd byte of serial :0049FA18 885001 mov byte ptr [eax+01], dl :0049FA1B C60001 mov byte ptr [eax], 01 :0049FA1E 8D55EC lea edx, dword ptr [ebp-14] :0049FA21 8D45F0 lea eax, dword ptr [ebp-10] :0049FA24 B102 mov cl, 02 :0049FA26 E8B92FF6FF call 004029E4 :0049FA2B 8D55F0 lea edx, dword ptr [ebp-10] :0049FA2E 8D45E8 lea eax, dword ptr [ebp-18] :0049FA31 E86A43F6FF call 00403DA0 :0049FA36 8B45E8 mov eax, dword ptr [ebp-18] :0049FA39 E8B68FF6FF call 004089F4 :0049FA3E 83C040 add eax, 00000040 <-- add 64 decimal to eax :0049FA41 8B55FC mov edx, dword ptr [ebp-04] :0049FA44 0FB65209 movzx edx, byte ptr [edx+09] <-- get the 10th byte of serial :0049FA48 3BC2 cmp eax, edx <-- compare eax and edx :0049FA4A 7407 je 0049FA53 <-- jump to good_boy if equal :0049FA4C 33DB xor ebx, ebx :0049FA4E E9E3000000 jmp 0049FB36 <-- jump to ret with bad_boy valueThis is almost same as the previous check, edx=ascii of 10th byte of serial while eax=integer form of char of 3rd and 2nd byte of serial("3" + "1" = 31), so, to pass this check, modify your serial into the following again:
Note that I changed the 10th byte of serial into K-ascii 75 decimal('K' is one of the characters of my handle!) and the 2nd and 3rd byte into 5 and 7(making up 75, third byte is read first and when converted into integer form, it will bear a value of 70). Another thing to note is that 64 decimal will be added to the integer form of the char at the 3rd and 2nd byte of serial(that explains why thee 3rd and 2nd byte of the serial should be 11 and not 57). Let's continue with the next check which is also the last:
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0049FA4A(C) | :0049FA53 8D45E4 lea eax, dword ptr [ebp-1C] :0049FA56 8B55FC mov edx, dword ptr [ebp-04] :0049FA59 8A5201 mov dl, byte ptr [edx+01] <-- get the 2nd byte of serial :0049FA5C E8C342F6FF call 00403D24 :0049FA61 8B45E4 mov eax, dword ptr [ebp-1C] :0049FA64 E88B8FF6FF call 004089F4 :0049FA69 8BD8 mov ebx, eax :0049FA6B 8D45E0 lea eax, dword ptr [ebp-20] :0049FA6E 8B55FC mov edx, dword ptr [ebp-04] :0049FA71 8A5202 mov dl, byte ptr [edx+02] <-- get the 3rd byte of serial :0049FA74 E8AB42F6FF call 00403D24 :0049FA79 8B45E0 mov eax, dword ptr [ebp-20] :0049FA7C E8738FF6FF call 004089F4 :0049FA81 03D8 add ebx, eax :0049FA83 8D45DC lea eax, dword ptr [ebp-24] :0049FA86 8B55FC mov edx, dword ptr [ebp-04] :0049FA89 8A5203 mov dl, byte ptr [edx+03] <-- get the 4th byte of serial :0049FA8C E89342F6FF call 00403D24 :0049FA91 8B45DC mov eax, dword ptr [ebp-24] :0049FA94 E85B8FF6FF call 004089F4 :0049FA99 03D8 add ebx, eax :0049FA9B 8D45D8 lea eax, dword ptr [ebp-28] :0049FA9E 8B55FC mov edx, dword ptr [ebp-04] :0049FAA1 8A5204 mov dl, byte ptr [edx+04] <-- get the 5th byte of serial :0049FAA4 E87B42F6FF call 00403D24 :0049FAA9 8B45D8 mov eax, dword ptr [ebp-28] :0049FAAC E8438FF6FF call 004089F4 :0049FAB1 03D8 add ebx, eax :0049FAB3 8D45D4 lea eax, dword ptr [ebp-2C] :0049FAB6 8B55FC mov edx, dword ptr [ebp-04] :0049FAB9 8A5205 mov dl, byte ptr [edx+05] <-- get the 6th byte of serial :0049FABC E86342F6FF call 00403D24 :0049FAC1 8B45D4 mov eax, dword ptr [ebp-2C] :0049FAC4 E82B8FF6FF call 004089F4 :0049FAC9 03D8 add ebx, eax :0049FACB 8D45D0 lea eax, dword ptr [ebp-30] :0049FACE 8B55FC mov edx, dword ptr [ebp-04] :0049FAD1 8A5206 mov dl, byte ptr [edx+06] <-- get the 7th byte of serial :0049FAD4 E84B42F6FF call 00403D24 :0049FAD9 8B45D0 mov eax, dword ptr [ebp-30] :0049FADC E8138FF6FF call 004089F4 :0049FAE1 03D8 add ebx, eax :0049FAE3 8D45F4 lea eax, dword ptr [ebp-0C] :0049FAE6 8B55FC mov edx, dword ptr [ebp-04] :0049FAE9 8A5208 mov dl, byte ptr [edx+08] <-- get the 9th byte of serial :0049FAEC 885001 mov byte ptr [eax+01], dl :0049FAEF C60001 mov byte ptr [eax], 01 :0049FAF2 8D55F4 lea edx, dword ptr [ebp-0C] :0049FAF5 8D45F0 lea eax, dword ptr [ebp-10] :0049FAF8 E8172FF6FF call 00402A14 :0049FAFD 8D45EC lea eax, dword ptr [ebp-14] :0049FB00 8B55FC mov edx, dword ptr [ebp-04] :0049FB03 8A520B mov dl, byte ptr [edx+0B] <-- get the 12th byte of serial :0049FB06 885001 mov byte ptr [eax+01], dl :0049FB09 C60001 mov byte ptr [eax], 01 :0049FB0C 8D55EC lea edx, dword ptr [ebp-14] :0049FB0F 8D45F0 lea eax, dword ptr [ebp-10] :0049FB12 B102 mov cl, 02 :0049FB14 E8CB2EF6FF call 004029E4 :0049FB19 8D55F0 lea edx, dword ptr [ebp-10] :0049FB1C 8D45CC lea eax, dword ptr [ebp-34] :0049FB1F E87C42F6FF call 00403DA0 :0049FB24 8B45CC mov eax, dword ptr [ebp-34] :0049FB27 E8C88EF6FF call 004089F4 :0049FB2C 3BD8 cmp ebx, eax <-- compare :0049FB2E 7404 je 0049FB34 <-- jump to good_boy if equals :0049FB30 33DB xor ebx, ebx :0049FB32 EB02 jmp 0049FB36 <-- jump to ret with bad_boy value * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0049FB2E(C) | :0049FB34 B301 mov bl, 01 <-- set good_boy value --- snipped out to save space, its useless anyway --- :0049FB6B C3 retWow, lots of code. I myself wasn't able to understand at first, but after struggling for more than 1 hour I finally got it(I'm lame, you know?). It adds up all the value of the 2nd, 3rd, 4th, 5th, 6th and 7th byte of serial and store it in ebx(those bytes are used in its char form that we used in our normal life : 1 + 1 + 1 + 9 +9 + 7 = 28 decimal), for eax it does string concatenation and conversion into integer form of the 9th and the 12th byte of serial("1" + "2" = "12" = 12 decimal) and then it compare both of them. To pass this final and bitchy check, just simply replace the 9th byte of serial with 2 and the 12th byte of serial into 8. The final valid serial will be:
M11199782K28
Try it and you will be thanked for registering. There are some other minor checks like for example the 7th and the 4th byte of serial must be integer value(0-9) which I didn't mention, it shall be your work if you wish to fully crack this program. Here's the explanation of its protection in a nutshell:
1st char = CharOf(IntegerOf(StringOf(7th char)+StringOf(4th char)) + 6), only A-Z characters are valid
2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 11th chars = Anything but 7th and 4th chars must be integer numbers(0-9) and there might still be some other checks which you must find out yourself
9th char = FirstCharOf(StringOf(IntegerOf(2nd char + 3rd char + 4th char + 5th char + 6th char + 7th char)))
10th char = CharOf((IntegerOf(StringOf(3rd char) + StringOf(2nd char))) + 64)
12th char = SecondCharOf(StringOf(IntegerOf(2nd char + 3rd char + 4th char + 5th char + 6th char + 7th char)))
IntegerOf = the integer value(not ascii value) of something
StringOf = the value of an integer(not ascii value) treated as string
FirstCharOf = first character of a string
CharOf = the ascii character of a number
SecondCharOf = second character of a string
By the way, did you take note of something which I asked you to at the beginning of the tutorial? It is this line which is the beginning of the serial verification call:
* Referenced by a CALL at Addresses:
|:0049AF69 , :0049FC29
Hmm, the serial verification call referenced by two calls? One should be when we register and another should be during the startup of the program. I guess its also possible for you to patch this call to crack this protection. How to patch? Since this call is important for returning al's value which should be either 0 or 1, you should use HIEW to load the executable, go to the beginning of the call and insert the following instruction(F3, then F2):
mov al, 1 <-- opcode B001
retn <-- opcode C3
Press F9 to save and F10 to exit HIEW. Now, try to load up that patched executable. Its cracked. I should have end this tutorial now, but as a cracker, I think I could do more than this. What? Probably a keygen or brute-forcer. Is it possible? That's my question too previously and thanks a lot to ^tCM^'s explanation, help and encouragement, below is a source of a keygen/brute-forcer for Auto-IP Publisher 2.32 coded in Turbo Pascal 7.0 by me. It should also compile on any other compatible Pascal compilers. Sorry, this time I didn't comment my codes(I'm running out of time, sorry) but if you are really interested in it, I will comment it for you anytime you want(just mail and ask me, ok?).
Program keygen ; uses crt ; var temp1, temp2, char1, char10, temp3, temp4, char9, char11, char8, char12, temp7, temp5, temp6, fixed : string ; tempo1, tempo2, i, tempo3, tempo4, tempo5, tempo6, tempo7, tempo8, tempo9, tempo10, tempo11 : longint ; e, random1, random2 : integer ; tempfile : text ; Begin clrscr ; Writeln('++++++++++++++++++++++++++++++++++++++++++++++++++') ; Writeln('+ KeyGen/Brute-Forcer for Auto-IP Publisher 2.32 +') ; Writeln('+ by ManKind on 11th June 2000 +') ; Writeln('+ Service for Mankind +') ; Writeln('+ mankind001@bigfoot.com +') ; Writeln('++++++++++++++++++++++++++++++++++++++++++++++++++') ; assign(tempfile, 'serials.txt') ; rewrite(tempfile) ; close(tempfile) ; Writeln('Please be patient. Saving serials...') ; for i := 1 to 150 do begin randomize ; tempo1 := 1000+random(9999-1000); tempo1 := tempo1 * 98 ; Str(tempo1, temp1) ; temp2 := Chr(Ord(temp1[6])) + Chr(Ord(temp1[3])) ; Val(temp2, tempo2, e) ; char1 := Chr(tempo2+6) ; temp3 := Chr(Ord(temp1[2])) + Chr(Ord(temp1[1])) ; Val(temp3, tempo3, e) ; char10 := Chr(tempo3+64) ; Val(temp1[1], tempo5, e) ; Val(temp1[2], tempo6, e) ; Val(temp1[3], tempo7, e) ; Val(temp1[4], tempo8, e) ; Val(temp1[5], tempo9, e) ; Val(temp1[6], tempo10, e) ; tempo4 := tempo5 + tempo6 + tempo7 + tempo8 + tempo9 + tempo10 ; Str(tempo4, temp5) ; char9 := Chr(Ord(temp5[1])) ; char12 := Chr(Ord(temp5[2])) ; fixed := 'qOH0Uwke8ZNC61nGM4tS5BAmRLlopr9abcWPJKxy7FIhguvTDLXjsXY2V3dfizQ' ; random1 := random(63) + 1 ; random2 := random(63) + 1 ; char8 := Chr(Ord(fixed[random1])) ; randomize ; delay(150) ; char11 := Chr(Ord(fixed[random2])) ; temp7 := char1 + temp1 + char8 + char9 + char10 + char11 + char12 ; tempo11 := Ord(temp7[1]) ; If (Length(temp7) = 12) then If (tempo11 > 59) and (tempo11 < 91) then begin append(tempfile) ; writeln(tempfile, temp7) ; close(tempfile) ; delay(150) ; end; end ; Writeln('All serials have been saved to serials.txt file. Press enter to exit to system') ; readln ; end. |
This program could at least(and I mean AT LEAST) generate few hundreds of valid serials for Auto-IP Publisher 2.32. It will add new serials to serials.txt file everytime it is run. I also notice that its quite slow, but it does it work, so, just be patient for about 1-2 minutes and do something else while it does its work in the background. Turbo Pascal is my best bet now since my Visual Basic and Visual C++ is not with me(and QBasic is not better than Pascal while Borland Delphi is not too suitable here). Hope to see you soon on my next tutorial. As usual, contact me if I make any mistake, give me your feedback, comments, suggestions and opinions about this tutorial and my way of presenting it.
Extra notes:
I am quite satisfied cracking and writing this tutorial. I would not write anymore lame tutorial in the future but will only write tutorials on interesting protections because I need more time(as if 24 hours a day is not enough) to concentrate on my real-life, my family, my education, my friend, my happiness, my love, etc. which I have just found out IS the MOST IMPORTANT thing of one's life... That's all for now.
Ending:
Thanks and greetz to:
+ORC, +HCU, Sandman, HarvestR, tKC, ytc_, Punisher, Kwai_Lo, TORN@DO,
CrackZ, cLUSTER, LaZaRuS, mISTER fANATIC, yes123, WhizKiD, Volatility,
ACiD BuRN, Eternal Bliss, R!SC, Kwazy Webbit, +Mammon, MisterE, Shadow,
^tCM^, WaJ, Borna Janes, Kathras, tsehp, AB4DS(Death), douby, Steinowitz, Lord Soth, Latigo, Lucifer48, NeuRaL_NoiSE, Fravia+, [dshadow], Latigo, Duelist, Alpine, flag eRRatum, Nitrus, +Frog's Print, Muad`Dib, Acid_Cool_178, Iczelion, Razzia, Warezpup, Bomber Monkey, llama and other crackers, individuals and organisations who have helped me, either directly or indirectly.
Service for Mankind
ManKind
mankind001@bigfoot.com