QModem Pro 2.1 for Win95 & Win NT Cracked by Hambo.H, Written by Hambo.H E-mail: hambo@nenpub.szptt.net.cn Shenzhen China 98-2-8 2:03AM 有上过CFIDO的人应该知道这个是个什么软件,2.1版好象有Telnet的功能 可以用来上Internet BBS。 废话少说,进正题。 按Purchase进入注册窗口。 注意:如果你是第一次按Purchse,它将要你输入Personal Information。 第二次进入才是注册窗口。 填入: Unlock Code : 191919191919 User Name : Hambo.H Company Name: Shenzhen University 按CTRL-D进入SoftIce。 设bpx getwindowtexa 按CTRL-D回到Win95,按OK按钮。 被SoftIce拦截,然后关闭BreakPoint(用bd *)。 按F12一下。见如下程序段。 014F:10003F51 PUSH 14 014F:10003F53 LEA EAX,[EBP-14] 014F:10003F56 PUSH EAX 014F:10003F57 MOV EBX,[USER32!GetWindowTextA] 014F:10003F5D PUSH EDI 014F:10003F5E CALL EBX 014F:10003F60 PUSH 00002334 <===按F12后,返回在此处。 014F:10003F65 PUSH ESI 014F:10003F66 CALL [USER32!GetDlgItem] 014F:10003F6C PUSH EAX 014F:10003F6D MOV EDI,EAX 014F:10003F6F CALL [USER32!GetWindowTextLengthA] 014F:10003F75 CMP EAX,02 014F:10003F78 JG 10003F96 014F:10003F7A PUSH 00002000 014F:10003F7F PUSH 10013D29 014F:10003F84 PUSH 10014239 014F:10003F89 PUSH 00 014F:10003F8B CALL [USER32!MessageBoxA] 014F:10003F91 JMP 100040CB 014F:10003F96 PUSH 27 014F:10003F98 LEA EAX,[EBP-7C] 014F:10003F9B PUSH EAX 014F:10003F9C PUSH EDI 014F:10003F9D CALL EBX 014F:10003F9F PUSH 00002335 014F:10003FA4 PUSH ESI 014F:10003FA5 CALL [USER32!GetDlgItem] 014F:10003FAB PUSH 31 014F:10003FAD PUSH 10013B50 014F:10003FB2 PUSH EAX 014F:10003FB3 CALL EBX 014F:10003FB5 LEA EAX,[EBP-28] 014F:10003FB8 PUSH EAX 上面一段程序是读取Unlock Code,User name和Company。 014F:10003FB9 CALL 10001D08 <==这里就是进行注册码计算 由Reg Number计算出Unlock Code 然后与你输入的Unlock Code比较。 按F10执行上面的Call。好戏在后头。接着看。 014F:10003FBE ADD ESP,04 014F:10003FC1 LEA EAX,[EBP-14] 014F:10003FC4 LEA ECX,[EBP-28] <==这里,D一下看看。 014F:10003FC7 PUSH EAX 014F:10003FC8 PUSH ECX :d 0157:0080F4FC 0157:0080F4FC 30 32 36 32 36 34 36 37-35 39 31 34 37 34 30 39 0262646759147409 0157:0080F50C 00 00 66 20 31 39 31 39-31 39 31 39 31 39 31 39 ..f 191919191919 0157:0080F51C 00 85 39 80 04 01 6E 07-44 F5 80 00 63 36 F7 BF ..9...n.D...c6.. 0157:0080F52C 10 05 00 00 11 01 00 00-01 00 00 00 14 05 00 00 ................ 哇......注册码都帮我算出来,真好人。 ^o^ 可惜这个是我的注册码,你不能用。(你跟的你就能用) 原来注册码是16位数字的。 好人作到底,做个注册器出来吧。 下面就进入看看014F:10003FB9 CALL 10001D08这里。 接着刚才,设bpx 014F:10003FB9。 按CTRL-D,回到Win95,再按一下OK按钮。 被SoftIce拦截,然后关闭BreakPoint, bd *。 按F8进入Call。 再按数次F10直到见如下程序: 014F:10001D2E PUSH 10011044 014F:10001D33 LEA EAX,[EBP-04] 014F:10001D36 PUSH EAX 014F:10001D37 INC EDI 014F:10001D38 CALL 10004D70 014F:10001D3D ADD ESP,08 014F:10001D40 LEA ECX,[EBP-04] 014F:10001D43 MOVSX EAX,BYTE PTR [EDI+10014542] 014F:10001D4A PUSH EAX 014F:10001D4B PUSH 100111B4 014F:10001D50 PUSH ECX 014F:10001D51 CALL ESI 014F:10001D53 ADD ESP,0C 014F:10001D56 LEA ECX,[EBP-04] 014F:10001D59 PUSH ECX 014F:10001D5A CALL 10004F10 014F:10001D5F ADD ESP,04 014F:10001D62 MOV [EDI*4+EBP-60],EAX 014F:10001D66 CMP EDI,06 014F:10001D69 JB 10001D2E 上面一段程序是将QModem Pro的版本号(字符串) :d 0157:10014543 0157:10014543 32 31 30 30 30 30 51 6D-6F 64 65 6D 00 32 33 30 210000Qmodem.230 ^^^^^^这六个 转化成数值的形式。 而下面这段程序则是将本机器的Reg Number转换成数值的程序。 014F:10001D6B XOR EDI,EDI 014F:10001D6D PUSH 10011044 014F:10001D72 LEA EAX,[EBP-04] 014F:10001D75 PUSH EAX 014F:10001D76 INC EDI 014F:10001D77 CALL 10004D70 014F:10001D7C ADD ESP,08 014F:10001D7F LEA ECX,[EBP-04] 014F:10001D82 MOVSX EAX,BYTE PTR [EDI+100145AF] 014F:10001D89 PUSH EAX 014F:10001D8A PUSH 100111B4 014F:10001D8F PUSH ECX 014F:10001D90 CALL ESI 014F:10001D92 ADD ESP,0C 014F:10001D95 LEA ECX,[EBP-04] 014F:10001D98 PUSH ECX 014F:10001D99 CALL 10004F10 014F:10001D9E ADD ESP,04 014F:10001DA1 MOV [EDI*4+EBP-48],EAX 014F:10001DA5 CMP EDI,10 014F:10001DA8 JB 10001D6D 经过上面两段程序的转化,其本身是这样的2100005890769232127022字符串 变成了下面这样。 :d 0157:0080F434 0157:0080F434 02 00 00 00 01 00 00 00-00 00 00 00 00 00 00 00 ................ 0157:0080F444 00 00 00 00 00 00 00 00-05 00 00 00 08 00 00 00 ................ 0157:0080F454 09 00 00 00 00 00 00 00-07 00 00 00 06 00 00 00 ................ 0157:0080F464 09 00 00 00 02 00 00 00-03 00 00 00 02 00 00 00 ................ 0157:0080F474 01 00 00 00 02 00 00 00-07 00 00 00 00 00 00 00 ................ 0157:0080F484 02 00 00 00 02 00 00 00- 接着下面的程序就是注册码的计算。 014F:10001DAA PUSH DWORD PTR [EBP-34] 014F:10001DAD PUSH DWORD PTR [EBP-08] 014F:10001DB0 PUSH DWORD PTR [EBP-5C] 014F:10001DB3 PUSH DWORD PTR [EBP-28] 014F:10001DB6 PUSH DWORD PTR [EBP-44] 014F:10001DB9 CALL 10001C29 014F:10001DBE ADD ESP,14 014F:10001DC1 MOV [EBP-009C],EAX 014F:10001DC7 PUSH DWORD PTR [EBP-30] 014F:10001DCA PUSH DWORD PTR [EBP-0C] 014F:10001DCD PUSH DWORD PTR [EBP-58] 014F:10001DD0 PUSH DWORD PTR [EBP-2C] 014F:10001DD3 PUSH DWORD PTR [EBP-40] 014F:10001DD6 CALL 10001C29 014F:10001DDB ADD ESP,14 014F:10001DDE MOV [EBP-0098],EAX 014F:10001DE4 PUSH DWORD PTR [EBP-2C] 014F:10001DE7 PUSH DWORD PTR [EBP-10] 014F:10001DEA PUSH DWORD PTR [EBP-54] 014F:10001DED PUSH DWORD PTR [EBP-30] 014F:10001DF0 PUSH DWORD PTR [EBP-3C] 014F:10001DF3 CALL 10001C29 014F:10001DF8 ADD ESP,14 014F:10001DFB MOV [EBP-0094],EAX 014F:10001E01 PUSH DWORD PTR [EBP-28] 014F:10001E04 PUSH DWORD PTR [EBP-14] 014F:10001E07 PUSH DWORD PTR [EBP-50] 014F:10001E0A PUSH DWORD PTR [EBP-34] 014F:10001E0D PUSH DWORD PTR [EBP-38] 014F:10001E10 CALL 10001C29 014F:10001E15 ADD ESP,14 014F:10001E18 MOV [EBP-0090],EAX 014F:10001E1E PUSH DWORD PTR [EBP-24] 014F:10001E21 PUSH DWORD PTR [EBP-18] 014F:10001E24 PUSH DWORD PTR [EBP-4C] 014F:10001E27 PUSH DWORD PTR [EBP-38] 014F:10001E2A PUSH DWORD PTR [EBP-34] 014F:10001E2D CALL 10001C29 014F:10001E32 ADD ESP,14 014F:10001E35 MOV [EBP-008C],EAX 014F:10001E3B PUSH DWORD PTR [EBP-20] 014F:10001E3E PUSH DWORD PTR [EBP-1C] 014F:10001E41 PUSH DWORD PTR [EBP-48] 014F:10001E44 PUSH DWORD PTR [EBP-3C] 014F:10001E47 PUSH DWORD PTR [EBP-30] 014F:10001E4A CALL 10001C29 014F:10001E4F ADD ESP,14 014F:10001E52 MOV [EBP-0088],EAX 014F:10001E58 PUSH DWORD PTR [EBP-1C] 014F:10001E5B PUSH DWORD PTR [EBP-20] 014F:10001E5E PUSH DWORD PTR [EBP-5C] 014F:10001E61 PUSH DWORD PTR [EBP-40] 014F:10001E64 PUSH DWORD PTR [EBP-2C] 014F:10001E67 CALL 10001C29 014F:10001E6C ADD ESP,14 014F:10001E6F MOV [EBP-0084],EAX 014F:10001E75 PUSH DWORD PTR [EBP-18] 014F:10001E78 PUSH DWORD PTR [EBP-24] 014F:10001E7B PUSH DWORD PTR [EBP-58] 014F:10001E7E PUSH DWORD PTR [EBP-44] 014F:10001E81 PUSH DWORD PTR [EBP-28] 014F:10001E84 CALL 10001C29 014F:10001E89 ADD ESP,14 014F:10001E8C MOV [EBP-80],EAX 014F:10001E8F PUSH DWORD PTR [EBP-18] 014F:10001E92 PUSH DWORD PTR [EBP-08] 014F:10001E95 PUSH DWORD PTR [EBP-54] 014F:10001E98 PUSH DWORD PTR [EBP-08] 014F:10001E9B PUSH DWORD PTR [EBP-24] 014F:10001E9E CALL 10001C29 014F:10001EA3 ADD ESP,14 014F:10001EA6 MOV [EBP-7C],EAX 014F:10001EA9 PUSH DWORD PTR [EBP-14] 014F:10001EAC PUSH DWORD PTR [EBP-0C] 014F:10001EAF PUSH DWORD PTR [EBP-50] 014F:10001EB2 PUSH DWORD PTR [EBP-0C] 014F:10001EB5 PUSH DWORD PTR [EBP-20] 014F:10001EB8 CALL 10001C29 014F:10001EBD ADD ESP,14 014F:10001EC0 MOV [EBP-78],EAX 014F:10001EC3 PUSH DWORD PTR [EBP-10] 014F:10001EC6 PUSH DWORD PTR [EBP-10] 014F:10001EC9 PUSH DWORD PTR [EBP-4C] 014F:10001ECC PUSH DWORD PTR [EBP-10] 014F:10001ECF PUSH DWORD PTR [EBP-1C] 014F:10001ED2 CALL 10001C29 014F:10001ED7 ADD ESP,14 014F:10001EDA MOV [EBP-74],EAX 014F:10001EDD PUSH DWORD PTR [EBP-0C] 014F:10001EE0 PUSH DWORD PTR [EBP-14] 014F:10001EE3 PUSH DWORD PTR [EBP-48] 014F:10001EE6 PUSH DWORD PTR [EBP-14] 014F:10001EE9 PUSH DWORD PTR [EBP-18] 014F:10001EEC CALL 10001C29 014F:10001EF1 ADD ESP,14 014F:10001EF4 MOV [EBP-70],EAX 014F:10001EF7 PUSH DWORD PTR [EBP-08] 014F:10001EFA PUSH DWORD PTR [EBP-18] 014F:10001EFD PUSH DWORD PTR [EBP-5C] 014F:10001F00 PUSH DWORD PTR [EBP-18] 014F:10001F03 PUSH DWORD PTR [EBP-14] 014F:10001F06 CALL 10001C29 014F:10001F0B ADD ESP,14 014F:10001F0E MOV [EBP-6C],EAX 014F:10001F11 PUSH DWORD PTR [EBP-34] 014F:10001F14 PUSH DWORD PTR [EBP-1C] 014F:10001F17 PUSH DWORD PTR [EBP-58] 014F:10001F1A PUSH DWORD PTR [EBP-1C] 014F:10001F1D PUSH DWORD PTR [EBP-10] 014F:10001F20 CALL 10001C29 014F:10001F25 ADD ESP,14 014F:10001F28 MOV [EBP-68],EAX 014F:10001F2B PUSH DWORD PTR [EBP-30] 014F:10001F2E PUSH DWORD PTR [EBP-20] 014F:10001F31 PUSH DWORD PTR [EBP-54] 014F:10001F34 PUSH DWORD PTR [EBP-20] 014F:10001F37 PUSH DWORD PTR [EBP-0C] 014F:10001F3A CALL 10001C29 014F:10001F3F ADD ESP,14 014F:10001F42 MOV [EBP-64],EAX 014F:10001F45 PUSH DWORD PTR [EBP-2C] 014F:10001F48 PUSH DWORD PTR [EBP-24] 014F:10001F4B PUSH DWORD PTR [EBP-50] 014F:10001F4E PUSH DWORD PTR [EBP-24] 014F:10001F51 PUSH DWORD PTR [EBP-08] 014F:10001F54 CALL 10001C29 注册码是由16位组成的,所以就进行了16次同样的计算, 每次再这个Version Number+Reg Number中取出5位数字来计算。 具体每次取哪5位(我按次序给这五位数命名位:A,B,C,D,E),见如下表: V/N+R/N: 2100005890769232127022 第几位: 1....................22 第i次 A B C D E ===================================================== 01 11 22 1 14 7 02 12 21 2 13 8 03 13 20 3 12 9 04 14 19 4 11 10 05 15 18 5 10 11 06 16 17 6 9 12 07 17 16 1 8 13 08 18 15 2 7 14 09 18 22 3 22 15 10 19 21 4 21 16 11 20 20 5 20 17 12 21 19 6 19 18 13 22 18 1 18 19 14 11 17 2 17 20 15 12 16 3 16 21 16 13 15 4 15 22 每次用5位数字Call下面的一段程序,计算出一位Reg Number。 总共call16次。 :u 14f:10001C29 l 100 014F:10001C29 PUSH EBP 014F:10001C2A MOV EAX,[ESP+08] 014F:10001C2E MOV EBP,ESP 014F:10001C30 ADD EAX,[ESP+0C] 014F:10001C34 CMP EAX,09 014F:10001C37 JLE 10001C3C 014F:10001C39 SUB EAX,0A 014F:10001C3C SUB EAX,[EBP+10] 014F:10001C3F JNS 10001C44 014F:10001C41 ADD EAX,0A 014F:10001C44 ADD EAX,[EBP+14] 014F:10001C47 CMP EAX,09 014F:10001C4A JLE 10001C4F 014F:10001C4C SUB EAX,0A 014F:10001C4F SUB EAX,[EBP+18] 014F:10001C52 JNS 10001C57 014F:10001C54 ADD EAX,0A 014F:10001C57 POP EBP 014F:10001C58 RET 上面一段程序的大概意思是: para a,b,c,d,e rg=e+d if rg>9 then rg=rg-10 rg=rg-c if rg<0 then rg=rg+10 rg=rg+b if rg>9 then rg=rg-10 rg=rg-a if rg<0 then rg=rg+10 return rg 它的算法就这么简单。 从上面看来,程序没有用到User name和Cmpany这两个。 所以你就可以随便输入你想的啦。 我用Turbo 2.0编了个注册器。 程序如下: #include #include #include unsigned char cal_reg(signed,signed,signed,signed,signed); void main() { unsigned int i,l; unsigned char rn[30],fc,sc,reg[25]="210000"; clrscr(); printf("QModem Pro 2.1 for Win95 & Win NT KeyMaker\n"); printf("Programming by Hambo.H Cracked by Hambo.H\n"); printf("Shenzhen China Feb 5, 1998\n\n"); printf("Please Enter Your Reg Number(16 figures): "); gets(rn); l=strlen(rn); if (l!=16) { printf("This a wrong Reg Number!!"); exit(1); } for(i=0;i<16;i++) { reg[i+6]=rn[i]; } reg[22]=0; for(i=0;i<22;i++) { rn[i+1]=reg[i]-48; } reg[0] =cal_reg(rn[11],rn[22],rn[1],rn[14],rn[ 7]); reg[1] =cal_reg(rn[12],rn[21],rn[2],rn[13],rn[ 8]); reg[2] =cal_reg(rn[13],rn[20],rn[3],rn[12],rn[ 9]); reg[3] =cal_reg(rn[14],rn[19],rn[4],rn[11],rn[10]); reg[4] =cal_reg(rn[15],rn[18],rn[5],rn[10],rn[11]); reg[5] =cal_reg(rn[16],rn[17],rn[6],rn[ 9],rn[12]); reg[6] =cal_reg(rn[17],rn[16],rn[1],rn[ 8],rn[13]); reg[7] =cal_reg(rn[18],rn[15],rn[2],rn[ 7],rn[14]); reg[8] =cal_reg(rn[18],rn[22],rn[3],rn[22],rn[15]); reg[9] =cal_reg(rn[19],rn[21],rn[4],rn[21],rn[16]); reg[10]=cal_reg(rn[20],rn[20],rn[5],rn[20],rn[17]); reg[11]=cal_reg(rn[21],rn[19],rn[6],rn[19],rn[18]); reg[12]=cal_reg(rn[22],rn[18],rn[1],rn[18],rn[19]); reg[13]=cal_reg(rn[11],rn[17],rn[2],rn[17],rn[20]); reg[14]=cal_reg(rn[12],rn[16],rn[3],rn[16],rn[21]); reg[15]=cal_reg(rn[13],rn[15],rn[4],rn[15],rn[22]); printf("\n\nUnlock Code: "); for(i=0;i<16;i++) printf("%d",reg[i]); printf("\n\n"); printf("Please press PURCHASE button to enter the Unlock Code.\n"); printf("If you first press PUCHASE button, you must enter the\n"); printf("Personal Information.\n"); printf("So you can press the PURCHASE button again to enter Unlock\n"); printf("Code, after you enter the Personal Information.\n\n"); printf("Name and company are any strings you like.\n"); printf("But they must be more than two chars.\n\n"); printf("Enjoy it!! ^o^\n"); } unsigned char cal_reg(signed a,signed b,signed c,signed d,signed e) { signed ax; ax=e+d; if (ax>9) ax=ax-10; ax=ax-c; if (ax<0) ax=ax+10; ax=ax+b; if (ax>9) ax=ax-10; ax=ax-a; if (ax<0) ax=ax+10; return(ax); } 到此为止,Over!! 该说题外话的时候了。 由于本人知识有限,如有错漏,欢迎指教。 本文欢迎各位读者以各种形式转载, 但未经作者同意,不得擅自改动。多谢!!! ^o^