Turotial 33 for CD to MP3 Converter v1.15 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ok, this going to be a fast tutorial, since it is very easy to find & code the keygen. first we load the app and open up the registration box. we get: Registration Name: Registration Code: first we do a test check for the 'error' message that we will get: enter some info, i.e: Registration Name: bengaly Registration Code: 12121212 pressing the OK button and we get: "Error Register Code!", not much fancy, and we loadup Win32dasm, let it disasm and open up the string-references box. we now will search for this string: ========================================================================= "Complete" "congratulation!" "Convert " "Converting" "Could not get handle to CD!" "CRC" "crc" "decoder is not stop!" "Dir" "DisableThreadLibraryCalls" "edit" "Error register code!" <----- here it is, press this line "Error retrieving CDDB info... " "Error" "File name" "FORMAT" "Format" ============================================================================= we press the selected line and we are here: ================================================================================ * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041181F(C) | :0041188D 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Warning!" | :0041188F 6820D04400 push 0044D020 * Possible StringData Ref from Data Obj ->"Error register code!" | :00411894 6808D04400 push 0044D008 <---- here we are! :00411899 8BCE mov ecx, esi :0041189B E83E2F0200 call 004347DE :004118A0 8B442410 mov eax, dword ptr [esp+10] :004118A4 8B4C2418 mov ecx, dword ptr [esp+18] :004118A8 50 push eax :004118A9 51 push ecx * Possible StringData Ref from Data Obj ->"Name" | :004118AA 68FCC44400 push 0044C4FC * Possible StringData Ref from Data Obj ->"Mp3Option" | :004118AF 6844C34400 push 0044C344 :004118B4 FFD3 call ebx ==================================================================================== now, we have luck becuase this whole routine has a caller ;-) * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0041181F(C) <== this is where we called from, simply do a search for the string "41181F" the way up and we land here: ==================================================================================== * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004117E7(C) | :004117F5 8BC2 mov eax, edx :004117F7 C1E006 shl eax, 06 :004117FA 03C2 add eax, edx :004117FC 8D0CC0 lea ecx, dword ptr [eax+8*eax] :004117FF 8DAC8A155E0100 lea ebp, dword ptr [edx+4*ecx+00015E15] :00411806 8D4C241C lea ecx, dword ptr [esp+1C] :0041180A E874E90100 call 00430183 :0041180F 8B86A0030000 mov eax, dword ptr [esi+000003A0] :00411815 C684244002000004 mov byte ptr [esp+00000240], 04 :0041181D 3BE8 cmp ebp, eax :0041181F 756C jne 0041188D <==== we land here! :00411821 8B542410 mov edx, dword ptr [esp+10] :00411825 8B07 mov eax, dword ptr [edi] :00411827 52 push edx :00411828 50 push eax * Possible StringData Ref from Data Obj ->"Name" | :00411829 68FCC44400 push 0044C4FC ==================================================================================== now, this is a bit confusing?..why ?..because think of this: most of the time we find such thing: call cmp jne in this case its +- the same thing, but entering the call at 00430183 will give us nothing important, and i mean No Algo :( hm..think of this, ASM is really old coded from up to down, meaning, the code is running from the top to down (sure there are calls,jmps..but they do return and keep executing after that call), so in this case we look a bit up ;-) we see something interesting..some "calculations" here it is: :004117DB BA01000000 mov edx, 00000001 :004117E0 8B48F8 mov ecx, dword ptr [eax-08] :004117E3 33C0 xor eax, eax :004117E5 85C9 test ecx, ecx :004117E7 7E0C jle 004117F5 :004117E9 0FBE6C0438 movsx ebp, byte ptr [esp+eax+38] :004117EE 03D5 add edx, ebp :004117F0 40 inc eax :004117F1 3BC1 cmp eax, ecx :004117F3 7CF4 jl 004117E9 :004117F5 8BC2 mov eax, edx :004117F7 C1E006 shl eax, 06 :004117FA 03C2 add eax, edx :004117FC 8D0CC0 lea ecx, dword ptr [eax+8*eax] :004117FF 8DAC8A155E0100 lea ebp, dword ptr [edx+4*ecx+00015E15] i can commet it, but its better to fire up ollydbg this time!! just to get a more close up on this "easy" algo :-) right, u got it disassembled, searching for the address 4117CD now, why i put this address??.. :004117CD 68FCC44400 push 0044C4FC <== this is where we will break in olly. actually i put this as the breakpoint cuz its few lines before the algo, it doesn't really matter where as long as its in the algo of before :) go to this address and put a breakpoint with F2 (line turns red), right, lets run the app now, press F9 and ollydbg runs the process and the app shows, go to the registration dialog, put the fake info (bengaly/121212) and press OK, Ollyfbg breaks :) , now we trace the lines with F8 and enter calls/jmps with F7 lucky us we dont need to trace calls. start trace each line with F8 and u will see the registers/info on the right window ===================================================================================== :004117D9 8B07 mov eax, dword ptr [edi] ; eax = fake name :004117DB BA01000000 mov edx, 00000001 ; edx = 1 :004117E0 8B48F8 mov ecx, dword ptr [eax-08] ; ecx = lenght of fake name :004117E3 33C0 xor eax, eax ; eax = 0 :004117E5 85C9 test ecx, ecx ; crap :004117E7 7E0C jle 004117F5 ; crap :004117E9 0FBE6C0438 movsx ebp, byte ptr [esp+eax+38] ; ebp = char of name in loop <-+ :004117EE 03D5 add edx, ebp ; edx = edx+ebp | :004117F0 40 inc eax ; eax = eax + 1 | :004117F1 3BC1 cmp eax, ecx ; eax == ecx ? (ecx=lenght) | :004117F3 7CF4 jl 004117E9 ; -----------------------------+ :004117F5 8BC2 mov eax, edx ; eax = edx :004117F7 C1E006 shl eax, 06 ; eax << 6 :004117FA 03C2 add eax, edx ; eax = eax + edx :004117FC 8D0CC0 lea ecx, dword ptr [eax+8*eax] ; ecx = eax+(eax*8) :004117FF 8DAC8A155E0100 lea ebp, dword ptr [edx+4*ecx+00015E15] ; ebp = edx+4*ecx+0x15e15 ========================================================================================== this is the whole algo!! ebp will hold the final serial, we can see this: :0041181D 3BE8 cmp ebp, eax ; compare ;) :0041181F 756C jne 0041188D ; bad boy now we know that we need the serial as a "%d" (decimal) because the algo call the convertion routine here: ==================================================== * Possible StringData Ref from Data Obj ->"%d" | :00411840 6854C44400 push 0044C454 :00411845 52 push edx :00411846 E845910000 call 0041A990 ==================================================== this is probably a standrad sprintf(bla,"%d",ebp) function lets make the actual keygens: ---------------------------------------------------------------------------------------- VIsual C++ (C) Source Code ---------------------------------------------------------------------------------------- char name[255]={0}; int i,j,eax,edx,ecx,ebp,buff; char ch; eax=edx=ecx=ebp=buff=0; GetDlgItemTextA(hWnd,IDC_NAME,name,255); // lets get the info from the edit-box j=lstrlen(name); edx =1; ecx =j; for(i=0;i