Автор: 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; }