home *** CD-ROM | disk | FTP | other *** search
Wrap
************************************************************************************************************************************************************************************* Keygenning4Newbies KeygenMe #3 ************************************************************************************************************************************************************************************* Author: Seifer[ECLiPSE/HellForge] Protection: Name / Serial URL: http://www.leelouonline.com/users/bofh/k4n/k4n3.zip Tools: SoftICE 4.05 ---> Intro... Ok, my next tutorial about "Keygenning4Newbies "KeygenMe" #3. I think this CrackMe is very good for Newbies it has some little trick ;) Anyway i'm showing you now the algo and stuff related ;) ---> Let's begin... Ok, open the CrackMe and it'll ask you for a Name and Serial i've used: Name: CoDe_InSiDe Serial: 1234567890 Then get into SoftICE (CTRL+D) and type "bpx hmemcpy" followed by "enter" and out of SoftICE (CTRL+D). Then press "Check !" and SoftICE should popup, then press (F12) 9 times and you'll see this: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :004011D1 8BF0 mov esi, eax <--- Move the length of our Name in ESI :004011D3 85F6 test esi, esi <--- Test if ESI is 00 (have we entered a Name ?) :004011D5 0F844B010000 je 00401326 <--- If it's 00 (no Name entered) we jump to the Bad Guy message, else continue :004011DB 83FE40 cmp esi, 00000040 <--- Compare ESI with 40 (64 Decimal) :004011DE 0F8742010000 ja 00401326 <--- If more then 40 (64 Decimal) we jump to the Bad Guy message, else continue :004011E4 8B4508 mov eax, dword ptr [ebp+08] :004011E7 8D5594 lea edx, dword ptr [ebp-6C] <--- This will be the place where our "Fake" Serial will be stored :004011EA 6A13 push 00000013 <--- Push 13 maximum string size to be copied from our "Fake" Serial :004011EC 52 push edx * Possible Reference to Dialog: DialogID_0065, CONTROL_ID:03E9, "" | :004011ED 68E9030000 push 000003E9 :004011F2 50 push eax :004011F3 FFD7 call edi <--- Call GetDlgItemTextA :004011F5 6BC003 imul eax, 00000003 <--- Multiply our "Fake" Serial length with 3 ? :004011F8 C1E002 shl eax, 02 <--- Shift EAX to the left with 2 ? :004011FB 05CD000000 add eax, 000000CD <--- Add 000000CD to EAX ? :00401200 8945FC mov dword ptr [ebp-04], eax <--- Store EAX in memory (EBP-04) :00401203 817DFCA5010000 cmp dword ptr [ebp-04], 000001A5 <--- Compare the result with 000001A5 :0040120A 0F85BC000000 jne 004012CC <--- If not equal we jump and get the Bad Guy message ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- As you see here it Compares the length of our entered Name with 00 and 40, so you need to enter a Name between 1 and 64 Characters, remember this for programming a KeyGen :) Ok, now it does something weird with the length of our "Fake" Serial. i'll explain: The length of my "Fake" Serial was 0A (10 Decimal) Then it multiplies with 03 ---> Result = 0000001E Then it Shifts EAX to the left with 02 ---> Result = 00000078 Then it ADDs 000000CD to EAX ---> Result = 00000145 And then it Compares EAX with 000001A5 Hmm... Now how are we going to solve this, we're going to Reverse the process :) The final Result must be 000001A5, so then we SUB 000000CD (it's the opposite of ADD) from it and you'll get 000000D8. Then we divide it by 04 (shl eax, 02 is the same as multiply with 4) and we'll get 00000036. Then we're going to divide it by 03 (opposite of Multiply) and the final result is 00000012. So we need to enter a Serial of 18 Characters (12 = 18 Decimal). Ok change the "Fake" Serial and get back to this place then you'll see this after the JNE: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :00401210 33C0 xor eax, eax <--- XOR EAX, which is now 00 :00401212 8A4594 mov al, byte ptr [ebp-6C] <--- Move first Char of our "Fake" Serial in AL :00401215 84C0 test al, al <--- Test if AL is 00 :00401217 7413 je 0040122C <--- If so we jump to the next stuff, else continue :00401219 8D4D94 lea ecx, dword ptr [ebp-6C] <--- Point ECX to our "Fake" Serial * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040122A(C) | :0040121C 3C30 cmp al, 30 <--- Compare first Char (in AL) with 30 (0) :0040121E 0F82C6000000 jb 004012EA <--- If lower then 30 (0) we jump and get the Bad Guy message, else continue :00401224 8A4101 mov al, byte ptr [ecx+01] <--- Move next Char in AL :00401227 41 inc ecx <--- ECX +1 :00401228 84C0 test al, al <--- Test if AL is 00 :0040122A 75F0 jne 0040121C <--- If equal we continue to the next stuff, else we jump and repeat the loop * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401217(C) | :0040122C E8CFFDFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI :00401231 8D852CFFFFFF lea eax, dword ptr [ebp+FFFFFF2C] <--- EAX now points to our Name :00401237 50 push eax <--- Save the offset in EAX :00401238 E843FEFFFF call 00401080 <--- Here it generates a unique value to our Name !!! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, so in here it first checks if your Serial has Characters that are equal or more then 30 (0), if so we continue, else we get the Bad Guy message. Now step into the CALL 00401080 to see what it's going to do with our Name =) and you'll see this: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :00401080 55 push ebp :00401081 8BEC mov ebp, esp :00401083 51 push ecx :00401084 53 push ebx :00401085 56 push esi :00401086 57 push edi * Possible StringData Ref from Data Obj ->"eheh" | :00401087 6880504000 push 00405080 <--- Suspicious :) :0040108C 6A00 push 00000000 <--- Push 00 :0040108E E8ADFFFFFF call 00401040 <--- In here it moves "eheh" in EAX :00401093 83C408 add esp, 00000008 <--- Prepare ESP for pushes :00401096 8BD8 mov ebx, eax <--- Move EAX in EBX :00401098 E863FFFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI * Possible StringData Ref from Data Obj ->" is a whore." | :0040109D BF70504000 mov edi, 00405070 <--- Suspicious :) :004010A2 83C9FF or ecx, FFFFFFFF <--- Prepare ECX for counting :004010A5 33C0 xor eax, eax <--- XOR EAX which is now 00 :004010A7 F2AE repnz scasb <--- Let the count begin :) :004010A9 F7D1 not ecx <--- NOT ECX (sort of Reverse the value :) :004010AB 2BF9 sub edi, ecx <--- Sub ECX from EDI :004010AD 8BF7 mov esi, edi <--- Move EDI in ESI :004010AF 8B7D08 mov edi, dword ptr [ebp+08] <--- Move the offset to our Name in EDI :004010B2 8BD1 mov edx, ecx <--- Move ECX in EDX :004010B4 83C9FF or ecx, FFFFFFFF <--- Prepare ECX for counting :004010B7 F2AE repnz scasb <--- Let the count begin :) :004010B9 8BCA mov ecx, edx <--- Move EDX in ECX :004010BB 4F dec edi <--- EDI -1 :004010BC C1E902 shr ecx, 02 <--- Shift ECX to the right with 02 :004010BF F3A5 repz movsd <--- Place the string " is a whore" behind our Name :004010C1 8BCA mov ecx, edx <--- Move EDX in ECX :004010C3 83E103 and ecx, 00000003 <--- AND ECX 00000003 :004010C6 F3A4 repz movsb <--- Place the rest of the string " is a whore" behind our Name :004010C8 33FF xor edi, edi <--- XOR EDI which is now 00 :004010CA 33F6 xor esi, esi <--- XOR ESI which is now 00 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, in the first CALL it puts the String "eheh" in EAX so the result in EAX is then "68656865" (hehe always reverse). Then it moves that value in EBX. After this it moves the string " is a whore" behind our Name, remember this all for programming a KeyGen :) For my Name it would be now: CoDe_InSiDe is a whore <--- thx :P Anyway let's see what's next: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004010F6(C) | :004010CC 8B4508 mov eax, dword ptr [ebp+08] <--- Move the offset to our Name in EAX :004010CF 50 push eax <--- Save EAX :004010D0 56 push esi <--- Save ESI :004010D1 E86AFFFFFF call 00401040 <--- In here it puts the first 4 Chars of our Name in EAX (in reverse) :004010D6 8B8E30504000 mov ecx, dword ptr [esi+00405030] <--- Move "ESI+00405030" in ECX ??? :004010DC 83C408 add esp, 00000008 <--- Prepare ESP for pushes :004010DF 33CF xor ecx, edi <--- XOR EDI with ECX (EDI is 00 at the beginning) :004010E1 03C1 add eax, ecx <--- ADD ECX to EAX :004010E3 8945FC mov dword ptr [ebp-04], eax <--- Save EAX in memory (EBP-04) :004010E6 C145FC07 rol dword ptr [ebp-04], 07 <--- Rotate the value in (EBP-04) with 07 :004010EA 8B45FC mov eax, dword ptr [ebp-04] <--- Move the value from (EBP-04) in EAX :004010ED 83C604 add esi, 00000004 <--- ESI +4 :004010F0 33D8 xor ebx, eax <--- XOR EAX with EBX :004010F2 47 inc edi <--- EDI +1 :004010F3 83FE40 cmp esi, 00000040 <--- Compare ESI with 40 :004010F6 7CD4 jl 004010CC <--- If lower we jump and continue the loop, else continue and we got our unique value for our Name :004010F8 5F pop edi :004010F9 8BC3 mov eax, ebx <--- Move our unique value in EAX :004010FB 5E pop esi :004010FC 5B pop ebx :004010FD 8BE5 mov esp, ebp :004010FF 5D pop ebp :00401100 C3 ret ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, let me explain this piece: First it points EAX to our Name. Then in the CALL 00401040 it takes the first 4 Chars of our Name and puts it in Reverse in EAX, so i would have then EAX = 65446F43 (eDoC) Then it moves "ESI+00405030" in ECX (ESI is 00 at the beginning). if you look at the offset 00405030 you'll see a Table of numbers remember these numbers for programming a KeyGen :) Then it XORs EDI with ECX (EDI is 00 at the beginning and ECX holds a number from the Table). And then it ADDs ECX (Number from the Table) to EAX (Our first 4 Chars) Then it moves the new value in EAX in EBP-04. Then it Rotates the value in EBP-04 with 07. And then it moves that value back in EAX. Increase ESI with 04. And then XOR EAX (our New value) with EBX (eheh in reverse remember). Increase EDI with 01. Compare ESI with 40 If ESI is lower then 40 it repeats this loop and takes everytime the next 4 Chars of our Name, else it continues and we have our unique value :) Ok, code this all in "YOUR" language for the KeyGen :) I'll explain the table later and stuff so Let's see what's next when we return to the main Code: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :0040123D 8945FC mov dword ptr [ebp-04], eax <--- Save our unique value in EBP-04 :00401240 E8BBFDFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI :00401245 8D8D2CFFFFFF lea ecx, dword ptr [ebp+FFFFFF2C] <--- Point ECX to our Name :0040124B 56 push esi <--- Save ESI :0040124C 51 push ecx <--- Save ECX :0040124D E8BEFDFFFF call 00401010 <--- And here it removes the string " is a whore" from our Name :00401252 83C40C add esp, 0000000C <--- Prepare ESP for pushes :00401255 33C9 xor ecx, ecx <--- XOR ECX which is now 00 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401284(C) | :00401257 8B45FC mov eax, dword ptr [ebp-04] <--- Move our unique value in EAX :0040125A 33D2 xor edx, edx <--- XOR EDX which is now 00 :0040125C BE1A000000 mov esi, 0000001A <--- Move 0000001A in ESI :00401261 F7F6 div esi <--- Divide EAX with ESI :00401263 8A941510FFFFFF mov dl, byte ptr [ebp+edx-000000F0] <--- Move (EBP+Remainder-000000F0) in DL :0040126A 88540DC8 mov byte ptr [ebp+ecx-38], dl <--- Move DL in (EBP+ECX-38) :0040126E 8B45FC mov eax, dword ptr [ebp-04] <--- Move our unique value in EAX :00401271 C1E003 shl eax, 03 <--- Shift EAX to the left with 03 :00401274 BA45230100 mov edx, 00012345 <--- Move 00012345 in EDX :00401279 F7E8 imul eax <--- Sort of multiply EAX with EDX :0040127B 03C2 add eax, edx <--- ADD EDX to EAX :0040127D 8945FC mov dword ptr [ebp-04], eax <--- Move EAX in EBP-04 :00401280 41 inc ecx <--- ECX +1 :00401281 83F912 cmp ecx, 00000012 <--- Compare ECX with 12 :00401284 72D1 jb 00401257 <--- If below we repeat the loop, else continue and we have a string made out of our Name (unique value) :00401286 E875FDFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI :0040128B 33C0 xor eax, eax <--- XOR EAX which is now 00 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This is some interesting piece of Code :) Here it makes a string out of our unique number. Let me explain: First it moves our unique value in EAX. Then it moves 0000001A in ESI and divides EAX with it. Then it moves a Char from the string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in DL, which Char it is depends on the remainder. And then it moves DL to some place. Then it moves our unique number in EAX Then it Shifts EAX to the left with 03 and moves 00012345 in EDX. And then it sort of multiplies EAX with EDX and ADD the result in EDX in EAX. Then save the new value in EAX in EBP-04 Increase ECX with 01 Compare ECX with 12 If lower we jump and repeat the loop else we made the string and continue Remember this all again for YOUR selfmade KeyGen :) Better write down the String that has been generated now... Now comes the Smart Part :) You'll see this after the "xor eax, eax": ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004012A2(C) | :0040128D 8A4C0594 mov cl, byte ptr [ebp+eax-6C] <--- Move first Char of our "Fake" Serial in CL :00401291 8A5405C8 mov dl, byte ptr [ebp+eax-38] <--- Move first Char of our New String in DL :00401295 80E930 sub cl, 30 <--- SUB 30 from CL :00401298 32D1 xor dl, cl <--- XOR CL with DL :0040129A 885405C8 mov byte ptr [ebp+eax-38], dl <--- Move DL in the same place in our New String :0040129E 40 inc eax <--- EAX +1 :0040129F 83F812 cmp eax, 00000012 <--- Compare EAX with 12 :004012A2 72E9 jb 0040128D <--- If below we repeat the loop, else continue :004012A4 E857FDFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI :004012A9 8D55C8 lea edx, dword ptr [ebp-38] <--- Point EDX to our New String :004012AC 52 push edx <--- Save EDX :004012AD E85EFEFFFF call 00401110 <--- Check out this CALL !!! :004012B2 E849FDFFFF call 00401000 <--- In here it XORs all Registers except EBX, ESP, EBP, ESI, EDI ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, so here it allready XORs our "Fake" Serial with the newly created String... ? Remember this stuff. let's see what's next in the CALL 00401110: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :00401110 8B4C2404 mov ecx, dword ptr [esp+04] <--- Move the offset to our New String in ECX :00401114 33C0 xor eax, eax <--- XOR EAX which is now 00 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401122(C) | :00401116 8A1408 mov dl, byte ptr [eax+ecx] <--- Move the first Char in DL :00401119 32D0 xor dl, al <--- XOR AL with DL :0040111B 881408 mov byte ptr [eax+ecx], dl <--- Move DL in the same place in our New String :0040111E 40 inc eax <--- EAX +1 :0040111F 83F812 cmp eax, 00000012 <--- Compare EAX with 12 :00401122 72F2 jb 00401116 <--- If below we repeat this loop, else continue :00401124 C3 ret ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, so here it XORs the value's of our New String with EAX counting... let me show you: My New String ---> "DUBKCQDEJYQCUZOHQW" <--- String before it was XORed with our "Fake" Serial, you'll soon notice why i did it like this :) Ascii D U B K C Q D E J Y Q C U Z O H Q W Hex 44 55 42 4B 43 51 44 45 4A 59 51 43 55 5A 4F 48 51 57 XOR with 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 ----------------------------------------------------- Result 44 54 40 48 47 54 42 42 42 50 5B 48 59 57 41 47 41 46 (DT@HGTBBBP[HYWAGAF) Ok, its not so difficult let's see what we get when we RETurn: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :004012B7 8D45C8 lea eax, dword ptr [ebp-38] <--- EAX now points to our New String * Possible StringData Ref from Data Obj ->"KEYGENNING4NEWBIES" | :004012BA 6814514000 push 00405114 <--- Suspicious :) :004012BF 50 push eax <--- Save EAX :004012C0 E86BFEFFFF call 00401130 <--- Check out this CALL !!! :004012C5 83C40C add esp, 0000000C <--- Prepare ESP for pushes :004012C8 85C0 test eax, eax <--- Test EAX if its 00 :004012CA 753C jne 00401308 <--- If so we continue and get the Bad Guy message, else we jump and get the Good Guy message :) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, not much to say about this just check the CALL 00401130 and you'll see this: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :00401130 8B442408 mov eax, dword ptr [esp+08] <--- EAX now points to "KEYGENNING4NEWBIES" :00401134 53 push ebx <--- Save EBX :00401135 56 push esi <--- Save ESI :00401136 8B74240C mov esi, dword ptr [esp+0C] <--- ESI now points to our New String :0040113A 33C9 xor ecx, ecx <--- XOR ECX which is now 00 :0040113C 2BF0 sub esi, eax <--- SUB EAX from ESI (this is just a little bit too confuse you :) * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040114C(C) | :0040113E 8A1406 mov dl, byte ptr [esi+eax] <--- Move the first Char of our New String in DL :00401141 8A18 mov bl, byte ptr [eax] <--- Move the first Char of the string "KEYGENNING4NEWBIES" :00401143 3AD3 cmp dl, bl <--- Compare BL with DL :00401145 750F jne 00401156 <--- If not equal jump and XOR EAX so that we fail, else continue :00401147 41 inc ecx <--- ECX +1 :00401148 40 inc eax <--- EAX +1 :00401149 83F912 cmp ecx, 00000012 <--- Compare ECX with 12 :0040114C 72F0 jb 0040113E <--- If below repeat this loop, else continue :0040114E 5E pop esi :0040114F B801000000 mov eax, 00000001 <--- Move 00000001 in EAX (Good Thing) :00401154 5B pop ebx :00401155 C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401145(C) | :00401156 5E pop esi :00401157 33C0 xor eax, eax <--- XOR EAX which is now 00 (Bad Thing) :00401159 5B pop ebx :0040115A C3 ret ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, this is the place where it Compares "KEYGENNING4NEWBIES" with our New String :) Now how do we get a valid Serial for this ???... we're just going to reverse the process :) some info: It creates a New String out of our Name, for me it was ---> DUBKCQDEJYQCUZOHQW Then it XORs with our "Fake" Serial (All Chars of "Fake" Serial -30) Then it XORs with EAX counting... And then Compares with "KEYGENNING4NEWBIES" So what i did was: 1. Take the string "KEYGENNING4NEWBIES" and XOR it with EAX counting... 2. Then XOR it with my New String ---> DUBKCQDEJYQCUZOHQW 3. And finally ADD 30 to all Chars, why? because it SUBs -30 from all the Chars ("Fake" Serial XOR routine) Result: 1. KD[DAKHNFN>EIZLFUB 2. 0F 11 19 0F 02 1A 0C 0B 0C 17 6F 06 1C 00 03 0E 04 15 (Hex) 3. ?AI?2J<;<Gƒ6L03>4E So finally i got this info: Name: CoDe_InSiDe Serial: ?AI?2J<;<Gƒ6L03>4E Now some other info: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Magic value to begin with making our unique value: eheh (Hex = 65686568) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- An extra string to add by our Name: is a whore. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Table for making our unique value: 12 00 00 00 5C 00 00 00 34 00 00 00 22 00 00 00 AB 00 00 00 9D 00 00 00 54 00 00 00 00 00 00 00 DD 00 00 00 84 00 00 00 AE 00 00 00 66 00 00 00 31 00 00 00 78 00 00 00 73 00 00 00 CF 00 00 00 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- String to make our New String: ABCDEFGHIJKLMNOPQRSTUVWXYZ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, i think that's it, pretty big Tutorial and i hope you learned something from it :) I think you can make a KeyGen in YOUR Language ;) Anyway Thank You for reading this Tutorial and Good luck with keygenning (if you haven't done allready :) Btw, remember "NO ASM RIPPING ALLOWED" ;) ---> Greetings... Everyone from TrickSoft (www.TrickSoft.net) Everyone from Cracking4Newbies (www.Cracking4Newbies.com) Everyone from Keygenning4Newbies :P (Keygenning4Newbies.cjb.net) And Everyone i know and You... Thanks for reading ! Don't trust the Outside, trust the InSiDe !!! Cya... CoDe_InSiDe Email: code.inside@home.nl