Статьи Делаем Key Generator для WinZip и WinZip Self-Extractor

Discussion in 'Статьи' started by Zitt, 21 Aug 2006.

  1. Zitt

    Zitt Elder - Старейшина

    Joined:
    7 May 2006
    Messages:
    736
    Likes Received:
    268
    Reputations:
    59
    Автор: R!50770

    Сегодня мы напишим КлючеДелки для продукции от WinZip©. Я не буду размывать воду о том, что это тако WinZip и тому подобное. Так что сразу к делу. Кто уж вооообще в танке, то слить мона с http://www.winzip.com/

    Soft:
    SoftIce
    Win32dasm или IDA
    Какой-нить компилятор C/C++ и плюс знание языка
    Немного английского

    Теперь можно начинать. Сначало будем заниматься WinZip-ом. Запускаем, идем в окно регистрации, ставим бряк на GetDlgItemTextA, пытаемся зарегиться и вываливаемся в SI примерно здесь:


    018F:00407F9B 56 PUSH ESI
    018F:00407F9C E822790300 CALL 0043F8C3
    018F:00407FA1 803D78CD480000 CMP BYTE PTR [0048CD78],00
    018F:00407FA8 59 POP ECX
    018F:00407FA9 59 POP ECX
    018F:00407FAA 7459 JZ 00408005
    018F:00407FAC 803DA4CD480000 CMP BYTE PTR [0048CDA4],00
    018F:00407FB3 7450 JZ 00408005
    018F:00407FB5 E81BFAFFFF CALL 004079D5 ? generation is here
    018F:00407FBA 85C0 TEST EAX,EAX
    018F:00407FBC 7447 JZ 00408005

    Заходим в CALL 004079D5 и трасируем до этих пор:
    018F:00407A91 8D85C0FEFFFF LEA EAX,[EBP-0140]
    018F:00407A97 50 PUSH EAX
    018F:00407A98 57 PUSH EDI
    018F:00407A99 E8A9000000 CALL 00407B47 ? calculation is here

    Заходим в CALL 00407B47. Это то, что нам и нужно для написания кейгена:
    018F:00407B47 55 PUSH EBP
    018F:00407B48 8BEC MOV EBP,ESP
    018F:00407B4A 8B4D08 MOV ECX,[EBP+08]
    018F:00407B4D 53 PUSH EBX
    018F:00407B4E 56 PUSH ESI
    018F:00407B4F 57 PUSH EDI
    018F:00407B50 8A11 MOV DL,[ECX] ? first char into DL
    018F:00407B52 33DB XOR EBX,EBX
    018F:00407B54 33C0 XOR EAX,EAX
    018F:00407B56 8BF1 MOV ESI,ECX ? pointer to the name
    018F:00407B58 33FF XOR EDI,EDI ? counter
    018F:00407B5A 84D2 TEST DL,DL ? DL ? 0 :loop_1
    018F:00407B5C 7410 JZ 00407B6E ? if yes, jump
    018F:00407B5E 660FB6D2 MOVZX DX,DL ? DH == 0
    018F:00407B62 0FAFD7 IMUL EDX,EDI ? EDX == ascii * counter
    018F:00407B65 03DA ADD EBX,EDX ? result into EBX
    018F:00407B67 8A5601 MOV DL,[ESI+01] ? next char into DL
    018F:00407B6A 47 INC EDI ? inc counter
    018F:00407B6B 46 INC ESI ? pointer to the next char
    018F:00407B6C EBEC JMP 00407B5A ? loop_1
    018F:00407B6E C70544… MOV DWORD PTR [0048C844],00000001
    018F:00407B78 8BF1 MOV ESI,ECX ? pointer to the name
    018F:00407B7A 8A09 MOV CL,[ECX] ? first char into CL
    018F:00407B7C 84C9 TEST CL,CL ? CL ? 0 :loop_3
    018F:00407B7E 7419 JZ 00407B99 ? if yes, jump
    018F:00407B80 660FB6C9 MOVZX CX,CL ? CH == 0
    018F:00407B84 6821100000 PUSH 00001021
    018F:00407B89 51 PUSH ECX
    018F:00407B8A 50 PUSH EAX
    018F:00407B8B E829000000 CALL 00407BB9 ? another routin
    018F:00407B90 8A4E01 MOV CL,[ESI+01] ? into CL next char
    018F:00407B93 83C40C ADD ESP,0C
    018F:00407B96 46 INC ESI ? pointer to the next char
    018F:00407B97 EBE3 JMP 00407B7C ? loop_3
    018F:00407B99 83C063 ADD EAX,63
    018F:00407B9C 0FB7CB MOVZX ECX,BX
    018F:00407B9F 0FB7C0 MOVZX EAX,AX
    018F:00407BA2 51 PUSH ECX
    018F:00407BA3 50 PUSH EAX
    018F:00407BA4 688CE34700 PUSH 0047E38C
    018F:00407BA9 FF750C PUSH DWORD PTR [EBP+0C]
    018F:00407BAC E803FF0500 CALL 00467AB4 ? HEX into ASCII
    018F:00407BB1 83C410 ADD ESP,10 ? value_2 + value_1
    018F:00407BB4 5F POP EDI
    018F:00407BB5 5E POP ESI
    018F:00407BB6 5B POP EBX
    018F:00407BB7 5D POP EBP
    018F:00407BB8 C3 RET


    -->00407B8B CALL 00407BB9:
    018F:00407BB9 55 PUSH EBP
    018F:00407BBA 8BEC MOV EBP,ESP
    018F:00407BBC 8B4508 MOV EAX,[EBP+08]
    018F:00407BBF 56 PUSH ESI
    018F:00407BC0 33C9 XOR ECX,ECX
    018F:00407BC2 6A08 PUSH 08 ? counter
    018F:00407BC4 8A6D0C MOV CH,[EBP+0C] ? CH == ascii
    018F:00407BC7 5A POP EDX ? edx == 8
    018F:00407BC8 8BF0 MOV ESI,EAX ? :loop_2
    018F:00407BCA 33F1 XOR ESI,ECX ? ESI ^= ascii
    018F:00407BCC 66F7C60080 TEST SI,8000 ? if SI < 8000
    018F:00407BD1 7407 JZ 00407BDA ? jump
    018F:00407BD3 03C0 ADD EAX,EAX ? EAX += EAX
    018F:00407BD5 334510 XOR EAX,[EBP+10] ? EAX ^= 1021
    018F:00407BD8 EB02 JMP 00407BDC ? jump
    018F:00407BDA D1E0 SHL EAX,1 ? EAX <<= 1
    018F:00407BDC D1E1 SHL ECX,1 ? ECX <<= 1
    018F:00407BDE 4A DEC EDX ? dec counter
    018F:00407BDF 75E7 JNZ 00407BC8 ? loop_2
    018F:00407BE1 5E POP ESI
    018F:00407BE2 5D POP EBP
    018F:00407BE3 C3 RET

    Надеюся, что алго я объяснил придельно и ясно. Если кто-нить не понял, постарайтесь разабраться сами – в данном случае это несложно. Исходник генератора я дам вконце, а сейчас WinZip Self-Extractor. Опять-таки запускаем, ставим бряк на GetDlgItemTextA, пытаемся зарегистрироваться и вываливаемся в SI:


    018F:0040B176 0FB60590594300 MOVZX EAX,BYTE PTR [00435990]
    018F:0040B17D 85C0 TEST EAX,EAX
    018F:0040B17F 0F850F000000 JNZ 0040B194
    018F:0040B185 0FB60580584300 MOVZX EAX,BYTE PTR [00435880]
    018F:0040B18C 85C0 TEST EAX,EAX
    018F:0040B18E 0F845D000000 JZ 0040B1F1
    018F:0040B194 6A00 PUSH 00
    018F:0040B196 E8CEFBFFFF CALL 0040AD69 ? look here
    Входим в CALL 0040AD69 и трасируем:
    018F:0040ADE9 8D85FCFEFFFF LEA EAX,[EBP-0104]
    018F:0040ADEF 50 PUSH EAX
    018F:0040ADF0 6890594300 PUSH 00435990
    018F:0040ADF5 E837FDFFFF CALL 0040AB31 ? then look here

    Входим в CALL 0040AB31 и трасируем:
    018F:0040AC92 6821100000 PUSH 00001021
    018F:0040AC97 8B45FC MOV EAX,[EBP-04]
    018F:0040AC9A 660FB600 MOVZX AX,BYTE PTR [EAX]
    018F:0040AC9E 50 PUSH EAX
    018F:0040AC9F FF75F8 PUSH DWORD PTR [EBP-08]
    018F:0040ACA2 E858000000 CALL 0040ACFF ? and finally here
    018F:0040ACA7 83C40C ADD ESP,0C
    018F:0040ACAA 668945F8 MOV [EBP-08],AX

    Наконец мы у цели:
    018F:0040ACFF 55 PUSH EBP
    018F:0040AD00 8BEC MOV EBP,ESP
    018F:0040AD02 83EC04 SUB ESP,04
    018F:0040AD05 53 PUSH EBX
    018F:0040AD06 56 PUSH ESI
    018F:0040AD07 57 PUSH EDI
    018F:0040AD08 66C1650C08 SHL WORD PTR [EBP+0C],08 ? char <<= 8
    018F:0040AD0D C745FC00000000 MOV DWORD PTR [EBP-04],00000000 ? counter
    018F:0040AD14 E903000000 JMP 0040AD1C
    018F:0040AD19 FF45FC INC DWORD PTR [EBP-04]
    018F:0040AD1C 837DFC08 CMP DWORD PTR [EBP-04],08 ? counter ? 8
    018F:0040AD20 0F8D35000000 JGE 0040AD5B ? if greater, jump
    018F:0040AD26 0FB7450C MOVZX EAX,WORD PTR [EBP+0C]
    018F:0040AD2A 0FB74D08 MOVZX ECX,WORD PTR [EBP+08]
    018F:0040AD2E 33C1 XOR EAX,ECX ? EAX ^= ascii
    018F:0040AD30 F6C480 TEST AH,80 ? if AH > 80
    018F:0040AD33 0F8415000000 JZ 0040AD4E ? jump
    018F:0040AD39 0FB74508 MOVZX EAX,WORD PTR [EBP+08]
    018F:0040AD3D 03C0 ADD EAX,EAX ? EAX <<= 1
    018F:0040AD3F 0FB74D10 MOVZX ECX,WORD PTR [EBP+10] <-- ECX == 0x1021
    018F:0040AD43 33C1 XOR EAX,ECX ? EAX ^= 1021
    018F:0040AD45 66894508 MOV [EBP+08],AX
    018F:0040AD49 E904000000 JMP 0040AD52
    018F:0040AD4E 66D16508 SHL WORD PTR [EBP+08],1 ? EAX <<= 1
    018F:0040AD52 66D1650C SHL WORD PTR [EBP+0C],1 ? ECX <<= 1
    018F:0040AD56 E9BEFFFFFF JMP 0040AD19
    018F:0040AD5B 668B4508 MOV AX,[EBP+08]
    018F:0040AD5F E900000000 JMP 0040AD64
    018F:0040AD64 5F POP EDI
    018F:0040AD65 5E POP ESI
    018F:0040AD66 5B POP EBX
    018F:0040AD67 C9 LEAVE
    018F:0040AD68 C3 RET

    Это все? Да, это все. Что теперь? Вооружаемся компиляторам. Каким? Что за вопросы - какой работает, такой и юзай. Я взял Dev-C++ 4. Вот собственно и исходник:


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>

    typedef unsigned char BYTE;
    typedef unsigned int WORD;
    typedef unsigned long DWORD;

    int main( )
    {
    char name_1[ 100 ], name_2[ 100 ], *p;

    WORD value_1 = 0,
    value_2 = 0,
    value = 0,
    i;

    printf( "\nWinZip and WinZip Self-Extractor Key Generator by R!50770 (с)\n" );

    printf("\nName: ");
    scanf("%s", &name_1);
    for ( i = 0; i <= strlen( name_1 ); i++ )
    name_2[ i ] = name_1 [ i ];
    strlwr( name_2 );

    /* WinZip */

    p = name_1;
    i = 0;
    while( *p ) {
    value_1 += ( i++ ) * ( WORD ) *( p++ );
    }

    p = name_1;
    while( *p ) {
    value = *p;
    value <<= 8;
    for( i = 0; i < 8; i++ ) {
    if( ( value ^ value_2 ) > 0x8000 ) {
    value_2 <<= 1;
    value_2 &= 0xfff;
    value_2 ^= 0x1021;
    } else {
    value_2 <<= 1;
    value_2 &= 0xffff;
    }

    value <<= 1;
    value &= 0xffff;
    }
    p++;
    }

    sprintf( name_1, "%04X", value_2 + 0x63 );
    sprintf( name_1 + 4, "%04X", value_1 );
    *( name_1 + 8 ) = '\0';

    printf( "\nWinZip: %s\n", name_1 );

    /* WinZip Self-Extractor */
    value_1 = 0;
    value_2 = 0;
    value = 0;
    p = name_2;
    i = 1;
    while( *p ) {
    if( !isalpha( *p ) ) {
    p++;
    continue;
    }
    value_1 += ( i++ ) * ( WORD ) *( p++ );
    }

    p = name_2;
    while( *p ) {
    if( !isalpha( *p ) ) {
    p++;
    continue;
    }

    value = *p;
    value <<= 8;
    for( i = 0; i < 8; i++ ) {
    if( ( value ^ value_2 ) > 0x8000 ) {
    value_2 <<= 1;
    value_2 &= 0xffff;
    value_2 ^= 0x1021;
    } else {
    value_2 <<= 1;
    value_2 &= 0xffff;
    }
    value <<= 1;
    value &= 0xffff;
    }
    p++;
    }

    sprintf( name_2, "%03u", value_1 );
    sprintf( name_2 + 3, "%03u", value_2 + 0x9dd );
    *( name_2 + 6 ) = '\0';

    printf( "\nWinZip Self-Extractor: %s\n", name_2 );
    printf( "\n[mailto: [email protected]]" );
    return 0;
    }