Since the 'coder' of Download
    Master seems to be very stupid, I won't continue like normal with a short introduction; we
    will go directly to the protection, analyze it and KeyGEN it in NO time. I think everyone
    can code a KeyGEN for this target. This KeyGEN will work like a calculator - just with
    limited functions. However, let's start real cracking. 
     
    First of all, let's make sure that we all know this is a Visual Basic 6.0 'program',
    so you need the Visual Basic 6.0 exports loaded (if you haven't loaded them already,
    use Symbol Loader - Load Exports - MSVBVM60.DLL and go on). This said, we need to
    enter our fake registration details. Now it's time for setting the right breakpoints. I
    normally use - as always - __vbaStrCmp for Visual Basic programs. SoftICE will pop up and
    display the following code snippet: 
      
      
          :00433CAF    PUSH    EAX                              ; User Name
         
          :00433CB0    PUSH    0040C514                         ; Empty String
         
          :00433CB5    CALL    [MSVBVM60!__vbaStrCmp]           ; User Name enterd? | 
       
     
    The above code snippet is
    not important for us, so we can leave SoftICE. It will break again and the following code
    snippet is displayed now: 
    
      
          :00433E77    PUSH    EDX                              ; Registration Key
         
          :00433E78    PUSH    0040C514                         ; Empty String
         
          :00433E7D    CALL    [MSVBVM60!__vbaStrCmp]           ; Registration Key enterd? | 
       
     
    The above code snippet is
    also not important for us, so let's trace through the code in SoftICE. You will come
    accross the routine rtcIsNumeric, where it's checked if your Registration Key is a number.
    About 40 F10's further, you will come accross something like the following code snippet (be
    sure to toggle on the floating point stack window with WF): 
    
      
          :004341A9    PUSH    EDX                              ; Registration Key
         
          :004341AA    CALL    [MSVBVM60!__vbaR8Str]            ; Real from String?
         
          :004341B0    FSTP    REAL8 PTR [EBP-0108]
         
          :004341B6    MOV     EAX,[EBP-28]
         
          :004341B9    PUSH    EAX                              ; Product ID
         
          :004341BA    CALL    [MSVBVM60!__vbaR8Str]            ; Real from String?
         
          :004341C0    FADD    ST(0),ST                         ; ST + ST
         
          :004341C2    FADD    REAL8 PTR [00402AB8]             ; ST + 49h
         
          :004341C8    FMUL    REAL8 PTR [00402AB0]             ; ST * 03h
         
          :004341CE    FSUB    REAL8 PTR [00402AA8]             ; ST - 0Dh
         
          :004341D4    FSUB    REAL8 PTR [00402AA0]             ; ST - 0Fh
         
          :004341DA    FSTSW   AX                               ; ?
         
          :004341DC    TEST    AL,0D  
          :004341DE    JNZ     00434A09  
          :004341E4    CALL    [MSVBVM60!__vbaFpR8]             ; ?
         
          :004341EA    FCOMP   REAL8 PTR [EBP-0108]             ; check validity
         
          :004341F0    FSTSW   AX  
          :004341F2    TEST    AH,40  
          :004341F5    JZ      00434203                         ; invalid => JMP
         
          :004341F7    MOV     DWORD PTR [EBP-010C],00000001    ; Flag for valid key
         
          :00434201    JMP     0043420D  
          :00434203    MOV     DWORD PTR [EBP-010C],00000000    ; Flag for invalid key
         
          :0043420D    MOV     ECX,[EBP-010C]
         
             ...         ... | 
       
     
    The above code snippet seems
    to be the main calculation routine - and also the Registration Key checking routine. If
    you want to know what's going on, just watch ST0 (float window) whilst tracing
    through the code. You will find out what the 'coder' of the program did: 
     
         Registration Key = ((Product_ID * 2
    + 0x49) * 3) - 0x0D - 0x0F 
     
    I don't know why he substracts 0Dh and then 0Fh - he could substract 1Ch to save
    some code ... maybe this is another sign of his stupidity? 
     
    Ok. Now you have to transform the above formula into a KeyGEN. I've used exactly
    the same calculation as the author and I've also commented that C++ source code ... so I
    hope you all understand it. BTW, your registration details are stored at  HKEY_CURRENT_USER\Software\VB and VBA Program Settings\Download
    Master\Settings
  
       
    
      
        // This is the C++ Source Code of my KeyGEN. I hope you like it. 
        // I've compiled it using Symantec C/C++ 6.11 
         
        // DO NOT ASK ME WHY I HAVEN'T SUBSTRACTED 28 AT ONCE! I'VE TRIED TO 
        // USE THE ASM SOURCE OF THE CALCULATION ROUTINE SO THAT NEWBIES CAN 
        // UNDERSTAND IT. IF YOU DON'T THINK I SHOULD DO THAT, JUST DROP ME 
        // A MAIL! 
         
        #include <stdio.h> 
        #include <stdlib.h> 
         
        int main() 
        { 
        long double Reg_KEY    = 0; 
        long double Product_ID = 0; 
         
        printf("   ____                     __       __\n"); 
        printf("  /  _/_ _  __ _  ___  ____/ /____ _/ /\n"); 
        printf(" _/ //  ' \\/  ' \\/ _ \\/ __/ __/ _ `/ /\n"); 
        printf("/___/_/_/_/_/_/_/\\___/_/  \\__/\\_,_/_/\n"); 
        printf("   ____                          __          __\n"); 
        printf("  / __ \\___ ___ _______ ___  ___/ /__ ____  / /____\n"); 
        printf(" / /_/ / -_|_-</ __/ -_) _ \\/ _  / _ `/ _ \\/ __(_-<\n"); 
        printf("/_____/\\__/___/\\__/\\__/_//_/\\_,_/\\_,_/_//_/\\__/___/\n\n"); 
         
        for (;;){ 
        printf("\nDownload Master
        2.0 KeyGEN - d0NE bY TORN@DO in '99\n"); 
        printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"); 
         
        printf("Product ID:       "); 
         
        // read in long double 
        scanf("%Lf", &Product_ID); 
         
        if (Product_ID < 0) 
        {printf("ERROR:            
        Invalid Product ID!"); return -1;} 
        else 
        break; 
        } 
         
        // calculate Registration Key 
        Reg_KEY = Product_ID + Product_ID;   // FADD    ST(0),ST 
        Reg_KEY = Reg_KEY    + 73;
                  // FADD    REAL8 PTR
        [00402AB8] 
        Reg_KEY = Reg_KEY    *  3;
                  // FMUL    REAL8 PTR
        [00402AB0] 
        Reg_KEY = Reg_KEY    - 13;
                  // FSUB    REAL8 PTR
        [00402AA8] 
        Reg_KEY = Reg_KEY    - 15;
                  // FSUB    REAL8 PTR
        [00402AA0] 
         
        // print out the registration details 
        printf("User Name:        (any)\n"); 
        printf("Registration Key: %.Lf\n",Reg_KEY); 
         
        return 0; 
        } 
         | 
       
     
       
       
    Another target has been Reverse Engineerd. Any questions (no crack requests)? 
       |