http://www.quinnware.com/ - Webpage (qcd11_setup.zip - (707k)).
Welcome once again to another key generator including full ASM source. Quintessential CD provides good practice for those of you looking to refine your key generating skills, in fact the main body of the source code is ripped directly from the disassembly and just modified slightly to work with TASM. So without further ado lets locate our protection routine. Locate the registration option and >bpx GetDlgItemTextA, again I'm using CrackZ & 0123456789. After the necessary returns you'll be at the following code, the deciding jump is shortly afterwards.
:0040B30A LEA EAX,[ESP+24] <-- Name.
:0040B30E LEA ECX,[ESP+18]
:0040B312 PUSH EAX <-- Stack name for function call.
:0040B313 PUSH ECX
:0040B314 CALL 0040C790 <-- Main protection routine.
You'll need to trace 0040C790 and examine how the program calculates the good code for your user name, note how the code is actually the hex value of a register (not the decimal). Here are the main highlights of the calculation routine.
:0040C7A6 REPNZ <-- Start of string length routine.
:0040C7A8 NOT ECX
:0040C7AA DEC ECX
:0040C7AB CMP ECX,06 <-- Check name length.
:0040C7AE JB 00409EB1 <-- Jump_if_below.
:0040C7B0 MOV BL, BYTE PTR [EDX] <-- Pointer to name.
:0040C7B2 XOR ESI,ESI <-- Clean register for calculation routine.
:0040C7B4 TEST BL,BL <-- Check first letter for 0.
:0040C7B6 MOV EDI,EDX <-- Move name in EDI.
:0040C7B8 MOV ECX, 00000001
:0040C7BD JZ 0040C7E3
:0040C7BF TEST EDI,EDI
:0040C7C1 JZ 0040C7E3
:0040C7C3 MOV DL, BYTE PTR [EDI] <-- Pointer to name.
:0040C7C5 CMP DL,20 <-- Was it 20h (space).
:0040C7C8 JZ 0040C7DB <-- If_its_a_space_get_the_next_char.
:0040C7CA MOVSX EDX,DL
:0040C7CD MOV EBX,ECX <-- Start of calculation routine.
:0040C7CF LEA ECX,[ECX+2*ECX] <-- ECX * 3.
:0040C7D2 IMUL EBX,EDX
:0040C7D5 ADD EBX,ESI
:0040C7D7 ADD EAX,EBX
:0040C7D9 ADD ESI,EDX <-- End of calculation routine.
:0040C7DB MOV DL, BYTE PTR [EDI+01] <-- Next character.
:0040C7DE INC EDI <-- Required increment.
:0040C7DF TEST DL,DL <-- End of name.
:0040C7E1 JNZ 0040C7BF <-- Loop_name.
:0040C7E3 CDQ <-- Convert Double to Quad (EDX=0).
:0040C7E4 MOV EDI, 0000FFFF <-- Final stage, to format good code.
:0040C7E9 IDIV EDI
:0040C7EB MOV EAX,ECX
:0040C7ED MOV ECX, 0000FFFF
:0040C7F2 MOV EDI,EDX
:0040C7F4 XOR EDX,EDX <-- EDX=0.
:0040C7F6 DIV ECX
:0040C7F8 SHL EDI,10 <-- Shift left.
:0040C7FB MOV EAX,ESI
:0040C7FD MOV ECX, 000000FF
:0040C802 OR EDI,EDX <-- We're done here.
So you can now see the tasks a key generator has to perform, the name must be at least 6 characters else a code will not be generated and if the name has a space that will be ignored by the program. Before you look at my source code attempt to construct the key generator yourself, note several potential problems, firstly look how many of the registers this program uses, you might have to think a little how you are going to loop the name characters, its probably not a good idea to start swapping registers from those used by the program.
Note also how you might format your output, (the program uses an API call to do this), be sure that you test your key generator using various names. Be sure also to note the names of the registry keys used by the program, _Pants & _Spanky, maybe there is some author humour there after all.