----------------------------------- How to code a keygen for Cool label ----------------------------------- Cracker: stealthFIGHTER Target: Cool label v2.0 build 111 Tools: OllyDbg IDA VC++ Where: http://www.geocities.com/psirr/ Protection: MD5 -------------------------------------------------- Sorry for my English, it's not my mother language. -------------------------------------------------- ---------------- ---[ Step 1 ]--- ---------------- ======================================================================= Load your target in OllyDbg. Use GetWindowTextLength api to break on name/serial check. Trace a bit, pass some RETs and first useful code is here: ======================================================================= :00409521 call ?MakeUpper@CString@@QAEXXZ ;Uppercase all chars. :00409526 mov ecx, offset unk_0_525414 ;ECX = entered name :0040952B call sub_0_4022E0 ;Get length of name :00409530 mov [ebp+var_320], eax ;var_320 = eax (length) :00409536 cmp [ebp+var_320], 5 ;If var320 < 5 :0040953D jle loc_0_409850 ;jump away ======================================================================= Here we see the length of our name should be > 5 and all characters in our name are uppercased. Trace a bit (or switch to IDA and see code in IDA): ======================================================================= :00409577 lea ecx, [ebp+MD5_CTX] ;ECX = MD5 context :0040957D call MD5_Init ;MD5 Init function ======================================================================= Wow! An initialization of MD5 hash. How I know this? In IDA double click the CALL (note I've renamed 44D190 to MD5_Init) and you can see this: ======================================================================= :0044D1AE mov dword ptr [edx], 67452301h ;1st const. :0044D1B4 mov eax, [ebp+var_4] :0044D1B7 mov dword ptr [eax+4], 0EFCDAB89h ;2nd const. :0044D1BE mov ecx, [ebp+var_4] :0044D1C1 mov dword ptr [ecx+8], 98BADCFEh ;3rd const. :0044D1C8 mov edx, [ebp+var_4] :0044D1CB mov dword ptr [edx+0Ch], 10325476h ;4th const. ======================================================================= So the program initalizes these four constants. In OllyDbg trace a bit: ======================================================================= :004095A9 mov [ebp+var_25C], 17h ;1st value :004095B0 mov [ebp+var_25A], 22h ;3rd value :004095B7 mov [ebp+var_259], 43h ;4th value :004095BE mov [ebp+var_258], 38h ;5th value :004095C5 mov [ebp+var_298], 0 :004095CC mov cl, [ebp+var_298] :004095D2 mov [ebp+var_299], cl :004095D8 mov dl, [ebp+var_299] :004095DE mov [ebp+var_29A], dl :004095E4 mov al, [ebp+var_29A] :004095EA mov [ebp+var_29B], al :004095F0 mov cl, [ebp+var_29B] :004095F6 mov [ebp+var_29C], cl : : :00409624 mov [ebp+var_25B], 2Dh ;2nd value : ======================================================================= Here we see five values are being moved into array. In OllyDbg you can see that at begining this array consist of 32 '6' numbers. After you pass address 00409624 the array should look like below (dump from OllyDbg): ======================================================================= 17 2D 22 43 38 36 36 36 36 36 36 36 36 36 36 36 -"C866666666666 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666 ======================================================================= Now in IDA scroll a bit: ======================================================================= :00409637 @@loop: :00409637 mov ecx, [ebp+var_230] :0040963D add ecx, 1 ;increase counter :00409640 mov [ebp+var_230], ecx :00409646 :00409646 loc_0_409646: :00409646 cmp [ebp+var_230], 20h ;length of array = 32 chars. :0040964D jge short @@away :0040964F mov edx, [ebp+var_230] :00409655 mov eax, [ebp+var_230] :0040965B mov cl, [ebp+eax+var_29C] :00409662 mov [ebp+edx+var_257], cl :00409669 jmp short @@loop ======================================================================= In this loop our name is put into array and the rest is filled with zeros. So after you pass this your array should look like this: ======================================================================= 17 2D 22 43 38 53 54 45 41 4C 54 48 46 49 47 48 -"C8STEALTHFIGHT 54 45 52 00 00 00 00 00 00 00 00 00 00 00 00 00 ER.............. ======================================================================= :0040966B push offset aCoollabel_0 ;const char "CoolLabel" :00409670 call _strlen ;return length of "CoolLabel" :00409675 add esp, 4 :00409678 push eax ;eax = strlen("CoolLabel)" :00409679 push offset aCoollabel_1 ;push string "CoolLabel" :0040967E lea ecx, [ebp+MD5_CTX] ;ecx = MD5 context :00409684 call MD5_Update ;MD5 update function ======================================================================= 1st. MD5 update function: MD5Update(&md,"CoolLabel",9); ======================================================================= In IDA immediately below this you can see: ======================================================================= :00409689 push 25h ;length of input = 37 :0040968B lea edx, [ebp+var_25C] ;edx = our array (see :00409691 push edx ;push array :00409692 lea ecx, [ebp+MD5_CTX] ;ecx = MD5 context :00409698 call MD5_Update ;MD5 update function ======================================================================= 2nd. MD5 update function: MD5Update(&md,szArray,0x25); ======================================================================= In IDA immediately below this you can see: ======================================================================= :0040969D lea eax, [ebp+szSerial] ;eax = szSerial :004096A3 push eax ; push eax (szSerial) :004096A4 lea ecx, [ebp+MD5_CTX] ; ecx = MD5 context :004096AA call MD5_Final ======================================================================= MD5 final function: MD5Final(&md,szSerial); ======================================================================= Below you can see formating the final result (from MD5Final function) and the format of the serial is '%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x'. ======================================================================= Time to keygen: 1. Take user's name and upper case it. 2. Put five values (0x17, 0x2D, 0x22, 0x43, 0x38) at the beginning of an array 3. Put all chars of our name into array and the rest fill with zero bytes 4. Initialize MD5 hash 5. Update MD5 with string "CoolLabel" (without brackets) and length 9 6. Update MD5 with our array and length 37 7. Final MD5 hash 8. Format result (xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx) 9. Lowercase result ======================================================================= Here comes my source in VC++: ======================================================================= //**********_Begin_algorithm_here_************ nameLength = strlen(szName); ;get length of name szArray[0] = 0x017; ;put szArray[1] = 0x02D; ;these szArray[2] = 0x022; ;values szArray[3] = 0x043; ;into szArray[4] = 0x038; ;array for (i=0; i