*********************************************************************************************************************************************************** Keygenning4Newbies KeygenMe 4 *********************************************************************************************************************************************************** Author: Andox Protection: Name / Serial URL: http://www.leelouonline.com/users/bofh/k4n/kac.zip Tools: SoftICE 4.05 ---> Intro... An old CrackMe but fun to do :), it has some nice little tricks... Great for practicing :P ---> Let's Begin... Open the CrackMe and you'll see some black screen and a "File - Help" menu. Now go to the Register Dialog by either clicking in the Main Window or selecting "Help/Register". There you can enter a Name and Serial, just fill something in, i've used: Name: CoDe_InSiDe Serial: 1234567890 Now get into SoftICE (CTRL+D) and type "bpx hmemcpy" followed by "enter" and out of SoftICE (CTRL+D). - *BOOM* - SoftICE popups immediately... Hmmm...Ok...let's continue... Now disable the breakpoint by typing "BC *" and press (F12) 9 times and you'll see this: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004015CB 83F805 cmp eax, 00000005 <--- Compare EAX with 05 (Length of Name) :004015CE 726B jb 0040163B <--- If below we jump and fail, else continue :004015D0 BED4204000 mov esi, 004020D4 <--- Offset to our Name in ESI :004015D5 8BC8 mov ecx, eax <--- Move EAX in ECX :004015D7 33C0 xor eax, eax <--- XOR EAX which is now 00 :004015D9 8BC6 mov eax, esi <--- Move ESI in EAX * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004015E6(C) | :004015DB 660FBE1E movsx bx, byte ptr [esi] <--- Move first Char in BX :004015DF 03D8 add ebx, eax <--- ADD EAX to EBX :004015E1 0FAFC3 imul eax, ebx <--- Multiply EBX with EAX :004015E4 46 inc esi <--- ESI +1 :004015E5 49 dec ecx <--- ECX -1 :004015E6 75F3 jne 004015DB <--- If ECX is 00 continue, else repeat loop ----------------------------------------------------------------------------------------------------------------------------------------------------------- Doesn't look so though :) It just puts the first Char in BX, ADDs EAX to EBX, Multiplies EBX with EAX, and then repeats this loop till all Chars done. Notice the weird numbers in the Registers? like ESI was moved to EAX and contains the offset to our Name... Ok, let's see what's next: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004015E8 0505721800 add eax, 00187205 <--- ADD 00187205 to EAX ??? :004015ED 50 push eax <--- Save EAX :004015EE 6A3C push 0000003C <--- Push the maximum string length to be copied from our "Fake" Serial :004015F0 68D4204000 push 004020D4 <--- Offset to our "Fake" Serial * Possible Reference to Dialog: DialogID_0064, CONTROL_ID:0068, "" | :004015F5 6A68 push 00000068 :004015F7 FF7508 push [ebp+08] * Reference To: USER32.GetDlgItemTextA, Ord:0000h | :004015FA E8AB000000 Call 004016AA ----------------------------------------------------------------------------------------------------------------------------------------------------------- Hmmm... a weird value has been ADDed to EAX (00187205). And it takes our "Fake" Serial and puts it in 004020D4. Let's see what's next: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004015FF 5A pop edx <--- EDX now holds the value created out of our Name :00401600 BFD4204000 mov edi, 004020D4 <--- Move 004020D4 in EDI (points to our "Fake" Serial) :00401605 660FBE4701 movsx ax, byte ptr [edi+01] <--- Put the "Second" Char of our "Fake" Serial in AX :0040160A 3BC2 cmp eax, edx <--- Compare EDX with EAX :0040160C 752D jne 0040163B <--- If not equal we jump and fail, else continue :0040160E 83F841 cmp eax, 00000041 <--- Compare 41 (A) with EAX :00401611 7228 jb 0040163B <--- If below we jump and fail, else continue :00401613 83F85A cmp eax, 0000005A <--- Compare 5A (Z) with EAX :00401616 7723 ja 0040163B <--- If above we jump and fail, else continue :00401618 BED4204000 mov esi, 004020D4 <--- Move 004020D4 in ESI (Points to our "Fake" Serial) :0040161D 33FF xor edi, edi <--- XOR EDI which is now 00 :0040161F 3BD0 cmp edx, eax <--- Compare EAX with EDX ??? :00401621 7418 je 0040163B <--- If equal we jump and fail, else continue :00401623 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Registerd" | :00401625 688D214000 push 0040218D <--- This looks nice :) * Possible StringData Ref from Data Obj ->"Program registerd (good work) " ->":)" | :0040162A 6897214000 push 00402197 <--- This looks nice :) :0040162F 6A00 push 00000000 * Reference To: USER32.MessageBoxA, Ord:0000h | :00401631 E8FE000000 Call 00401734 :00401636 E94DFFFFFF jmp 00401588 <--- Jump to the end ----------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, this looks like a normal Registration routine but you probably noticed something strange :) Because as you see the "cmp eax, edx" at the top, well that looks ok. If it's not equal we jump and fail else we continue, but if you look a little further down then you'll see a "cmp edx, eax" ??? If equal we jump and fail, So in this piece of Code we will ALWAYS fail :P Hmmm... tricky... Ok, what now ??? I suggest to get out of SoftICE and then click "Give up" to close the Register Dialog, why??? Well we know that when we put a breakpoint, SoftICE immediately popups and we haven't even clicked on the "Register" button :/ And the "Registration Routine" we come in then isn't the right way. So i thought of something... Now your looking at the Main Window, if you click in it we get the Register Dialog, don't click yet :) Ok, now get into SoftICE (CTRL+D) and type "bpx hmemcpy" followed by "enter" and then (CTRL+D) again to get out of SoftICE. Now click in the Main Window and immediately on the "Register" button and SoftICE should popup. ---> There's also some nice thing here :) try putting a breakpoint on "GetDlgItemTextA" and your in for a surprise :P <--- Now press (F12) 9 times and you'll see this: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004013E7 83F805 cmp eax, 00000005 <--- Compare EAX with 05 (Length of our Name) :004013EA 0F8263010000 jb 00401553 <--- If below we jump and fail, else continue :004013F0 A394224000 mov dword ptr [00402294], eax <--- Save the length of our Name in 00402294 :004013F5 BF98264000 mov edi, 00402698 <--- Move 00402698 in EDI :004013FA B9B7000000 mov ecx, 000000B7 <--- Move 000000B7 in ECX :004013FF 33C0 xor eax, eax <--- XOR EAX which is now 00 :00401401 F3AA repz stosb <--- Place 00 in EDI, EDI +1, till ECX is 00 * Possible StringData Ref from Data Obj ->" " ->" " | :00401403 BF12274000 mov edi, 00402712 <--- Move 00402712 in EDI * Possible StringData Ref from Data Obj ->" " ->" " | :00401408 BED5264000 mov esi, 004026D5 <--- Move 004026D5 in ESI ----------------------------------------------------------------------------------------------------------------------------------------------------------- Here it Compares our length with 05, if we continue it'll jump and we fail because we haven't entered our Name (We couldn't otherwise we end up in the bad Registration Routine). So when your on the "jb 00401553" type "r fl c" followed by "enter" and we can continue. Then it fills a place with 00. Now comes the big Algo :) ----------------------------------------------------------------------------------------------------------------------------------------------------------- :0040140D C7059B2740003FA7DF89 mov dword ptr [0040279B], 89DFA73F <--- Move 89DFA73F in 0040279B :00401417 BA788A3F02 mov edx, 023F8A78 <--- Move 023F8A78 in EDX :0040141C 8B0D94224000 mov ecx, dword ptr [00402294] <--- Move the length of our Name in ECX :00401422 BFAC164000 mov edi, 004016AC <--- Move 004016AC in EDI :00401427 8B3F mov edi, dword ptr [edi] <--- Move [EDI] in EDI :00401429 8B3F mov edi, dword ptr [edi] <--- Move [EDI] in EDI :0040142B 8B3F mov edi, dword ptr [edi] <--- Move [EDI] in EDI :0040142D 8BD9 mov ebx, ecx <--- Move ECX in EBX :0040142F 331D9B274000 xor ebx, dword ptr [0040279B] <--- XOR (89DFA73F) with EBX :00401435 03DA add ebx, edx <--- ADD EDX to EBX :00401437 33DA xor ebx, edx <--- XOR EDX with EBX :00401439 55 push ebp <--- Save EBP * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004014A5(C) | :0040143A A194224000 mov eax, dword ptr [00402294] <--- Move the length of our Name in EAX :0040143F E8F9000000 call 0040153D <--- Check out what happens here, important for the keygen :) :00401444 660FBE0406 movsx ax, byte ptr [esi+eax] <--- Move one byte from [ESI+EAX] in AX :00401449 0FAFC2 imul eax, edx <--- Multiply EDX with EAX :0040144C 33C2 xor eax, edx <--- XOR EDX with EAX :0040144E 41 inc ecx <--- ECX +1 :0040144F D3C2 rol edx, cl <--- Rotate EDX to the left by CL :00401451 69C2AEF5B215 imul eax, edx, 15B2F5AE <--- Multiply 15B2F5AE with EDX and put the result in EAX :00401457 49 dec ecx <--- ECX -1 :00401458 D3E8 shr eax, cl <--- Shift EAX to the right by CL :0040145A 7202 jb 0040145E <--- If below we jump and skip one instruction, else continue :0040145C 13C3 adc eax, ebx <--- ADC EBX with EAX * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040145A(C) | :0040145E 40 inc eax <--- EAX +1 :0040145F 4B dec ebx <--- EBX -1 :00401460 33D8 xor ebx, eax <--- XOR EAX with EBX :00401462 52 push edx <--- Save EDX :00401463 B811000000 mov eax, 00000011 <--- Move 00000011 in EAX :00401468 E8D0000000 call 0040153D <--- Check out what happens here, important for the keygen :) :0040146D 5A pop edx <--- Pop EDX :0040146E 331C8553274000 xor ebx, dword ptr [4*eax+00402753] <--- XOR (Some value) with EBX :00401475 93 xchg eax,ebx <--- Switch the Register EBX with EAX :00401476 C1C810 ror eax, 10 <--- Rotate EAX to the right with 10 :00401479 8ADC mov bl, ah <--- Move AH to BL :0040147B 8B2C9D98224000 mov ebp, dword ptr [4*ebx+00402298] <--- Move (Some value) in EBP :00401482 8AD8 mov bl, al <--- Move AL to BL :00401484 032C9D98224000 add ebp, dword ptr [4*ebx+00402298] <--- ADD (Some value) to EBP :0040148B C1C810 ror eax, 10 <--- Rotate EAX to the right with 10 :0040148E 8ADC mov bl, ah <--- Move AH to BL :00401490 332C9D98224000 xor ebp, dword ptr [4*ebx+00402298] <--- XOR (Some value) with EBP :00401497 8AD8 mov bl, al <--- Move AL to BL :00401499 032C9D98224000 add ebp, dword ptr [4*ebx+00402298] <--- ADD (Some value) in EBP :004014A0 33D5 xor edx, ebp <--- XOR EBP with EDX :004014A2 33FA xor edi, edx <--- XOR EDX with EDI :004014A4 49 dec ecx <--- ECX -1 :004014A5 7593 jne 0040143A <--- If ECX is 00 we continue, else we repeat the loop ----------------------------------------------------------------------------------------------------------------------------------------------------------- Ok, this is difficult to explain ;) But at the top it moves a value (89DFA73F) in the address 0040279B, that value will be used for creating an unique value for our Name. I recommend doing this first otherwise you can't find the correct serial for your Name :) ---> type "d 00402294" and then press (ALT+D) now type there the length of your name for me it was: C o D e _ I n S i D e 01 02 03 04 05 06 07 08 09 0A 0B Length = 0B then (ALT+D) again to return to the message window now type "d 004026D5" and press (ALT+D) this is for our Name. Then press TAB and type your Name there. Then (ALT+D) again to return to the message window now type "d 00402712" and press (ALT+D) this is for our "Fake" Serial. Then press TAB and type your "Fake" Serial. <--- There's some Table at location 00402753 you can look at it with an Hex-Editor :) And there's also some other big Table at location 00402298 :) Use them all with your KeyGen. I suggest just to go slowly through this process to understand it all :) Let's see what's next: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004014A7 5D pop ebp :004014A8 8BC7 mov eax, edi <--- Move EDI in EAX :004014AA 50 push eax <--- Save EAX :004014AB 6A3C push 0000003C <--- Push maximum string length to be copied from our "Fake" Serial * Possible StringData Ref from Data Obj ->" " ->" " | :004014AD 6812274000 push 00402712 <--- This is the place for our "Fake" Serial * Possible Reference to Dialog: DialogID_0064, CONTROL_ID:0068, "" | :004014B2 6A68 push 00000068 :004014B4 FF7508 push [ebp+08] * Reference To: USER32.GetDlgItemTextA, Ord:0000h | :004014B7 E8EE010000 Call 004016AA * Possible StringData Ref from Data Obj ->" " ->" " | :004014BC BE12274000 mov esi, 00402712 <--- ESI now points to our "Fake" Serial ----------------------------------------------------------------------------------------------------------------------------------------------------------- And here it takes our "Fake" Serial and puts it in 00402712. Let's see what's next: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004014C1 33C0 xor eax, eax <--- XOR EAX which is now 00 :004014C3 33DB xor ebx, ebx <--- XOR EBX which is now 00 :004014C5 33C9 xor ecx, ecx <--- XOR ECX which is now 00 :004014C7 8A1E mov bl, byte ptr [esi] <--- Move first Char of "Fake" Serial in BL * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004014DE(C) | :004014C9 80EB30 sub bl, 30 <--- Subtract 30 from BL :004014CC 8D0480 lea eax, dword ptr [eax+4*eax] <--- Move [EAX+4*EAX] in EAX :004014CF 03C0 add eax, eax <--- ADD EAX to EAX :004014D1 03C3 add eax, ebx <--- ADD EBX to EAX :004014D3 46 inc esi <--- ESI +1 :004014D4 8A1E mov bl, byte ptr [esi] <--- Move second Char in BL :004014D6 41 inc ecx <--- ECX +1 :004014D7 83F90A cmp ecx, 0000000A <--- Compare ECX with 0000000A :004014DA 7404 je 004014E0 <--- If equal we jump and have put our "Fake" Serial in the Register EAX :004014DC 84DB test bl, bl <--- Test if BL is 00 :004014DE 75E9 jne 004014C9 <--- If so we continue, else repeat the loop ----------------------------------------------------------------------------------------------------------------------------------------------------------- And here the only thing it does is putting our "Fake" Serial in the Register EAX, after the "jne 004014C9" type "? EAX" to see your "Fake" Serial in Decimal format. Now let's see the last stuff: ----------------------------------------------------------------------------------------------------------------------------------------------------------- :004014E0 5A pop edx <--- Pop EDX :004014E1 33D0 xor edx, eax <--- XOR EAX with EDX :004014E3 7505 jne 004014EA <--- If the value in EDX is now 00 we continue as Good Guy, else we jump as Bad Guy ----------------------------------------------------------------------------------------------------------------------------------------------------------- And here it XORs EAX ("Fake" Serial) with EDX (Our "Real" Serial). So type here "? EDX" to see your "Real" Serial in Decimal format. That's it. I think i need to tell you that i'm not very good at explaining how to KeyGen something :) sorry about this... But i hope you can KeyGen it in YOUR language, and i hope that you learned something from this. And don't forget to use that little trick with "GetDlgItemTextA" i told you :) If you have any questions or something send them to: code.inside@home.nl ---> Greetings... Everyone from TrickSoft (www.TrickSoft.net) Everyone from Cracking4Newbies (www.Cracking4Newbies.com) Everyone from Keygenning4Newbies (Keygenning4Newbies.cjb.net) And You... Don't trust the Outside, trust the InSiDe !!! Cya... CoDe_InSiDe